Spaces:
Running
on
L4
Running
on
L4
Upload folder using huggingface_hub
Browse files- .env.example +9 -1
- backend/vespa_app.py +49 -13
- frontend/app.py +42 -3
- frontend/layout.py +7 -2
- icons.py +1 -1
- main.py +7 -1
- output.css +46 -8
- prepare_feed_deploy.py +9 -0
- static/img/vespa-colpali.png +0 -0
.env.example
CHANGED
|
@@ -1,4 +1,12 @@
|
|
| 1 |
-
|
|
|
|
| 2 |
HF_TOKEN=hf_xxxxxxxxxx
|
| 3 |
VESPA_CLOUD_SECRET_TOKEN=vespa_cloud_xxxxxxxx
|
| 4 |
GEMINI_API_KEY=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
VESPA_APP_TOKEN_URL=https://abcde.z.vespa-app.cloud
|
| 2 |
+
VESPA_APP_MTLS_URL=https://fghjkl.z.vespa-app.cloud
|
| 3 |
HF_TOKEN=hf_xxxxxxxxxx
|
| 4 |
VESPA_CLOUD_SECRET_TOKEN=vespa_cloud_xxxxxxxx
|
| 5 |
GEMINI_API_KEY=
|
| 6 |
+
USE_MTLS=false
|
| 7 |
+
VESPA_CLOUD_MTLS_KEY="-----BEGIN PRIVATE KEY-----
|
| 8 |
+
...
|
| 9 |
+
-----END PRIVATE KEY-----"
|
| 10 |
+
VESPA_CLOUD_MTLS_CERT="-----BEGIN CERTIFICATE-----
|
| 11 |
+
...
|
| 12 |
+
-----END CERTIFICATE-----"
|
backend/vespa_app.py
CHANGED
|
@@ -19,19 +19,57 @@ class VespaQueryClient:
|
|
| 19 |
Initialize the VespaQueryClient by loading environment variables and establishing a connection to the Vespa application.
|
| 20 |
"""
|
| 21 |
load_dotenv()
|
| 22 |
-
self.vespa_app_url = os.environ.get("VESPA_APP_URL")
|
| 23 |
-
self.vespa_cloud_secret_token = os.environ.get("VESPA_CLOUD_SECRET_TOKEN")
|
| 24 |
|
| 25 |
-
if
|
| 26 |
-
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
)
|
| 29 |
|
| 30 |
-
# Instantiate Vespa connection
|
| 31 |
-
self.app = Vespa(
|
| 32 |
-
url=self.vespa_app_url,
|
| 33 |
-
vespa_cloud_secret_token=self.vespa_cloud_secret_token,
|
| 34 |
-
)
|
| 35 |
self.app.wait_for_application_up()
|
| 36 |
print(f"Connected to Vespa at {self.vespa_app_url}")
|
| 37 |
|
|
@@ -280,12 +318,12 @@ class VespaQueryClient:
|
|
| 280 |
async with self.app.asyncio(connections=1) as session:
|
| 281 |
start = time.perf_counter()
|
| 282 |
yql = f'select questions from {self.VESPA_SCHEMA_NAME} where questions matches "{query}" limit 3'
|
| 283 |
-
print(yql)
|
| 284 |
response: VespaQueryResponse = await session.query(
|
| 285 |
body={
|
| 286 |
"yql": yql,
|
| 287 |
"ranking": "unranked",
|
| 288 |
"presentation.timing": True,
|
|
|
|
| 289 |
},
|
| 290 |
)
|
| 291 |
assert response.is_successful(), response.json
|
|
@@ -299,8 +337,6 @@ class VespaQueryClient:
|
|
| 299 |
if "root" in response.json and "children" in response.json["root"]
|
| 300 |
else []
|
| 301 |
)
|
| 302 |
-
print(response.json)
|
| 303 |
-
|
| 304 |
questions = [
|
| 305 |
result["fields"]["questions"]
|
| 306 |
for result in search_results
|
|
|
|
| 19 |
Initialize the VespaQueryClient by loading environment variables and establishing a connection to the Vespa application.
|
| 20 |
"""
|
| 21 |
load_dotenv()
|
|
|
|
|
|
|
| 22 |
|
| 23 |
+
if os.environ.get("USE_MTLS") == "true":
|
| 24 |
+
print("Connected using mTLS")
|
| 25 |
+
mtls_key = os.environ.get("VESPA_CLOUD_MTLS_KEY")
|
| 26 |
+
mtls_cert = os.environ.get("VESPA_CLOUD_MTLS_CERT")
|
| 27 |
+
|
| 28 |
+
self.vespa_app_url = os.environ.get("VESPA_APP_MTLS_URL")
|
| 29 |
+
if not self.vespa_app_url:
|
| 30 |
+
raise ValueError(
|
| 31 |
+
"Please set the VESPA_APP_MTLS_URL environment variable"
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
if not mtls_cert or not mtls_key:
|
| 35 |
+
raise ValueError(
|
| 36 |
+
"USE_MTLS was true, but VESPA_CLOUD_MTLS_KEY and VESPA_CLOUD_MTLS_CERT were not set"
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
# write the key and cert to a file
|
| 40 |
+
mtls_key_path = "/tmp/vespa-data-plane-private-key.pem"
|
| 41 |
+
with open(mtls_key_path, "w") as f:
|
| 42 |
+
f.write(mtls_key)
|
| 43 |
+
|
| 44 |
+
mtls_cert_path = "/tmp/vespa-data-plane-public-cert.pem"
|
| 45 |
+
with open(mtls_cert_path, "w") as f:
|
| 46 |
+
f.write(mtls_cert)
|
| 47 |
+
|
| 48 |
+
# Instantiate Vespa connection
|
| 49 |
+
self.app = Vespa(
|
| 50 |
+
url=self.vespa_app_url, key=mtls_key_path, cert=mtls_cert_path
|
| 51 |
+
)
|
| 52 |
+
else:
|
| 53 |
+
print("Connected using token")
|
| 54 |
+
self.vespa_app_url = os.environ.get("VESPA_APP_TOKEN_URL")
|
| 55 |
+
if not self.vespa_app_url:
|
| 56 |
+
raise ValueError(
|
| 57 |
+
"Please set the VESPA_APP_TOKEN_URL environment variable"
|
| 58 |
+
)
|
| 59 |
+
|
| 60 |
+
self.vespa_cloud_secret_token = os.environ.get("VESPA_CLOUD_SECRET_TOKEN")
|
| 61 |
+
|
| 62 |
+
if not self.vespa_cloud_secret_token:
|
| 63 |
+
raise ValueError(
|
| 64 |
+
"Please set the VESPA_CLOUD_SECRET_TOKEN environment variable"
|
| 65 |
+
)
|
| 66 |
+
|
| 67 |
+
# Instantiate Vespa connection
|
| 68 |
+
self.app = Vespa(
|
| 69 |
+
url=self.vespa_app_url,
|
| 70 |
+
vespa_cloud_secret_token=self.vespa_cloud_secret_token,
|
| 71 |
)
|
| 72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
self.app.wait_for_application_up()
|
| 74 |
print(f"Connected to Vespa at {self.vespa_app_url}")
|
| 75 |
|
|
|
|
| 318 |
async with self.app.asyncio(connections=1) as session:
|
| 319 |
start = time.perf_counter()
|
| 320 |
yql = f'select questions from {self.VESPA_SCHEMA_NAME} where questions matches "{query}" limit 3'
|
|
|
|
| 321 |
response: VespaQueryResponse = await session.query(
|
| 322 |
body={
|
| 323 |
"yql": yql,
|
| 324 |
"ranking": "unranked",
|
| 325 |
"presentation.timing": True,
|
| 326 |
+
"presentation.summary": "suggestions",
|
| 327 |
},
|
| 328 |
)
|
| 329 |
assert response.is_successful(), response.json
|
|
|
|
| 337 |
if "root" in response.json and "children" in response.json["root"]
|
| 338 |
else []
|
| 339 |
)
|
|
|
|
|
|
|
| 340 |
questions = [
|
| 341 |
result["fields"]["questions"]
|
| 342 |
for result in search_results
|
frontend/app.py
CHANGED
|
@@ -229,9 +229,48 @@ def Home():
|
|
| 229 |
Hero(),
|
| 230 |
SearchBox(with_border=True),
|
| 231 |
SampleQueries(),
|
| 232 |
-
cls="grid gap-8 -mt-[
|
| 233 |
),
|
| 234 |
-
cls="grid w-full h-full max-w-screen-md
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 235 |
)
|
| 236 |
|
| 237 |
|
|
@@ -457,7 +496,7 @@ def SearchResult(results: list, query_id: Optional[str] = None):
|
|
| 457 |
image_swapping,
|
| 458 |
toggle_text_content,
|
| 459 |
id="search-results",
|
| 460 |
-
cls="grid grid-cols-1 gap-px bg-border",
|
| 461 |
)
|
| 462 |
|
| 463 |
|
|
|
|
| 229 |
Hero(),
|
| 230 |
SearchBox(with_border=True),
|
| 231 |
SampleQueries(),
|
| 232 |
+
cls="grid gap-8 content-start mt-[13vh]",
|
| 233 |
),
|
| 234 |
+
cls="grid w-full h-full max-w-screen-md gap-4 mx-auto",
|
| 235 |
+
)
|
| 236 |
+
|
| 237 |
+
|
| 238 |
+
def WhatIsThis():
|
| 239 |
+
return Div(
|
| 240 |
+
Div(
|
| 241 |
+
Div(
|
| 242 |
+
H1(
|
| 243 |
+
"Vespa.ai + ColPali",
|
| 244 |
+
cls="text-5xl font-bold tracking-wide md:tracking-wider",
|
| 245 |
+
),
|
| 246 |
+
P(
|
| 247 |
+
"Efficient Document Retrieval with Vision Language Models",
|
| 248 |
+
cls="text-lg text-muted-foreground md:tracking-wide",
|
| 249 |
+
),
|
| 250 |
+
Div(
|
| 251 |
+
Img(
|
| 252 |
+
src="/static/img/vespa-colpali.png",
|
| 253 |
+
alt="Vespa and ColPali",
|
| 254 |
+
cls="object-contain h-[377px]",
|
| 255 |
+
),
|
| 256 |
+
cls="grid justify-center",
|
| 257 |
+
),
|
| 258 |
+
Div(
|
| 259 |
+
P(
|
| 260 |
+
"This is a demo application showcasing the integration of Vespa.ai and ColPali for visual retrieval of documents.",
|
| 261 |
+
cls="text-base",
|
| 262 |
+
),
|
| 263 |
+
P(
|
| 264 |
+
"The application uses a combination of neural networks and traditional search algorithms to retrieve relevant documents based on visual and textual queries.",
|
| 265 |
+
cls="text-base",
|
| 266 |
+
),
|
| 267 |
+
cls="grid gap-2 text-center",
|
| 268 |
+
),
|
| 269 |
+
cls="grid gap-5 text-center",
|
| 270 |
+
),
|
| 271 |
+
cls="grid gap-8 content-start mt-[8vh]",
|
| 272 |
+
),
|
| 273 |
+
cls="grid w-full h-full max-w-screen-md gap-4 mx-auto",
|
| 274 |
)
|
| 275 |
|
| 276 |
|
|
|
|
| 496 |
image_swapping,
|
| 497 |
toggle_text_content,
|
| 498 |
id="search-results",
|
| 499 |
+
cls="grid grid-cols-1 gap-px bg-border min-h-0",
|
| 500 |
)
|
| 501 |
|
| 502 |
|
frontend/layout.py
CHANGED
|
@@ -107,6 +107,11 @@ def ThemeToggle(variant="ghost", cls=None, **kwargs):
|
|
| 107 |
|
| 108 |
def Links():
|
| 109 |
return Nav(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
A(
|
| 111 |
Button(Lucide(icon="github"), size="icon", variant="ghost"),
|
| 112 |
href="https://github.com/vespa-engine/vespa",
|
|
@@ -119,7 +124,7 @@ def Links():
|
|
| 119 |
),
|
| 120 |
Separator(orientation="vertical"),
|
| 121 |
ThemeToggle(),
|
| 122 |
-
cls="flex items-center space-x-
|
| 123 |
)
|
| 124 |
|
| 125 |
|
|
@@ -134,7 +139,7 @@ def Layout(*c, **kwargs):
|
|
| 134 |
),
|
| 135 |
*c,
|
| 136 |
**kwargs,
|
| 137 |
-
cls="grid grid-rows-[
|
| 138 |
),
|
| 139 |
layout_script,
|
| 140 |
overlay_scrollbars,
|
|
|
|
| 107 |
|
| 108 |
def Links():
|
| 109 |
return Nav(
|
| 110 |
+
A(
|
| 111 |
+
Button("What's this?", variant="link"),
|
| 112 |
+
href="/what-is-this",
|
| 113 |
+
),
|
| 114 |
+
Separator(orientation="vertical"),
|
| 115 |
A(
|
| 116 |
Button(Lucide(icon="github"), size="icon", variant="ghost"),
|
| 117 |
href="https://github.com/vespa-engine/vespa",
|
|
|
|
| 124 |
),
|
| 125 |
Separator(orientation="vertical"),
|
| 126 |
ThemeToggle(),
|
| 127 |
+
cls="flex items-center space-x-2",
|
| 128 |
)
|
| 129 |
|
| 130 |
|
|
|
|
| 139 |
),
|
| 140 |
*c,
|
| 141 |
**kwargs,
|
| 142 |
+
cls="grid grid-rows-[minmax(0,55px)_minmax(0,1fr)] min-h-0",
|
| 143 |
),
|
| 144 |
layout_script,
|
| 145 |
overlay_scrollbars,
|
icons.py
CHANGED
|
@@ -1 +1 @@
|
|
| 1 |
-
ICONS = {"chevrons-right": "<path d=\"m6 17 5-5-5-5\"></path><path d=\"m13 17 5-5-5-5\"></path>", "moon": "<path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\"></path>", "sun": "<circle cx=\"12\" cy=\"12\" r=\"4\"></circle><path d=\"M12 2v2\"></path><path d=\"M12 20v2\"></path><path d=\"m4.93 4.93 1.41 1.41\"></path><path d=\"m17.66 17.66 1.41 1.41\"></path><path d=\"M2 12h2\"></path><path d=\"M20 12h2\"></path><path d=\"m6.34 17.66-1.41 1.41\"></path><path d=\"m19.07 4.93-1.41 1.41\"></path>", "github": "<path d=\"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4\"></path><path d=\"M9 18c-4.51 2-5-2-7-2\"></path>", "slack": "<rect height=\"8\" rx=\"1.5\" width=\"3\" x=\"13\" y=\"2\"></rect><path d=\"M19 8.5V10h1.5A1.5 1.5 0 1 0 19 8.5\"></path><rect height=\"8\" rx=\"1.5\" width=\"3\" x=\"8\" y=\"14\"></rect><path d=\"M5 15.5V14H3.5A1.5 1.5 0 1 0 5 15.5\"></path><rect height=\"3\" rx=\"1.5\" width=\"8\" x=\"14\" y=\"13\"></rect><path d=\"M15.5 19H14v1.5a1.5 1.5 0 1 0 1.5-1.5\"></path><rect height=\"3\" rx=\"1.5\" width=\"8\" x=\"2\" y=\"8\"></rect><path d=\"M8.5 5H10V3.5A1.5 1.5 0 1 0 8.5 5\"></path>", "settings": "<path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"></path><circle cx=\"12\" cy=\"12\" r=\"3\"></circle>", "arrow-right": "<path d=\"M5 12h14\"></path><path d=\"m12 5 7 7-7 7\"></path>", "search": "<circle cx=\"11\" cy=\"11\" r=\"8\"></circle><path d=\"m21 21-4.3-4.3\"></path>", "file-search": "<path d=\"M14 2v4a2 2 0 0 0 2 2h4\"></path><path d=\"M4.268 21a2 2 0 0 0 1.727 1H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3\"></path><path d=\"m9 18-1.5-1.5\"></path><circle cx=\"5\" cy=\"14\" r=\"3\"></circle>", "message-circle-question": "<path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"></path><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"></path><path d=\"M12 17h.01\"></path>", "text-search": "<path d=\"M21 6H3\"></path><path d=\"M10 12H3\"></path><path d=\"M10 18H3\"></path><circle cx=\"17\" cy=\"15\" r=\"3\"></circle><path d=\"m21 19-1.9-1.9\"></path>", "maximize": "<path d=\"M8 3H5a2 2 0 0 0-2 2v3\"></path><path d=\"M21 8V5a2 2 0 0 0-2-2h-3\"></path><path d=\"M3 16v3a2 2 0 0 0 2 2h3\"></path><path d=\"M16 21h3a2 2 0 0 0 2-2v-3\"></path>", "expand": "<path d=\"m21 21-6-6m6 6v-4.8m0 4.8h-4.8\"></path><path d=\"M3 16.2V21m0 0h4.8M3 21l6-6\"></path><path d=\"M21 7.8V3m0 0h-4.8M21 3l-6 6\"></path><path d=\"M3 7.8V3m0 0h4.8M3 3l6 6\"></path>", "fullscreen": "<path d=\"M3 7V5a2 2 0 0 1 2-2h2\"></path><path d=\"M17 3h2a2 2 0 0 1 2 2v2\"></path><path d=\"M21 17v2a2 2 0 0 1-2 2h-2\"></path><path d=\"M7 21H5a2 2 0 0 1-2-2v-2\"></path><rect height=\"8\" rx=\"1\" width=\"10\" x=\"7\" y=\"8\"></rect>", "images": "<path d=\"M18 22H4a2 2 0 0 1-2-2V6\"></path><path d=\"m22 13-1.296-1.296a2.41 2.41 0 0 0-3.408 0L11 18\"></path><circle cx=\"12\" cy=\"8\" r=\"2\"></circle><rect height=\"16\" rx=\"2\" width=\"16\" x=\"6\" y=\"2\"></rect>", "circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle>", "loader-circle": "<path d=\"M21 12a9 9 0 1 1-6.219-8.56\"></path>", "file-text": "<path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\"></path><path d=\"M14 2v4a2 2 0 0 0 2 2h4\"></path><path d=\"M10 9H8\"></path><path d=\"M16 13H8\"></path><path d=\"M16 17H8\"></path>"}
|
|
|
|
| 1 |
+
ICONS = {"chevrons-right": "<path d=\"m6 17 5-5-5-5\"></path><path d=\"m13 17 5-5-5-5\"></path>", "moon": "<path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\"></path>", "sun": "<circle cx=\"12\" cy=\"12\" r=\"4\"></circle><path d=\"M12 2v2\"></path><path d=\"M12 20v2\"></path><path d=\"m4.93 4.93 1.41 1.41\"></path><path d=\"m17.66 17.66 1.41 1.41\"></path><path d=\"M2 12h2\"></path><path d=\"M20 12h2\"></path><path d=\"m6.34 17.66-1.41 1.41\"></path><path d=\"m19.07 4.93-1.41 1.41\"></path>", "github": "<path d=\"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4\"></path><path d=\"M9 18c-4.51 2-5-2-7-2\"></path>", "slack": "<rect height=\"8\" rx=\"1.5\" width=\"3\" x=\"13\" y=\"2\"></rect><path d=\"M19 8.5V10h1.5A1.5 1.5 0 1 0 19 8.5\"></path><rect height=\"8\" rx=\"1.5\" width=\"3\" x=\"8\" y=\"14\"></rect><path d=\"M5 15.5V14H3.5A1.5 1.5 0 1 0 5 15.5\"></path><rect height=\"3\" rx=\"1.5\" width=\"8\" x=\"14\" y=\"13\"></rect><path d=\"M15.5 19H14v1.5a1.5 1.5 0 1 0 1.5-1.5\"></path><rect height=\"3\" rx=\"1.5\" width=\"8\" x=\"2\" y=\"8\"></rect><path d=\"M8.5 5H10V3.5A1.5 1.5 0 1 0 8.5 5\"></path>", "settings": "<path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"></path><circle cx=\"12\" cy=\"12\" r=\"3\"></circle>", "arrow-right": "<path d=\"M5 12h14\"></path><path d=\"m12 5 7 7-7 7\"></path>", "search": "<circle cx=\"11\" cy=\"11\" r=\"8\"></circle><path d=\"m21 21-4.3-4.3\"></path>", "file-search": "<path d=\"M14 2v4a2 2 0 0 0 2 2h4\"></path><path d=\"M4.268 21a2 2 0 0 0 1.727 1H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3\"></path><path d=\"m9 18-1.5-1.5\"></path><circle cx=\"5\" cy=\"14\" r=\"3\"></circle>", "message-circle-question": "<path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"></path><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"></path><path d=\"M12 17h.01\"></path>", "text-search": "<path d=\"M21 6H3\"></path><path d=\"M10 12H3\"></path><path d=\"M10 18H3\"></path><circle cx=\"17\" cy=\"15\" r=\"3\"></circle><path d=\"m21 19-1.9-1.9\"></path>", "maximize": "<path d=\"M8 3H5a2 2 0 0 0-2 2v3\"></path><path d=\"M21 8V5a2 2 0 0 0-2-2h-3\"></path><path d=\"M3 16v3a2 2 0 0 0 2 2h3\"></path><path d=\"M16 21h3a2 2 0 0 0 2-2v-3\"></path>", "expand": "<path d=\"m21 21-6-6m6 6v-4.8m0 4.8h-4.8\"></path><path d=\"M3 16.2V21m0 0h4.8M3 21l6-6\"></path><path d=\"M21 7.8V3m0 0h-4.8M21 3l-6 6\"></path><path d=\"M3 7.8V3m0 0h4.8M3 3l6 6\"></path>", "fullscreen": "<path d=\"M3 7V5a2 2 0 0 1 2-2h2\"></path><path d=\"M17 3h2a2 2 0 0 1 2 2v2\"></path><path d=\"M21 17v2a2 2 0 0 1-2 2h-2\"></path><path d=\"M7 21H5a2 2 0 0 1-2-2v-2\"></path><rect height=\"8\" rx=\"1\" width=\"10\" x=\"7\" y=\"8\"></rect>", "images": "<path d=\"M18 22H4a2 2 0 0 1-2-2V6\"></path><path d=\"m22 13-1.296-1.296a2.41 2.41 0 0 0-3.408 0L11 18\"></path><circle cx=\"12\" cy=\"8\" r=\"2\"></circle><rect height=\"16\" rx=\"2\" width=\"16\" x=\"6\" y=\"2\"></rect>", "circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle>", "loader-circle": "<path d=\"M21 12a9 9 0 1 1-6.219-8.56\"></path>", "file-text": "<path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\"></path><path d=\"M14 2v4a2 2 0 0 0 2 2h4\"></path><path d=\"M10 9H8\"></path><path d=\"M16 13H8\"></path><path d=\"M16 17H8\"></path>", "file-question": "<path d=\"M12 17h.01\"></path><path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z\"></path><path d=\"M9.1 9a3 3 0 0 1 5.82 1c0 2-3 3-3 3\"></path>"}
|
main.py
CHANGED
|
@@ -6,6 +6,7 @@ import os
|
|
| 6 |
import time
|
| 7 |
from concurrent.futures import ThreadPoolExecutor
|
| 8 |
from functools import partial
|
|
|
|
| 9 |
|
| 10 |
import google.generativeai as genai
|
| 11 |
from fasthtml.common import *
|
|
@@ -20,7 +21,6 @@ from backend.colpali import (
|
|
| 20 |
is_special_token,
|
| 21 |
)
|
| 22 |
from backend.modelmanager import ModelManager
|
| 23 |
-
from pathlib import Path
|
| 24 |
from backend.vespa_app import VespaQueryClient
|
| 25 |
from frontend.app import (
|
| 26 |
ChatResult,
|
|
@@ -30,6 +30,7 @@ from frontend.app import (
|
|
| 30 |
SearchResult,
|
| 31 |
SimMapButtonPoll,
|
| 32 |
SimMapButtonReady,
|
|
|
|
| 33 |
)
|
| 34 |
from frontend.layout import Layout
|
| 35 |
|
|
@@ -124,6 +125,11 @@ def get():
|
|
| 124 |
return Layout(Main(Home()))
|
| 125 |
|
| 126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
@rt("/search")
|
| 128 |
def get(request):
|
| 129 |
# Extract the 'query' and 'ranking' parameters from the URL
|
|
|
|
| 6 |
import time
|
| 7 |
from concurrent.futures import ThreadPoolExecutor
|
| 8 |
from functools import partial
|
| 9 |
+
from pathlib import Path
|
| 10 |
|
| 11 |
import google.generativeai as genai
|
| 12 |
from fasthtml.common import *
|
|
|
|
| 21 |
is_special_token,
|
| 22 |
)
|
| 23 |
from backend.modelmanager import ModelManager
|
|
|
|
| 24 |
from backend.vespa_app import VespaQueryClient
|
| 25 |
from frontend.app import (
|
| 26 |
ChatResult,
|
|
|
|
| 30 |
SearchResult,
|
| 31 |
SimMapButtonPoll,
|
| 32 |
SimMapButtonReady,
|
| 33 |
+
WhatIsThis,
|
| 34 |
)
|
| 35 |
from frontend.layout import Layout
|
| 36 |
|
|
|
|
| 125 |
return Layout(Main(Home()))
|
| 126 |
|
| 127 |
|
| 128 |
+
@rt("/what-is-this")
|
| 129 |
+
def get():
|
| 130 |
+
return Layout(Main(WhatIsThis()))
|
| 131 |
+
|
| 132 |
+
|
| 133 |
@rt("/search")
|
| 134 |
def get(request):
|
| 135 |
# Extract the 'query' and 'ranking' parameters from the URL
|
output.css
CHANGED
|
@@ -793,10 +793,6 @@ body {
|
|
| 793 |
margin-top: -1rem;
|
| 794 |
}
|
| 795 |
|
| 796 |
-
.-mt-\[21vh\] {
|
| 797 |
-
margin-top: -21vh;
|
| 798 |
-
}
|
| 799 |
-
|
| 800 |
.mb-1 {
|
| 801 |
margin-bottom: 0.25rem;
|
| 802 |
}
|
|
@@ -809,6 +805,18 @@ body {
|
|
| 809 |
margin-top: 0.5rem;
|
| 810 |
}
|
| 811 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 812 |
.block {
|
| 813 |
display: block;
|
| 814 |
}
|
|
@@ -841,6 +849,10 @@ body {
|
|
| 841 |
aspect-ratio: 1 / 1;
|
| 842 |
}
|
| 843 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 844 |
.size-4 {
|
| 845 |
width: 1rem;
|
| 846 |
height: 1rem;
|
|
@@ -919,6 +931,14 @@ body {
|
|
| 919 |
height: 1px;
|
| 920 |
}
|
| 921 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 922 |
.max-h-96 {
|
| 923 |
max-height: 24rem;
|
| 924 |
}
|
|
@@ -983,6 +1003,14 @@ body {
|
|
| 983 |
width: 100%;
|
| 984 |
}
|
| 985 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 986 |
.min-w-0 {
|
| 987 |
min-width: 0px;
|
| 988 |
}
|
|
@@ -1106,10 +1134,6 @@ body {
|
|
| 1106 |
grid-template-columns: repeat(1, minmax(0, 1fr));
|
| 1107 |
}
|
| 1108 |
|
| 1109 |
-
.grid-rows-\[55px_1fr\] {
|
| 1110 |
-
grid-template-rows: 55px 1fr;
|
| 1111 |
-
}
|
| 1112 |
-
|
| 1113 |
.grid-rows-\[auto_1fr\] {
|
| 1114 |
grid-template-rows: auto 1fr;
|
| 1115 |
}
|
|
@@ -1118,6 +1142,10 @@ body {
|
|
| 1118 |
grid-template-rows: auto 1fr auto;
|
| 1119 |
}
|
| 1120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1121 |
.flex-col {
|
| 1122 |
flex-direction: column;
|
| 1123 |
}
|
|
@@ -1592,6 +1620,11 @@ body {
|
|
| 1592 |
line-height: 1rem;
|
| 1593 |
}
|
| 1594 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1595 |
.font-bold {
|
| 1596 |
font-weight: 700;
|
| 1597 |
}
|
|
@@ -2652,6 +2685,11 @@ aside {
|
|
| 2652 |
line-height: 1;
|
| 2653 |
}
|
| 2654 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2655 |
.md\:tracking-wide {
|
| 2656 |
letter-spacing: 0.025em;
|
| 2657 |
}
|
|
|
|
| 793 |
margin-top: -1rem;
|
| 794 |
}
|
| 795 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 796 |
.mb-1 {
|
| 797 |
margin-bottom: 0.25rem;
|
| 798 |
}
|
|
|
|
| 805 |
margin-top: 0.5rem;
|
| 806 |
}
|
| 807 |
|
| 808 |
+
.mt-\[13vh\] {
|
| 809 |
+
margin-top: 13vh;
|
| 810 |
+
}
|
| 811 |
+
|
| 812 |
+
.mt-\[8vh\] {
|
| 813 |
+
margin-top: 8vh;
|
| 814 |
+
}
|
| 815 |
+
|
| 816 |
+
.mt-\[5vh\] {
|
| 817 |
+
margin-top: 5vh;
|
| 818 |
+
}
|
| 819 |
+
|
| 820 |
.block {
|
| 821 |
display: block;
|
| 822 |
}
|
|
|
|
| 849 |
aspect-ratio: 1 / 1;
|
| 850 |
}
|
| 851 |
|
| 852 |
+
.aspect-auto {
|
| 853 |
+
aspect-ratio: auto;
|
| 854 |
+
}
|
| 855 |
+
|
| 856 |
.size-4 {
|
| 857 |
width: 1rem;
|
| 858 |
height: 1rem;
|
|
|
|
| 931 |
height: 1px;
|
| 932 |
}
|
| 933 |
|
| 934 |
+
.h-\[377px\] {
|
| 935 |
+
height: 377px;
|
| 936 |
+
}
|
| 937 |
+
|
| 938 |
+
.h-\[610px\] {
|
| 939 |
+
height: 610px;
|
| 940 |
+
}
|
| 941 |
+
|
| 942 |
.max-h-96 {
|
| 943 |
max-height: 24rem;
|
| 944 |
}
|
|
|
|
| 1003 |
width: 100%;
|
| 1004 |
}
|
| 1005 |
|
| 1006 |
+
.w-\[377px\] {
|
| 1007 |
+
width: 377px;
|
| 1008 |
+
}
|
| 1009 |
+
|
| 1010 |
+
.w-\[233px\] {
|
| 1011 |
+
width: 233px;
|
| 1012 |
+
}
|
| 1013 |
+
|
| 1014 |
.min-w-0 {
|
| 1015 |
min-width: 0px;
|
| 1016 |
}
|
|
|
|
| 1134 |
grid-template-columns: repeat(1, minmax(0, 1fr));
|
| 1135 |
}
|
| 1136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1137 |
.grid-rows-\[auto_1fr\] {
|
| 1138 |
grid-template-rows: auto 1fr;
|
| 1139 |
}
|
|
|
|
| 1142 |
grid-template-rows: auto 1fr auto;
|
| 1143 |
}
|
| 1144 |
|
| 1145 |
+
.grid-rows-\[minmax\(0\2c 55px\)_minmax\(0\2c 1fr\)\] {
|
| 1146 |
+
grid-template-rows: minmax(0,55px) minmax(0,1fr);
|
| 1147 |
+
}
|
| 1148 |
+
|
| 1149 |
.flex-col {
|
| 1150 |
flex-direction: column;
|
| 1151 |
}
|
|
|
|
| 1620 |
line-height: 1rem;
|
| 1621 |
}
|
| 1622 |
|
| 1623 |
+
.text-4xl {
|
| 1624 |
+
font-size: 2.25rem;
|
| 1625 |
+
line-height: 2.5rem;
|
| 1626 |
+
}
|
| 1627 |
+
|
| 1628 |
.font-bold {
|
| 1629 |
font-weight: 700;
|
| 1630 |
}
|
|
|
|
| 2685 |
line-height: 1;
|
| 2686 |
}
|
| 2687 |
|
| 2688 |
+
.md\:text-xl {
|
| 2689 |
+
font-size: 1.25rem;
|
| 2690 |
+
line-height: 1.75rem;
|
| 2691 |
+
}
|
| 2692 |
+
|
| 2693 |
.md\:tracking-wide {
|
| 2694 |
letter-spacing: 0.025em;
|
| 2695 |
}
|
prepare_feed_deploy.py
CHANGED
|
@@ -723,6 +723,15 @@ colpali_schema = Schema(
|
|
| 723 |
],
|
| 724 |
from_disk=True,
|
| 725 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 726 |
],
|
| 727 |
)
|
| 728 |
|
|
|
|
| 723 |
],
|
| 724 |
from_disk=True,
|
| 725 |
),
|
| 726 |
+
DocumentSummary(
|
| 727 |
+
name="suggestions",
|
| 728 |
+
summary_fields=[
|
| 729 |
+
Summary(
|
| 730 |
+
name="questions"
|
| 731 |
+
),
|
| 732 |
+
],
|
| 733 |
+
from_disk=True,
|
| 734 |
+
),
|
| 735 |
],
|
| 736 |
)
|
| 737 |
|
static/img/vespa-colpali.png
ADDED
|