Skip to content

Commit 3b94082

Browse files
committed
Finish autorag feature
1 parent 433ecad commit 3b94082

File tree

5 files changed

+277
-74
lines changed

5 files changed

+277
-74
lines changed

package.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@
44
"description": "A serverless, AI-powered deep research agent built with Cloudflare Workers and Google Gemini 2.5",
55
"main": "./dist/index.js",
66
"type": "module",
7-
"files": [
8-
"dist",
9-
"LICENSE",
10-
"README.md"
11-
],
7+
"files": ["dist", "LICENSE", "README.md"],
128
"scripts": {
139
"build": "tsup src/index.ts --format cjs,esm --external cloudflare:workers",
1410
"build-css": "npx @tailwindcss/cli -i ./src/templates/styles.css -o ./src/static/styles.css",

src/index.tsx

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import puppeteer from "@cloudflare/puppeteer";
12
import { LoadAPIKeyError, generateObject, generateText } from "ai";
23
import { Hono } from "hono";
34
import { HTTPException } from "hono/http-exception";
@@ -19,7 +20,6 @@ import {
1920
} from "./templates/layout";
2021
import type { ResearchType, ResearchTypeDB } from "./types";
2122
import { formatDuration, getModel } from "./utils";
22-
import puppeteer from "@cloudflare/puppeteer";
2323

2424
export { ResearchWorkflow } from "./workflows";
2525

@@ -115,7 +115,7 @@ app.get("/", async (c) => {
115115
});
116116

117117
app.get("/create", async (c) => {
118-
const userRags = await c.env.AI.autorag().list()
118+
const userRags = await c.env.AI.autorag().list();
119119

120120
return c.html(
121121
<Layout>
@@ -202,7 +202,11 @@ app.post("/create", async (c) => {
202202

203203
const initialLearnings = form.get("initial-learnings") as string | undefined;
204204
const browseInternetFormValue = form.get("browse_internet");
205-
const browse_internet = browseInternetFormValue === "on" || browseInternetFormValue === "" || browseInternetFormValue === null ? true : false; // default to true if present (even as empty string from checked) or not present at all.
205+
const browse_internet = !!(
206+
browseInternetFormValue === "on" ||
207+
browseInternetFormValue === "" ||
208+
browseInternetFormValue === null
209+
); // default to true if present (even as empty string from checked) or not present at all.
206210
const autorag_id_form = form.get("autorag_id") as string | null;
207211
const autorag_id = autorag_id_form === "" ? null : autorag_id_form;
208212

@@ -320,17 +324,54 @@ app.get("/details/:id", async (c) => {
320324
</button>
321325
<div className="relative inline-block text-left">
322326
<div>
323-
<button type="button" className="inline-flex justify-center w-full rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" id="options-menu" aria-haspopup="true" aria-expanded="true" onClick={`toggleDropdown('${id}')`}>
327+
<button
328+
type="button"
329+
className="inline-flex justify-center w-full rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
330+
id="options-menu"
331+
aria-haspopup="true"
332+
aria-expanded="true"
333+
onClick={`toggleDropdown('${id}')`}
334+
>
324335
Download Report
325-
<svg className="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
326-
<path fillRule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clipRule="evenodd" />
336+
<svg
337+
className="-mr-1 ml-2 h-5 w-5"
338+
xmlns="http://www.w3.org/2000/svg"
339+
viewBox="0 0 20 20"
340+
fill="currentColor"
341+
aria-hidden="true"
342+
>
343+
<path
344+
fillRule="evenodd"
345+
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
346+
clipRule="evenodd"
347+
/>
327348
</svg>
328349
</button>
329350
</div>
330-
<div id={`download-dropdown-${id}`} className="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 hidden z-10" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
331-
<div className="py-1" role="none">
332-
<a href={`/details/${id}/download/pdf`} download="report.pdf" className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" role="menuitem">Download as PDF</a>
333-
<a href={`/details/${id}/download/markdown`} download="report.md" className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900" role="menuitem">Download as Markdown</a>
351+
<div
352+
id={`download-dropdown-${id}`}
353+
className="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 hidden z-10"
354+
role="menu"
355+
aria-orientation="vertical"
356+
aria-labelledby="options-menu"
357+
>
358+
<div className="py-1">
359+
<a
360+
href={`/details/${id}/download/pdf`}
361+
download="report.pdf"
362+
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
363+
role="menuitem"
364+
>
365+
Download as PDF
366+
</a>
367+
<a
368+
href={`/details/${id}/download/markdown`}
369+
download="report.md"
370+
className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
371+
role="menuitem"
372+
>
373+
Download as Markdown
374+
</a>
334375
</div>
335376
</div>
336377
</div>
@@ -361,17 +402,17 @@ app.get("/details/:id/download/pdf", async (c) => {
361402
const content = resp.results.result ?? "";
362403
const htmlContent = renderMarkdownReportContent(content);
363404

364-
const browser = await puppeteer.launch(c.env.BROWSER);
365-
const page = await browser.newPage();
405+
const browser = await puppeteer.launch(c.env.BROWSER);
406+
const page = await browser.newPage();
366407

367-
// // Step 2: Send HTML and CSS to our browser
368-
await page.setContent(htmlContent);
408+
// // Step 2: Send HTML and CSS to our browser
409+
await page.setContent(htmlContent);
369410

370-
// // Step 3: Generate and return PDF
371-
const pdf = await page.pdf({ printBackground: true });
411+
// // Step 3: Generate and return PDF
412+
const pdf = await page.pdf({ printBackground: true });
372413

373-
// Close browser since we no longer need it
374-
await browser.close();
414+
// Close browser since we no longer need it
415+
await browser.close();
375416

376417
c.header("Content-Type", "application/pdf");
377418
c.header("Content-Disposition", 'attachment; filename="report.pdf"');

src/static/core.js

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
function loadNewResearch() {
22
// Initial state based on potential pre-checked (though it's not by default here)
3-
document.addEventListener('DOMContentLoaded', () => {
4-
const useAutoRagCheckbox = document.getElementById('use_autorag_checkbox');
3+
document.addEventListener("DOMContentLoaded", () => {
4+
const useAutoRagCheckbox = document.getElementById("use_autorag_checkbox");
55
if (useAutoRagCheckbox) {
66
toggleAutoRagDropdown(useAutoRagCheckbox.checked);
77
}
@@ -118,30 +118,40 @@ function loadNewResearch() {
118118
});
119119

120120
// Ensure browse_internet and autorag_id are included in the final submission
121-
const browseInternetCheckbox = document.getElementById('browse_internet_checkbox');
121+
const browseInternetCheckbox = document.getElementById(
122+
"browse_internet_checkbox",
123+
);
122124
if (browseInternetCheckbox) {
123-
const browseInternetField = document.createElement('input');
124-
browseInternetField.type = 'hidden';
125-
browseInternetField.name = 'browse_internet';
126-
browseInternetField.value = browseInternetCheckbox.checked ? 'on' : 'off';
125+
const browseInternetField = document.createElement("input");
126+
browseInternetField.type = "hidden";
127+
browseInternetField.name = "browse_internet";
128+
browseInternetField.value = browseInternetCheckbox.checked
129+
? "on"
130+
: "off";
127131
finalForm.appendChild(browseInternetField);
128132
}
129133

130-
const useAutoRagCheckbox = document.getElementById('use_autorag_checkbox');
131-
const autoRagSelect = document.getElementById('autorag_id_select');
132-
if (useAutoRagCheckbox && autoRagSelect && useAutoRagCheckbox.checked) {
133-
const autoRagIdField = document.createElement('input');
134-
autoRagIdField.type = 'hidden';
135-
autoRagIdField.name = 'autorag_id';
134+
const useAutoRagCheckbox = document.getElementById(
135+
"use_autorag_checkbox",
136+
);
137+
const autoRagSelect = document.getElementById("autorag_id_select");
138+
if (
139+
useAutoRagCheckbox &&
140+
autoRagSelect &&
141+
useAutoRagCheckbox.checked
142+
) {
143+
const autoRagIdField = document.createElement("input");
144+
autoRagIdField.type = "hidden";
145+
autoRagIdField.name = "autorag_id";
136146
autoRagIdField.value = autoRagSelect.value;
137147
finalForm.appendChild(autoRagIdField);
138148
} else {
139149
// If not using AutoRAG, ensure we send an empty value if the field is expected
140150
// or make sure no old value is lingering if the field was dynamically added before
141151
// For this case, sending "" for autorag_id will be converted to null by the backend.
142-
const autoRagIdField = document.createElement('input');
143-
autoRagIdField.type = 'hidden';
144-
autoRagIdField.name = 'autorag_id';
152+
const autoRagIdField = document.createElement("input");
153+
autoRagIdField.type = "hidden";
154+
autoRagIdField.name = "autorag_id";
145155
autoRagIdField.value = "";
146156
finalForm.appendChild(autoRagIdField);
147157
}
@@ -247,16 +257,16 @@ function deleteItem(id) {
247257
function toggleDropdown(id) {
248258
const dropdownElement = document.getElementById(`download-dropdown-${id}`);
249259
if (dropdownElement) {
250-
dropdownElement.classList.toggle('hidden');
260+
dropdownElement.classList.toggle("hidden");
251261
}
252262
}
253263

254264
function toggleAutoRagDropdown(checked) {
255-
const dropdown = document.getElementById('autorag_id_dropdown_container');
265+
const dropdown = document.getElementById("autorag_id_dropdown_container");
256266
if (dropdown) {
257-
dropdown.style.display = checked ? 'block' : 'none';
267+
dropdown.style.display = checked ? "block" : "none";
258268
}
259-
const selectElement = document.getElementById('autorag_id_select');
269+
const selectElement = document.getElementById("autorag_id_select");
260270
if (selectElement) {
261271
selectElement.disabled = !checked;
262272
if (!checked) {

src/templates/layout.tsx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,17 @@ export const ResearchDetails: FC = (props) => {
457457

458458
{/* Research Parameters Section */}
459459
<div className="mb-8 bg-white p-6 rounded-lg shadow-md border border-gray-200">
460-
<h3 class="text-lg font-semibold text-gray-800 mb-4">Research Parameters</h3>
460+
<h3 class="text-lg font-semibold text-gray-800 mb-4">
461+
Research Parameters
462+
</h3>
461463
<div className="space-y-3">
462464
<div className="flex justify-between items-center py-2 border-b last:border-b-0 border-gray-100">
463465
<span class="text-sm font-medium text-gray-600">Duration:</span>
464-
<span class="text-sm text-gray-800">{researchData.duration ? formatDuration(researchData.duration) : "N/A"}</span>
466+
<span class="text-sm text-gray-800">
467+
{researchData.duration
468+
? formatDuration(researchData.duration)
469+
: "N/A"}
470+
</span>
465471
</div>
466472
<div className="flex justify-between items-center py-2 border-b last:border-b-0 border-gray-100">
467473
<span class="text-sm font-medium text-gray-600">Depth:</span>
@@ -472,13 +478,19 @@ export const ResearchDetails: FC = (props) => {
472478
<span class="text-sm text-gray-800">{researchData.breadth}</span>
473479
</div>
474480
<div className="flex justify-between items-center py-2 border-b last:border-b-0 border-gray-100">
475-
<span class="text-sm font-medium text-gray-600">Browse Internet:</span>
476-
<span class="text-sm text-gray-800">{researchData.browse_internet === 1 ? "Yes" : "No"}</span>
481+
<span class="text-sm font-medium text-gray-600">
482+
Browse Internet:
483+
</span>
484+
<span class="text-sm text-gray-800">
485+
{researchData.browse_internet === 1 ? "Yes" : "No"}
486+
</span>
477487
</div>
478488
{researchData.autorag_id && researchData.autorag_id !== "" && (
479489
<div className="flex justify-between items-center py-2 border-b last:border-b-0 border-gray-100">
480490
<span class="text-sm font-medium text-gray-600">AutoRAG ID:</span>
481-
<span class="text-sm text-gray-800">{researchData.autorag_id}</span>
491+
<span class="text-sm text-gray-800">
492+
{researchData.autorag_id}
493+
</span>
482494
</div>
483495
)}
484496
</div>
@@ -713,12 +725,16 @@ export const CreateResearch: FC<CreateResearchProps> = (props) => {
713725
{!hasRags && (
714726
<p class="text-sm text-gray-500">
715727
You don't have any AutoRAGs.{" "}
716-
{html`<a href='https://google.com' target='_blank' class='text-blue-600 hover:underline'>Click here</a>`}
717-
{" "}to create one.
728+
{html`<a href='https://google.com' target='_blank' class='text-blue-600 hover:underline'>Click here</a>`}{" "}
729+
to create one.
718730
</p>
719731
)}
720732
{hasRags && (
721-
<div id="autorag_id_dropdown_container" style="display: none;" class="mt-2">
733+
<div
734+
id="autorag_id_dropdown_container"
735+
style="display: none;"
736+
class="mt-2"
737+
>
722738
<label
723739
htmlFor="autorag_id_select"
724740
class="block text-sm font-medium text-gray-700 mb-1"
@@ -732,7 +748,7 @@ export const CreateResearch: FC<CreateResearchProps> = (props) => {
732748
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
733749
>
734750
<option value="">-- Select an AutoRAG --</option>
735-
{userRags.map(rag => (
751+
{userRags.map((rag) => (
736752
<option value={rag.id}>{rag.id}</option>
737753
))}
738754
</select>

0 commit comments

Comments
 (0)