Skip to content

Commit 23ecfc7

Browse files
authored
feat: init @llama-flow/http pacakge (#105)
1 parent 4402a6d commit 23ecfc7

32 files changed

+2818
-546
lines changed

.changeset/dirty-pugs-wink.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@llama-flow/core": patch
3+
"@llama-flow/http": patch
4+
---
5+
6+
feat: update http protocol

demo/waku/.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
node_modules
2+
dist
3+
.env*
4+
*.tsbuildinfo
5+
.cache
6+
.DS_Store
7+
*.pem
8+
src/pages.gen.ts

demo/waku/openapi-ts.config.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { defaultPlugins, defineConfig } from "@hey-api/openapi-ts";
2+
3+
export default defineConfig({
4+
input: "https://api.cloud.llamaindex.ai/api/openapi.json",
5+
output: "src/lib/api",
6+
plugins: [
7+
...defaultPlugins,
8+
"@hey-api/client-fetch",
9+
"zod",
10+
"@hey-api/schemas",
11+
"@hey-api/sdk",
12+
{
13+
enums: "javascript",
14+
identifierCase: "PascalCase",
15+
name: "@hey-api/typescript",
16+
},
17+
],
18+
});

demo/waku/package.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "waku-project",
3+
"version": "0.0.0",
4+
"type": "module",
5+
"private": true,
6+
"scripts": {
7+
"postinstall": "openapi-ts",
8+
"dev": "waku dev",
9+
"build": "waku build",
10+
"start": "waku start"
11+
},
12+
"dependencies": {
13+
"@llama-flow/core": "latest",
14+
"@llama-flow/http": "latest",
15+
"@neondatabase/serverless": "^1.0.0",
16+
"lucide-react": "^0.511.0",
17+
"openai": "^4.95.1",
18+
"react": "19.1.0",
19+
"react-dom": "19.1.0",
20+
"react-server-dom-webpack": "19.1.0",
21+
"stable-hash": "^0.0.5",
22+
"waku": "0.22.4"
23+
},
24+
"devDependencies": {
25+
"@hey-api/client-fetch": "^0.10.1",
26+
"@hey-api/openapi-ts": "^0.67.5",
27+
"@tailwindcss/postcss": "4.1.4",
28+
"@types/react": "19.1.2",
29+
"@types/react-dom": "19.1.2",
30+
"postcss": "8.5.3",
31+
"tailwindcss": "4.1.4",
32+
"typescript": "5.8.3"
33+
}
34+
}

demo/waku/postcss.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
plugins: {
3+
"@tailwindcss/postcss": {},
4+
},
5+
};

demo/waku/public/images/favicon.png

5.58 KB
Loading

demo/waku/src/components/RAG.tsx

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"use client";
2+
import { createClient } from "@llama-flow/http/client";
3+
import * as events from "../workflow/events";
4+
import { useState, useCallback } from "react";
5+
6+
const { fetch } = createClient("/api/store", events);
7+
8+
export const RAG = () => {
9+
const [list, setList] = useState<any[]>([]);
10+
const [file, setFile] = useState<File | null>(null);
11+
12+
const handleFileInput = useCallback(
13+
(e: React.ChangeEvent<HTMLInputElement>) => {
14+
if (e.target.files) {
15+
const selectedFiles = Array.from(e.target.files);
16+
setFile(selectedFiles[0]!);
17+
}
18+
},
19+
[],
20+
);
21+
22+
return (
23+
<section className="border-blue-400 -mx-4 mt-4 rounded-sm border p-4">
24+
<div>
25+
<input type="file" onChange={handleFileInput} id="file-upload" />
26+
<button
27+
onClick={async () => {
28+
fetch({
29+
file,
30+
}).then((stream) => {
31+
stream.forEach((event) => {
32+
console.log(event);
33+
if (event.data) {
34+
setList((prev) => [...prev, `${event.data}`]);
35+
}
36+
});
37+
});
38+
}}
39+
>
40+
Run
41+
</button>
42+
</div>
43+
44+
<form
45+
action={(form) => {
46+
const search = form.get("search") as string;
47+
fetch({
48+
search,
49+
}).then((stream) => {
50+
stream.forEach((event) => {
51+
console.log(event);
52+
if (event.data) {
53+
setList((prev) => [...prev, `${event.data}`]);
54+
}
55+
});
56+
});
57+
}}
58+
>
59+
<input
60+
type="text"
61+
name="search"
62+
className="border-gray-400 mt-4 w-full rounded-sm border p-2"
63+
placeholder="Search something..."
64+
/>
65+
<button type="submit" />
66+
</form>
67+
68+
{list.map((item, index) => (
69+
<div key={index} className="flex items-center gap-2">
70+
<div className="text-sm max-h-12 max-w-64 overflow-scroll">
71+
{item}
72+
</div>
73+
</div>
74+
))}
75+
</section>
76+
);
77+
};

