From 58f040b7d8f533f6887dd6767bb5cd9ed2744edd Mon Sep 17 00:00:00 2001 From: Mathijs de Bruin Date: Mon, 14 Jul 2025 12:34:49 +0100 Subject: [PATCH 1/5] Basic moon setup. --- .gitignore | 4 +++ .moon/toolchain.yml | 11 ++++++++ .moon/workspace.yml | 12 +++++++++ .prototools | 1 + .python-version | 1 - README.md | 57 +++++++++++------------------------------- apps/backend/moon.yml | 21 ++++++++++++++++ apps/frontend/moon.yml | 6 +++++ 8 files changed, 69 insertions(+), 44 deletions(-) create mode 100644 .moon/toolchain.yml create mode 100644 .moon/workspace.yml create mode 100644 .prototools delete mode 100644 .python-version create mode 100644 apps/backend/moon.yml create mode 100644 apps/frontend/moon.yml diff --git a/.gitignore b/.gitignore index e5a35cc6..edf70975 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ .env __pycache__/ .langgraph_api/ + +# moon +.moon/cache +.moon/docker diff --git a/.moon/toolchain.yml b/.moon/toolchain.yml new file mode 100644 index 00000000..baae0a19 --- /dev/null +++ b/.moon/toolchain.yml @@ -0,0 +1,11 @@ +# https://moonrepo.dev/docs/config/toolchain +$schema: "https://moonrepo.dev/schemas/toolchain.json" + +python: + version: "3.12" + packageManager: "uv" + +node: + version: "24" + packageManager: "pnpm" + inferTasksFromScripts: true diff --git a/.moon/workspace.yml b/.moon/workspace.yml new file mode 100644 index 00000000..342bc14e --- /dev/null +++ b/.moon/workspace.yml @@ -0,0 +1,12 @@ +# https://moonrepo.dev/docs/config/workspace +$schema: "./cache/schemas/workspace.json" + +# extends: './shared/workspace.yml' + +projects: + - "apps/*" + - "packages/*" + +vcs: + manager: "git" + defaultBranch: "main" diff --git a/.prototools b/.prototools new file mode 100644 index 00000000..305e5b18 --- /dev/null +++ b/.prototools @@ -0,0 +1 @@ +moon = "1.38.5" diff --git a/.python-version b/.python-version deleted file mode 100644 index 24ee5b1b..00000000 --- a/.python-version +++ /dev/null @@ -1 +0,0 @@ -3.13 diff --git a/README.md b/README.md index f711791a..101a634d 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,12 @@ Opinionated SvelteKit/Flowbite based LLM frontend for LangGraph server. ## Prerequisites -- Python 3.12 -- Node.js 24 LTS -- [uv](https://docs.astral.sh/uv/) (Python package manager) -- pnpm (Node.js package manager) +- [Install moonrepo](https://moonrepo.dev/docs/install), which installs all other dependencies: + + * Python 3.12 + * Node.js 24 LTS + * [uv](https://docs.astral.sh/uv/) (Python package manager) + * pnpm (Node.js package manager) ## Configuration @@ -54,43 +56,23 @@ Configure the following variables in `apps/frontend/.env`: ## Getting Started -### Backend Setup - -Navigate to the backend directory and install dependencies: - -```bash -cd apps/backend -uv sync -``` - -Start the development server: - -```bash -uv run langgraph dev -``` - -### Frontend Setup +### Start dev servers -Navigate to the frontend directory and install dependencies: +The following command ensures dependencies are installed and starts dev servers for frontend and backend, with hot reload: ```bash -cd apps/frontend -pnpm install +moon :dev ``` -Start the development server: +### Run local checks -```bash -npm run dev -``` - -Or open the app in a new browser tab: +Run all checks (linting, type checking, formatting): ```bash -npm run dev -- --open +moon check --all ``` -## Development +## Tooling ### Backend Development @@ -108,17 +90,6 @@ The frontend is built with modern web technologies: - Playwright for end-to-end testing - Vitest for unit testing -#### Available Scripts - -- `npm run dev` - Start development server -- `npm run build` - Build for production -- `npm run preview` - Preview production build -- `npm run test` - Run all tests -- `npm run test:unit` - Run unit tests -- `npm run test:e2e` - Run end-to-end tests -- `npm run lint` - Lint code -- `npm run format` - Format code - ## Production ### Frontend Build @@ -147,4 +118,4 @@ svelte-langgraph/ │ ├── messages/ # Internationalization files │ └── e2e/ # End-to-end tests └── README.md -``` \ No newline at end of file +``` diff --git a/apps/backend/moon.yml b/apps/backend/moon.yml new file mode 100644 index 00000000..4cdad5c8 --- /dev/null +++ b/apps/backend/moon.yml @@ -0,0 +1,21 @@ +# https://moonrepo.dev/docs/config/project +$schema: "https://moonrepo.dev/schemas/project.json" + +language: python +stack: backend +type: application + +tasks: + format: + command: "ruff format" + lint: + command: "ruff check" + lint-fix: + extends: lint + args: "--fix" + local: true + typecheck: + command: "pyright" + dev: + command: "langgraph dev --no-browser" + preset: "watcher" diff --git a/apps/frontend/moon.yml b/apps/frontend/moon.yml new file mode 100644 index 00000000..d85d88ce --- /dev/null +++ b/apps/frontend/moon.yml @@ -0,0 +1,6 @@ +# https://moonrepo.dev/docs/config/project +$schema: "https://moonrepo.dev/schemas/project.json" + +language: typescript +stack: frontend +type: application From cb0a87af9917d0489d1bff88223f8aa0a10f2c68 Mon Sep 17 00:00:00 2001 From: Mathijs de Bruin Date: Mon, 14 Jul 2025 12:36:40 +0100 Subject: [PATCH 2/5] Backend linter fixups. --- apps/backend/src/auth.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/backend/src/auth.py b/apps/backend/src/auth.py index eb65f1fa..d62765cd 100644 --- a/apps/backend/src/auth.py +++ b/apps/backend/src/auth.py @@ -1,15 +1,14 @@ import logging -import os +# import os -from descope import AuthException from langgraph_sdk import Auth from langgraph_sdk.auth.types import MinimalUserDict -from descope import DescopeClient +# from descope import DescopeClient logger = logging.getLogger(__name__) -descope_client = DescopeClient(project_id=os.getenv("DESCOPE_PROJECT_ID", "")) +# descope_client = DescopeClient(project_id=os.getenv("DESCOPE_PROJECT_ID", "")) # The "Auth" object is a container that LangGraph will use to mark our authentication function auth = Auth() @@ -54,7 +53,7 @@ async def get_current_user(authorization: str | None) -> MinimalUserDict: # permissions=claims["permissions"], # ) - return user + # return user @auth.on From a8c9e211d7708f577a0f590f1d564d39cdae037a Mon Sep 17 00:00:00 2001 From: Mathijs de Bruin Date: Mon, 14 Jul 2025 12:37:24 +0100 Subject: [PATCH 3/5] Fixup backend. --- apps/backend/src/graph.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/backend/src/graph.py b/apps/backend/src/graph.py index d13e4efa..891080f3 100755 --- a/apps/backend/src/graph.py +++ b/apps/backend/src/graph.py @@ -73,10 +73,10 @@ def make_graph(config: RunnableConfig) -> CompiledStateGraph: async def main(): load_dotenv() - agent = make_graph() - config = RunnableConfig(configurable={"thread_id": "1"}) + agent = make_graph(config) + user_input = input(f"{INITIAL_MESSAGE}\n") while True: From 7b47471e0e5a57f0457bcd18c4fd3dec204fba35 Mon Sep 17 00:00:00 2001 From: Mathijs de Bruin Date: Mon, 14 Jul 2025 12:38:10 +0100 Subject: [PATCH 4/5] Prettier. --- apps/frontend/README.md | 7 +- apps/frontend/moon.yml | 2 +- apps/frontend/src/app.html | 20 +- apps/frontend/src/app.tailwind.css | 5 +- apps/frontend/src/auth.ts | 8 +- apps/frontend/src/hooks.server.ts | 2 +- apps/frontend/src/routes/+layout.server.ts | 10 +- apps/frontend/src/routes/+layout.svelte | 37 ++- apps/frontend/src/routes/+page.svelte | 10 +- apps/frontend/src/routes/chat/+page.svelte | 291 +++++++++++------- .../src/routes/signin/+page.server.ts | 6 +- .../src/routes/signout/+page.server.ts | 6 +- 12 files changed, 234 insertions(+), 170 deletions(-) diff --git a/apps/frontend/README.md b/apps/frontend/README.md index 460af5a6..824c7e6e 100644 --- a/apps/frontend/README.md +++ b/apps/frontend/README.md @@ -1,13 +1,16 @@ # sv + Svelte frontend project. ## Getting started ### Requirements -* pnpm -* Node 24 LTS + +- pnpm +- Node 24 LTS ### Install deps + ```bash pnpm install ``` diff --git a/apps/frontend/moon.yml b/apps/frontend/moon.yml index d85d88ce..53dc1860 100644 --- a/apps/frontend/moon.yml +++ b/apps/frontend/moon.yml @@ -1,5 +1,5 @@ # https://moonrepo.dev/docs/config/project -$schema: "https://moonrepo.dev/schemas/project.json" +$schema: 'https://moonrepo.dev/schemas/project.json' language: typescript stack: frontend diff --git a/apps/frontend/src/app.html b/apps/frontend/src/app.html index 2a13dee2..f7989f72 100644 --- a/apps/frontend/src/app.html +++ b/apps/frontend/src/app.html @@ -1,15 +1,13 @@ + + + + + %sveltekit.head% + - - - - - %sveltekit.head% - - - -
%sveltekit.body%
- - + +
%sveltekit.body%
+ diff --git a/apps/frontend/src/app.tailwind.css b/apps/frontend/src/app.tailwind.css index a9ebb9ff..a393ca3e 100644 --- a/apps/frontend/src/app.tailwind.css +++ b/apps/frontend/src/app.tailwind.css @@ -1,4 +1,4 @@ -@import "tailwindcss"; +@import 'tailwindcss'; @plugin '@tailwindcss/forms'; @plugin '@tailwindcss/typography'; @@ -36,9 +36,8 @@ @source '../node_modules/flowbite-svelte-blocks/dist'; @layer base { - /* disable chrome cancel button */ - input[type="search"]::-webkit-search-cancel-button { + input[type='search']::-webkit-search-cancel-button { display: none; } } diff --git a/apps/frontend/src/auth.ts b/apps/frontend/src/auth.ts index 4039ef7a..b50fe49c 100644 --- a/apps/frontend/src/auth.ts +++ b/apps/frontend/src/auth.ts @@ -1,6 +1,6 @@ -import { SvelteKitAuth } from "@auth/sveltekit" -import Descope from "@auth/sveltekit/providers/descope" +import { SvelteKitAuth } from '@auth/sveltekit'; +import Descope from '@auth/sveltekit/providers/descope'; export const { handle, signIn, signOut } = SvelteKitAuth({ - providers: [Descope], -}) + providers: [Descope] +}); diff --git a/apps/frontend/src/hooks.server.ts b/apps/frontend/src/hooks.server.ts index 2beaefb8..8e806b2b 100644 --- a/apps/frontend/src/hooks.server.ts +++ b/apps/frontend/src/hooks.server.ts @@ -1,7 +1,7 @@ import type { Handle } from '@sveltejs/kit'; import { sequence } from '@sveltejs/kit/hooks'; import { paraglideMiddleware } from '$lib/paraglide/server'; -import { handle as handleAuth } from "./auth"; +import { handle as handleAuth } from './auth'; const handleParaglide: Handle = ({ event, resolve }) => paraglideMiddleware(event.request, ({ request, locale }) => { diff --git a/apps/frontend/src/routes/+layout.server.ts b/apps/frontend/src/routes/+layout.server.ts index 54c76a3d..6a306f19 100644 --- a/apps/frontend/src/routes/+layout.server.ts +++ b/apps/frontend/src/routes/+layout.server.ts @@ -1,9 +1,9 @@ -import type { LayoutServerLoad } from "./$types" +import type { LayoutServerLoad } from './$types'; export const load: LayoutServerLoad = async (event) => { - const session = await event.locals.auth() + const session = await event.locals.auth(); return { - session, - } -} + session + }; +}; diff --git a/apps/frontend/src/routes/+layout.svelte b/apps/frontend/src/routes/+layout.svelte index bd2711b1..4dabd7df 100644 --- a/apps/frontend/src/routes/+layout.svelte +++ b/apps/frontend/src/routes/+layout.svelte @@ -5,11 +5,7 @@ import { page } from '$app/state'; import { MessagesOutline } from 'flowbite-svelte-icons'; - import { - UserCircleSolid, - ClipboardListSolid, - ArrowRightAltSolid - } from 'flowbite-svelte-icons'; + import { UserCircleSolid, ClipboardListSolid, ArrowRightAltSolid } from 'flowbite-svelte-icons'; import { Button, Navbar, @@ -29,60 +25,63 @@ - + My AI Chat UI -
+
{#if page.data.session} - +
{page.data.session.user?.name ?? 'User'} - + {page.data.session.user?.email ?? 'email@example.com'}
- + Dashboard - + Profile - + Sign out diff --git a/apps/frontend/src/routes/+page.svelte b/apps/frontend/src/routes/+page.svelte index 9a8d9bca..3258b615 100644 --- a/apps/frontend/src/routes/+page.svelte +++ b/apps/frontend/src/routes/+page.svelte @@ -41,7 +41,7 @@
@@ -59,7 +59,7 @@ {#snippet head()}FEATURED IN{/snippet}
- + - + - + = 0; i--) { @@ -154,7 +153,7 @@ break; } } - + if (aiMessageIndex !== -1) { // Update the AI message in place and force reactivity messages[aiMessageIndex] = { ...aimessage }; @@ -178,51 +177,14 @@ } - - {#if !chat_started} -
-
+
+
-
+
-

+

{#if page.data.session?.user?.name} Hey {page.data.session.user.name}, how can I help you today? {:else if page.data.session?.user?.email} @@ -231,53 +193,63 @@ How can I help you today? {/if}

-

- I'm here to assist with your questions, provide information, help with tasks, or engage in conversation. +

+ I'm here to assist with your questions, provide information, help with tasks, or + engage in conversation.

- + -
- - - - - - -
-
- -
-
+ +
+