diff --git a/examples/ui-angular/.gitignore b/examples/ui-angular/.gitignore new file mode 100644 index 000000000..70a919d32 --- /dev/null +++ b/examples/ui-angular/.gitignore @@ -0,0 +1,46 @@ +# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings +__screenshots__/ + +# System files +.DS_Store +Thumbs.db + +# LangGraph API +.langgraph_api diff --git a/examples/ui-angular/angular.json b/examples/ui-angular/angular.json new file mode 100644 index 000000000..6d953eac3 --- /dev/null +++ b/examples/ui-angular/angular.json @@ -0,0 +1,97 @@ +{ + "$schema": "../../node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "example-angular": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "browser": "src/main.ts", + "polyfills": [ + "zone.js" + ], + "tsConfig": "tsconfig.app.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.css" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "example-angular:build:production" + }, + "development": { + "buildTarget": "example-angular:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular/build:extract-i18n" + }, + "test": { + "builder": "@angular/build:karma", + "options": { + "polyfills": [ + "zone.js", + "zone.js/testing" + ], + "tsConfig": "tsconfig.spec.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.css" + ] + } + } + } + } + }, + "cli": { + "cache": { + "enabled": false + } + } +} diff --git a/examples/ui-angular/langgraph.json b/examples/ui-angular/langgraph.json new file mode 100644 index 000000000..9d46f4d1a --- /dev/null +++ b/examples/ui-angular/langgraph.json @@ -0,0 +1,7 @@ +{ + "node_version": "22", + "graphs": { + "agent": "./src/agent.mts:graph" + }, + "env": ".env" +} \ No newline at end of file diff --git a/examples/ui-angular/package.json b/examples/ui-angular/package.json new file mode 100644 index 000000000..e466551d6 --- /dev/null +++ b/examples/ui-angular/package.json @@ -0,0 +1,51 @@ +{ + "name": "@examples/ui-angular", + "version": "0.0.0", + "scripts": { + "dev": "turbo dev:client dev:server", + "dev:client": "ng serve", + "dev:server": "langgraphjs dev --no-browser", + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "format": "prettier --write src", + "lint": "prettier --check src" + }, + "prettier": { + "printWidth": 100, + "singleQuote": true, + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "angular" + } + } + ] + }, + "private": true, + "dependencies": { + "@angular/common": "^20.3.0", + "@angular/compiler": "^20.3.0", + "@angular/core": "^20.3.0", + "@angular/forms": "^20.3.0", + "@angular/platform-browser": "^20.3.0", + "@angular/router": "^20.3.0", + "@langchain/angular": "workspace:*", + "@langchain/core": "^1.0.1", + "@langchain/langgraph": "workspace:*", + "@langchain/langgraph-sdk": "workspace:*", + "@langchain/openai": "^1.0.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zod": "^3.23.8", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular/build": "^20.3.9", + "@angular/cli": "^20.3.9", + "@angular/compiler-cli": "^20.3.0", + "typescript": "~5.9.2" + } +} diff --git a/examples/ui-angular/src/agent.mts b/examples/ui-angular/src/agent.mts new file mode 100644 index 000000000..9c32613a6 --- /dev/null +++ b/examples/ui-angular/src/agent.mts @@ -0,0 +1,18 @@ +import type { BaseMessage } from "@langchain/core/messages"; +import { StateGraph, MessagesZodMeta, START } from "@langchain/langgraph"; +import { registry } from "@langchain/langgraph/zod"; +import { ChatOpenAI } from "@langchain/openai"; +import { z } from "zod/v4"; + +const llm = new ChatOpenAI({ model: "gpt-4o-mini" }); + +const schema = z.object({ + messages: z.custom().register(registry, MessagesZodMeta), +}); + +export const graph = new StateGraph(schema) + .addNode("agent", async ({ messages }) => ({ + messages: await llm.invoke(messages), + })) + .addEdge(START, "agent") + .compile(); diff --git a/examples/ui-angular/src/app.ts b/examples/ui-angular/src/app.ts new file mode 100644 index 000000000..4982ba2d5 --- /dev/null +++ b/examples/ui-angular/src/app.ts @@ -0,0 +1,47 @@ +import { Component, signal } from '@angular/core'; +import { useStream } from '@langchain/angular'; +import { FormsModule } from '@angular/forms'; +import type { Message } from '@langchain/langgraph-sdk'; + +@Component({ + selector: 'app-root', + imports: [FormsModule], + template: ` +
+
+ @for (message of stream.messages(); track message.id) { +
{{ message.content }}
+ } +
+ +
+ + +
+
+ `, +}) +export class App { + protected message = signal(''); + + protected stream = useStream({ + assistantId: 'agent', + apiUrl: 'http://localhost:2024', + }); + + protected onSubmit() { + const newMessage = { content: this.message(), type: 'human' }; + this.stream.submit( + { messages: [newMessage] }, + { + optimisticValues: (prev) => ({ + ...prev, + messages: [...((prev['messages'] ?? []) as Message[]), newMessage], + }), + } + ); + + // reset form + this.message.set(''); + } +} diff --git a/examples/ui-angular/src/index.html b/examples/ui-angular/src/index.html new file mode 100644 index 000000000..7ce9f53eb --- /dev/null +++ b/examples/ui-angular/src/index.html @@ -0,0 +1,13 @@ + + + + + ExampleAngular + + + + + + + + diff --git a/examples/ui-angular/src/main.ts b/examples/ui-angular/src/main.ts new file mode 100644 index 000000000..cb8ac1f3e --- /dev/null +++ b/examples/ui-angular/src/main.ts @@ -0,0 +1,10 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core'; +import { App } from './app'; + +bootstrapApplication(App, { + providers: [ + provideBrowserGlobalErrorListeners(), + provideZoneChangeDetection({ eventCoalescing: true }), + ], +}).catch((err) => console.error(err)); diff --git a/examples/ui-angular/src/styles.css b/examples/ui-angular/src/styles.css new file mode 100644 index 000000000..90d4ee007 --- /dev/null +++ b/examples/ui-angular/src/styles.css @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/examples/ui-angular/tsconfig.app.json b/examples/ui-angular/tsconfig.app.json new file mode 100644 index 000000000..264f459bf --- /dev/null +++ b/examples/ui-angular/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts" + ] +} diff --git a/examples/ui-angular/tsconfig.json b/examples/ui-angular/tsconfig.json new file mode 100644 index 000000000..e4955f26b --- /dev/null +++ b/examples/ui-angular/tsconfig.json @@ -0,0 +1,34 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "ES2022", + "module": "preserve" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "typeCheckHostBindings": true, + "strictTemplates": true + }, + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/examples/ui-angular/tsconfig.spec.json b/examples/ui-angular/tsconfig.spec.json new file mode 100644 index 000000000..04df34cfe --- /dev/null +++ b/examples/ui-angular/tsconfig.spec.json @@ -0,0 +1,14 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/examples/ui-angular/turbo.json b/examples/ui-angular/turbo.json new file mode 100644 index 000000000..27d8fc09c --- /dev/null +++ b/examples/ui-angular/turbo.json @@ -0,0 +1,28 @@ +{ + "extends": [ + "//" + ], + "tasks": { + "build": { + "outputs": [ + "**/dist/**" + ] + }, + "build:internal": { + "dependsOn": [ + "^build:internal" + ], + "outputs": [ + "**/dist/**" + ] + }, + "dev:client": { + "cache": false, + "persistent": true + }, + "dev:server": { + "cache": false, + "persistent": true + } + } +} \ No newline at end of file diff --git a/examples/ui-svelte/.gitignore b/examples/ui-svelte/.gitignore new file mode 100644 index 000000000..5a23824c2 --- /dev/null +++ b/examples/ui-svelte/.gitignore @@ -0,0 +1,3 @@ + +# LangGraph API +.langgraph_api diff --git a/examples/ui-svelte/index.html b/examples/ui-svelte/index.html new file mode 100644 index 000000000..b5b125269 --- /dev/null +++ b/examples/ui-svelte/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Svelte + TS + + +
+ + + diff --git a/examples/ui-svelte/langgraph.json b/examples/ui-svelte/langgraph.json new file mode 100644 index 000000000..9d46f4d1a --- /dev/null +++ b/examples/ui-svelte/langgraph.json @@ -0,0 +1,7 @@ +{ + "node_version": "22", + "graphs": { + "agent": "./src/agent.mts:graph" + }, + "env": ".env" +} \ No newline at end of file diff --git a/examples/ui-svelte/package.json b/examples/ui-svelte/package.json new file mode 100644 index 000000000..d18e93434 --- /dev/null +++ b/examples/ui-svelte/package.json @@ -0,0 +1,31 @@ +{ + "name": "@examples/ui-svelte", + "private": true, + "type": "module", + "scripts": { + "dev": "turbo dev:client dev:server", + "dev:client": "vite", + "dev:server": "langgraphjs dev --no-browser", + "build:internal": "vite build", + "format": "prettier --write src", + "lint": "prettier --check src", + "preview": "vite preview" + }, + "dependencies": { + "@langchain/core": "^1.0.1", + "@langchain/langgraph": "workspace:*", + "@langchain/langgraph-sdk": "workspace:*", + "@langchain/openai": "^1.0.0", + "@langchain/svelte": "workspace:*", + "zod": "^3.23.8" + }, + "devDependencies": { + "@langchain/langgraph-cli": "workspace:*", + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "prettier": "^2.8.3", + "svelte": "^5.43.5", + "tsx": "^4.19.3", + "typescript": "^5.4.5", + "vite": "^7.0.0" + } +} diff --git a/examples/ui-svelte/src/App.svelte b/examples/ui-svelte/src/App.svelte new file mode 100644 index 000000000..847e9e2ce --- /dev/null +++ b/examples/ui-svelte/src/App.svelte @@ -0,0 +1,42 @@ + + +
+

Vite + Svelte

+ +
+ {#each $messages as message} +
{message.content}
+ {/each} + +
+ + +
+
+
diff --git a/examples/ui-svelte/src/agent.mts b/examples/ui-svelte/src/agent.mts new file mode 100644 index 000000000..9c32613a6 --- /dev/null +++ b/examples/ui-svelte/src/agent.mts @@ -0,0 +1,18 @@ +import type { BaseMessage } from "@langchain/core/messages"; +import { StateGraph, MessagesZodMeta, START } from "@langchain/langgraph"; +import { registry } from "@langchain/langgraph/zod"; +import { ChatOpenAI } from "@langchain/openai"; +import { z } from "zod/v4"; + +const llm = new ChatOpenAI({ model: "gpt-4o-mini" }); + +const schema = z.object({ + messages: z.custom().register(registry, MessagesZodMeta), +}); + +export const graph = new StateGraph(schema) + .addNode("agent", async ({ messages }) => ({ + messages: await llm.invoke(messages), + })) + .addEdge(START, "agent") + .compile(); diff --git a/examples/ui-svelte/src/main.ts b/examples/ui-svelte/src/main.ts new file mode 100644 index 000000000..a319f9065 --- /dev/null +++ b/examples/ui-svelte/src/main.ts @@ -0,0 +1,8 @@ +import { mount } from "svelte"; +import App from "./App.svelte"; + +const app = mount(App, { + target: document.getElementById("app")!, +}); + +export default app; diff --git a/examples/ui-svelte/svelte.config.js b/examples/ui-svelte/svelte.config.js new file mode 100644 index 000000000..96b345548 --- /dev/null +++ b/examples/ui-svelte/svelte.config.js @@ -0,0 +1,8 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +/** @type {import("@sveltejs/vite-plugin-svelte").SvelteConfig} */ +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/examples/ui-svelte/tsconfig.app.json b/examples/ui-svelte/tsconfig.app.json new file mode 100644 index 000000000..227a6c672 --- /dev/null +++ b/examples/ui-svelte/tsconfig.app.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/examples/ui-svelte/tsconfig.json b/examples/ui-svelte/tsconfig.json new file mode 100644 index 000000000..1ffef600d --- /dev/null +++ b/examples/ui-svelte/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/examples/ui-svelte/tsconfig.node.json b/examples/ui-svelte/tsconfig.node.json new file mode 100644 index 000000000..f85a39906 --- /dev/null +++ b/examples/ui-svelte/tsconfig.node.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/examples/ui-svelte/turbo.json b/examples/ui-svelte/turbo.json new file mode 100644 index 000000000..27d8fc09c --- /dev/null +++ b/examples/ui-svelte/turbo.json @@ -0,0 +1,28 @@ +{ + "extends": [ + "//" + ], + "tasks": { + "build": { + "outputs": [ + "**/dist/**" + ] + }, + "build:internal": { + "dependsOn": [ + "^build:internal" + ], + "outputs": [ + "**/dist/**" + ] + }, + "dev:client": { + "cache": false, + "persistent": true + }, + "dev:server": { + "cache": false, + "persistent": true + } + } +} \ No newline at end of file diff --git a/examples/ui-svelte/vite.config.ts b/examples/ui-svelte/vite.config.ts new file mode 100644 index 000000000..7e6817b8b --- /dev/null +++ b/examples/ui-svelte/vite.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vite"; +import { svelte } from "@sveltejs/vite-plugin-svelte"; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [svelte()], + clearScreen: false, +}); diff --git a/examples/ui-vue/.gitignore b/examples/ui-vue/.gitignore new file mode 100644 index 000000000..5a23824c2 --- /dev/null +++ b/examples/ui-vue/.gitignore @@ -0,0 +1,3 @@ + +# LangGraph API +.langgraph_api diff --git a/examples/ui-vue/index.html b/examples/ui-vue/index.html new file mode 100644 index 000000000..143557b52 --- /dev/null +++ b/examples/ui-vue/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Vue + TS + + +
+ + + diff --git a/examples/ui-vue/langgraph.json b/examples/ui-vue/langgraph.json new file mode 100644 index 000000000..9d46f4d1a --- /dev/null +++ b/examples/ui-vue/langgraph.json @@ -0,0 +1,7 @@ +{ + "node_version": "22", + "graphs": { + "agent": "./src/agent.mts:graph" + }, + "env": ".env" +} \ No newline at end of file diff --git a/examples/ui-vue/package.json b/examples/ui-vue/package.json new file mode 100644 index 000000000..be00f3fc7 --- /dev/null +++ b/examples/ui-vue/package.json @@ -0,0 +1,33 @@ +{ + "name": "@examples/ui-vue", + "private": true, + "type": "module", + "scripts": { + "dev": "turbo dev:client dev:server", + "dev:client": "vite", + "dev:server": "langgraphjs dev --no-browser", + "build:internal": "vite build", + "format": "prettier --write src", + "lint": "prettier --check src", + "preview": "vite preview" + }, + "dependencies": { + "@langchain/core": "^1.0.1", + "@langchain/langgraph": "workspace:*", + "@langchain/langgraph-sdk": "workspace:*", + "@langchain/openai": "^1.0.0", + "@langchain/vue": "workspace:*", + "vue": "^3.5.24", + "zod": "^3.23.8" + }, + "devDependencies": { + "@langchain/langgraph-cli": "workspace:*", + "@types/react": "^19.0.8", + "@types/react-dom": "^19.0.3", + "@vitejs/plugin-vue": "^6.0.1", + "prettier": "^2.8.3", + "tsx": "^4.19.3", + "typescript": "^5.4.5", + "vite": "^7.0.0" + } +} diff --git a/examples/ui-vue/src/App.vue b/examples/ui-vue/src/App.vue new file mode 100644 index 000000000..9f44477a2 --- /dev/null +++ b/examples/ui-vue/src/App.vue @@ -0,0 +1,37 @@ + + +