demo/waku/src/components/footer.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export const Footer = () => {
2+
return (
3+
<footer className="p-6 lg:fixed lg:bottom-0 lg:left-0">
4+
<div>
5+
visit{" "}
6+
<a
7+
href="https://waku.gg/"
8+
target="_blank"
9+
rel="noreferrer"
10+
className="mt-4 inline-block underline"
11+
>
12+
waku.gg
13+
</a>{" "}
14+
to learn more
15+
</div>
16+
</footer>
17+
);
18+
};

demo/waku/src/components/header.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Link } from "waku";
2+
3+
export const Header = () => {
4+
return (
5+
<header className="flex items-center gap-4 p-6 lg:fixed lg:left-0 lg:top-0">
6+
<h2 className="text-lg font-bold tracking-tight">
7+
<Link to="/">Waku starter</Link>
8+
</h2>
9+
</header>
10+
);
11+
};

demo/waku/src/pages/_layout.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import "../styles.css";
2+
3+
import type { ReactNode } from "react";
4+
5+
import { Header } from "../components/header";
6+
import { Footer } from "../components/footer";
7+
8+
type RootLayoutProps = { children: ReactNode };
9+
10+
export default async function RootLayout({ children }: RootLayoutProps) {
11+
const data = await getData();
12+
13+
return (
14+
<div className="font-['Nunito']">
15+
<meta name="description" content={data.description} />
16+
<link rel="icon" type="image/png" href={data.icon} />
17+
<Header />
18+
<main className="m-6 flex items-center *:min-h-64 *:min-w-64 lg:m-0 lg:min-h-svh lg:justify-center">
19+
{children}
20+
</main>
21+
<Footer />
22+
</div>
23+
);
24+
}
25+
26+
const getData = async () => {
27+
const data = {
28+
description: "An internet website!",
29+
icon: "/images/favicon.png",
30+
};
31+
32+
return data;
33+
};
34+
35+
export const getConfig = async () => {
36+
return {
37+
render: "static",
38+
} as const;
39+
};

demo/waku/src/pages/about.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Link } from "waku";
2+
3+
export default async function AboutPage() {
4+
const data = await getData();
5+
6+
return (
7+
<div>
8+
<title>{data.title}</title>
9+
<h1 className="text-4xl font-bold tracking-tight">{data.headline}</h1>
10+
<p>{data.body}</p>
11+
<Link to="/" className="mt-4 inline-block underline">
12+
Return home
13+
</Link>
14+
</div>
15+
);
16+
}
17+
18+
const getData = async () => {
19+
const data = {
20+
title: "About",
21+
headline: "About Waku",
22+
body: "The minimal React framework",
23+
};
24+
25+
return data;
26+
};
27+
28+
export const getConfig = async () => {
29+
return {
30+
render: "static",
31+
} as const;
32+
};

demo/waku/src/pages/api/store.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { createServer } from "@llama-flow/http/server";
2+
import { workflow } from "../../workflow/basic";
3+
import { upload } from "../../workflow/llama-parse";
4+
import { storeEvent, stopEvent, searchEvent } from "../../workflow/events";
5+
6+
process.on("unhandledRejection", (reason) => {
7+
console.error("Unhandled Rejection at:", reason);
8+
});
9+
10+
export const POST = createServer(
11+
workflow,
12+
async (data, sendEvent) => {
13+
if (data.file) {
14+
const file = data.file;
15+
const job = await upload({
16+
file,
17+
});
18+
const text = await job.markdown();
19+
sendEvent(storeEvent.with(text));
20+
} else if (data.search) {
21+
const search = data.search;
22+
sendEvent(searchEvent.with(search));
23+
}
24+
},
25+
(stream) => stream.until(stopEvent),
26+
);

demo/waku/src/pages/index.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { RAG } from "../components/RAG";
2+
3+
export default async function HomePage() {
4+
const data = await getData();
5+
6+
return (
7+
<div>
8+
<title>{data.title}</title>
9+
<h1 className="text-4xl font-bold tracking-tight">{data.headline}</h1>
10+
<p>{data.body}</p>
11+
<RAG />
12+
</div>
13+
);
14+
}
15+
16+
const getData = async () => {
17+
const data = {
18+
title: "Waku",
19+
headline: "Waku",
20+
body: "Hello world!",
21+
};
22+
23+
return data;
24+
};
25+
26+
export const getConfig = async () => {
27+
return {
28+
render: "static",
29+
} as const;
30+
};

0 commit comments

Comments
 (0)