├── .codespellignore ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .yarnrc.yml ├── CONCEPTS.md ├── LICENSE ├── README.md ├── apps ├── docs │ ├── README.md │ ├── custom-agents │ │ ├── configuration.mdx │ │ └── overview.mdx │ ├── docs.json │ ├── favicon.svg │ ├── index.mdx │ ├── logo │ │ ├── dark.svg │ │ └── light.svg │ ├── package.json │ ├── quickstart.mdx │ └── setup │ │ ├── agents.mdx │ │ ├── authentication.mdx │ │ ├── mcp-server.mdx │ │ └── rag-server.mdx └── web │ ├── .dockerignore │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── components.json │ ├── eslint.config.js │ ├── next.config.mjs │ ├── package.json │ ├── postcss.config.mjs │ ├── prettier.config.js │ ├── scripts │ ├── update-agents-mcp-auth-status.ts │ └── update-agents-mcp-url.ts │ ├── src │ ├── app │ │ ├── (app) │ │ │ ├── agents │ │ │ │ └── page.tsx │ │ │ ├── inbox │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ ├── rag │ │ │ │ └── page.tsx │ │ │ └── tools │ │ │ │ ├── page.tsx │ │ │ │ └── playground │ │ │ │ └── page.tsx │ │ ├── (auth) │ │ │ ├── auth-layout.tsx │ │ │ ├── forgot-password │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── reset-password │ │ │ │ └── page.tsx │ │ │ ├── signin │ │ │ │ └── page.tsx │ │ │ └── signup │ │ │ │ └── page.tsx │ │ ├── api │ │ │ ├── auth │ │ │ │ └── callback │ │ │ │ │ └── route.ts │ │ │ ├── langgraph │ │ │ │ ├── defaults │ │ │ │ │ └── route.ts │ │ │ │ └── proxy │ │ │ │ │ └── [..._path] │ │ │ │ │ └── route.ts │ │ │ └── oap_mcp │ │ │ │ ├── proxy-request.ts │ │ │ │ └── route.ts │ │ ├── debug-auth │ │ │ └── page.tsx │ │ ├── favicon.ico │ │ ├── globals.css │ │ └── layout.tsx │ ├── components │ │ ├── agent-inbox │ │ │ ├── components │ │ │ │ ├── generic-inbox-item.tsx │ │ │ │ ├── generic-interrupt-value.tsx │ │ │ │ ├── inbox-buttons.tsx │ │ │ │ ├── inbox-item-input.tsx │ │ │ │ ├── inbox-item.tsx │ │ │ │ ├── interrupt-details-view.tsx │ │ │ │ ├── interrupted-inbox-item.tsx │ │ │ │ ├── pagination.tsx │ │ │ │ ├── state-view.tsx │ │ │ │ ├── statuses.tsx │ │ │ │ ├── thread-actions-view.tsx │ │ │ │ ├── thread-id.tsx │ │ │ │ ├── tool-call-table.tsx │ │ │ │ └── views │ │ │ │ │ ├── EmptyStateView.tsx │ │ │ │ │ ├── InterruptedDescriptionView.tsx │ │ │ │ │ ├── NonInterruptedDescriptionView.tsx │ │ │ │ │ ├── ThreadStateView.tsx │ │ │ │ │ └── index.ts │ │ │ ├── constants.ts │ │ │ ├── contexts │ │ │ │ ├── ThreadContext.tsx │ │ │ │ └── utils.ts │ │ │ ├── hooks │ │ │ │ └── use-interrupted-actions.tsx │ │ │ ├── inbox-view.tsx │ │ │ ├── index.tsx │ │ │ ├── thread-view.tsx │ │ │ ├── types.ts │ │ │ ├── utils.ts │ │ │ └── utils │ │ │ │ └── logger.ts │ │ ├── auth │ │ │ └── debug.tsx │ │ ├── icons │ │ │ ├── github.tsx │ │ │ ├── graph.tsx │ │ │ └── langgraph.tsx │ │ ├── inbox-sidebar │ │ │ └── index.tsx │ │ ├── sidebar │ │ │ ├── app-sidebar.tsx │ │ │ ├── index.tsx │ │ │ ├── nav-main.tsx │ │ │ ├── nav-user.tsx │ │ │ └── sidebar-header.tsx │ │ └── ui │ │ │ ├── agents-combobox.tsx │ │ │ ├── alert-dialog.tsx │ │ │ ├── alert.tsx │ │ │ ├── avatar.tsx │ │ │ ├── badge.tsx │ │ │ ├── breadcrumb.tsx │ │ │ ├── button.tsx │ │ │ ├── card.tsx │ │ │ ├── collapsible.tsx │ │ │ ├── command.tsx │ │ │ ├── default-star.tsx │ │ │ ├── dialog.tsx │ │ │ ├── dropdown-menu.tsx │ │ │ ├── input.tsx │ │ │ ├── label.tsx │ │ │ ├── markdown-text │ │ │ ├── index.tsx │ │ │ ├── styles.css │ │ │ └── syntax-highlighter.tsx │ │ │ ├── pagination.tsx │ │ │ ├── password-input.tsx │ │ │ ├── popover.tsx │ │ │ ├── resizable.tsx │ │ │ ├── scroll-area.tsx │ │ │ ├── select.tsx │ │ │ ├── separator.tsx │ │ │ ├── sheet.tsx │ │ │ ├── sidebar.tsx │ │ │ ├── skeleton.tsx │ │ │ ├── slider.tsx │ │ │ ├── sonner.tsx │ │ │ ├── switch.tsx │ │ │ ├── table.tsx │ │ │ ├── tabs.tsx │ │ │ ├── textarea.tsx │ │ │ ├── tool-search.tsx │ │ │ ├── tooltip-icon-button.tsx │ │ │ └── tooltip.tsx │ ├── constants.ts │ ├── features │ │ ├── agents │ │ │ ├── components │ │ │ │ ├── agent-card.tsx │ │ │ │ ├── agent-dashboard │ │ │ │ │ └── index.tsx │ │ │ │ ├── create-edit-agent-dialogs │ │ │ │ │ ├── agent-form.tsx │ │ │ │ │ ├── create-agent-dialog.tsx │ │ │ │ │ ├── edit-agent-dialog.tsx │ │ │ │ │ └── graph-select.tsx │ │ │ │ ├── page-header.tsx │ │ │ │ └── templates-list │ │ │ │ │ ├── agent-list.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── templates-card.tsx │ │ │ │ │ └── templates-loading.tsx │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── chat │ │ │ ├── components │ │ │ │ ├── chat-breadcrumb │ │ │ │ │ └── index.tsx │ │ │ │ ├── configuration-sidebar │ │ │ │ │ ├── config-field.tsx │ │ │ │ │ ├── config-section.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── sidebar-buttons │ │ │ │ │ └── index.tsx │ │ │ │ ├── thread-history-sidebar │ │ │ │ │ └── index.tsx │ │ │ │ └── thread │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── messages │ │ │ │ │ ├── ContentBlocksPreview.tsx │ │ │ │ │ ├── MultimodalPreview.tsx │ │ │ │ │ ├── ai.tsx │ │ │ │ │ ├── human.tsx │ │ │ │ │ ├── shared.tsx │ │ │ │ │ └── tool-calls.tsx │ │ │ ├── hooks │ │ │ │ └── use-config-store.tsx │ │ │ ├── index.tsx │ │ │ ├── providers │ │ │ │ └── Stream.tsx │ │ │ └── utils │ │ │ │ ├── api-key.tsx │ │ │ │ ├── content-string.tsx │ │ │ │ └── tool-responses.ts │ │ ├── forgot-password │ │ │ └── index.tsx │ │ ├── inbox │ │ │ └── index.tsx │ │ ├── rag │ │ │ ├── components │ │ │ │ ├── collections-card.tsx │ │ │ │ ├── collections-list │ │ │ │ │ ├── collection-actions.tsx │ │ │ │ │ ├── delete-collection-alert.tsx │ │ │ │ │ ├── edit-collection-dialog.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── create-collection-dialog.tsx │ │ │ │ ├── documents-card │ │ │ │ │ ├── documents-table.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── empty-collections.tsx │ │ │ ├── hooks │ │ │ │ └── use-rag.tsx │ │ │ ├── index.tsx │ │ │ └── providers │ │ │ │ └── RAG.tsx │ │ ├── reset-password │ │ │ └── index.tsx │ │ ├── signin │ │ │ └── index.tsx │ │ ├── signup │ │ │ └── index.tsx │ │ └── tools │ │ │ ├── components │ │ │ ├── tool-card │ │ │ │ └── index.tsx │ │ │ ├── tool-details-dialog │ │ │ │ ├── index.tsx │ │ │ │ └── schema-renderer.tsx │ │ │ └── tool-list-command.tsx │ │ │ ├── index.tsx │ │ │ └── playground │ │ │ ├── components │ │ │ ├── response-viewer.tsx │ │ │ └── schema-form.tsx │ │ │ └── index.tsx │ ├── hooks │ │ ├── use-agent-config.tsx │ │ ├── use-agents.tsx │ │ ├── use-fetch-preselected-tools.tsx │ │ ├── use-file-upload.tsx │ │ ├── use-local-storage.tsx │ │ ├── use-mcp.tsx │ │ ├── use-mobile.ts │ │ ├── use-scroll-position.tsx │ │ ├── use-search-tools.tsx │ │ └── useMediaQuery.tsx │ ├── lib │ │ ├── agent-utils.ts │ │ ├── auth │ │ │ ├── middleware.ts │ │ │ ├── supabase-client.ts │ │ │ ├── supabase.ts │ │ │ └── types.ts │ │ ├── client.ts │ │ ├── environment │ │ │ └── deployments.ts │ │ ├── multimodal-utils.ts │ │ ├── ui-config.ts │ │ └── utils.ts │ ├── middleware.ts │ ├── providers │ │ ├── Agents.tsx │ │ ├── Auth.tsx │ │ └── MCP.tsx │ └── types │ │ ├── agent.ts │ │ ├── collection.ts │ │ ├── configurable.ts │ │ ├── deployment.ts │ │ └── tool.ts │ ├── tailwind.config.js │ ├── tsconfig.json │ └── turbo.json ├── package.json ├── tsconfig.json ├── turbo.json └── yarn.lock /.codespellignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/langchain-ai/open-agent-platform/2b1d92b9281240304f73a9a94d638c3469896649/.codespellignore -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # Run formatting on all PRs 2 | 3 | name: CI 4 | 5 | on: 6 | push: 7 | branches: ["main"] 8 | pull_request: 9 | workflow_dispatch: # Allows triggering the workflow manually in GitHub UI 10 | 11 | # If another push to the same PR or branch happens while this workflow is still running, 12 | # cancel the earlier run in favor of the next run. 13 | # 14 | # There's no point in testing an outdated version of the code. GitHub only allows 15 | # a limited number of job runners to be active at the same time, so it's better to cancel 16 | # pointless jobs early so that more useful jobs can run sooner. 17 | concurrency: 18 | group: ${{ github.workflow }}-${{ github.ref }} 19 | cancel-in-progress: true 20 | 21 | jobs: 22 | format: 23 | name: Check formatting 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: Enable Corepack 28 | run: corepack enable 29 | - name: Use Node.js 18.x 30 | uses: actions/setup-node@v3 31 | with: 32 | node-version: 18.x 33 | cache: "yarn" 34 | - name: Install dependencies 35 | run: yarn install --immutable --mode=skip-build 36 | - name: Check formatting 37 | run: yarn format:check 38 | 39 | lint: 40 | name: Check linting 41 | runs-on: ubuntu-latest 42 | steps: 43 | - uses: actions/checkout@v4 44 | - name: Enable Corepack 45 | run: corepack enable 46 | - name: Use Node.js 18.x 47 | uses: actions/setup-node@v3 48 | with: 49 | node-version: 18.x 50 | cache: "yarn" 51 | - name: Install dependencies 52 | run: yarn install --immutable --mode=skip-build 53 | - name: Check linting 54 | run: yarn run lint 55 | 56 | readme-spelling: 57 | name: Check README spelling 58 | runs-on: ubuntu-latest 59 | steps: 60 | - uses: actions/checkout@v4 61 | - uses: codespell-project/actions-codespell@v2 62 | with: 63 | ignore_words_file: .codespellignore 64 | path: README.md 65 | 66 | check-spelling: 67 | name: Check code spelling 68 | runs-on: ubuntu-latest 69 | steps: 70 | - uses: actions/checkout@v4 71 | - uses: codespell-project/actions-codespell@v2 72 | with: 73 | ignore_words_file: .codespellignore 74 | path: apps/src 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | **/node_modules 6 | /.pnp 7 | .pnp.js 8 | .yarn/install-state.gz 9 | .yarn/cache 10 | 11 | # testing 12 | /coverage 13 | 14 | # next.js 15 | /.next/ 16 | /out/ 17 | 18 | # production 19 | /build 20 | /dist 21 | **/dist 22 | .turbo/ 23 | 24 | # misc 25 | .DS_Store 26 | *.pem 27 | 28 | # debug 29 | npm-debug.log* 30 | yarn-debug.log* 31 | yarn-error.log* 32 | 33 | # local env files 34 | .env*.local 35 | .env 36 | 37 | # vercel 38 | .vercel 39 | 40 | # typescript 41 | *.tsbuildinfo 42 | next-env.d.ts 43 | 44 | credentials.json 45 | 46 | # LangGraph API 47 | .langgraph_api 48 | 49 | **/.claude/settings.local.json 50 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | npmRegistryServer: "https://registry.npmjs.org/" 2 | nodeLinker: node-modules 3 | -------------------------------------------------------------------------------- /CONCEPTS.md: -------------------------------------------------------------------------------- 1 | # Concepts 2 | 3 | This doc contains a conceptual overview of different concepts and features of the Open Agent Platform. 4 | 5 | ## Agent 6 | 7 | An Agent is a custom assistant that is tied to a specific graph in a LangGraph deployment. An agent has a user provided name, description, and configurable fields. 8 | 9 | The configurable fields tied to an Agent are what makes an Agent useful. This is a custom config object which contains fields that personalize the behavior of the agent (e.g. model, system prompt, tools, etc). 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) LangChain, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /apps/docs/README.md: -------------------------------------------------------------------------------- 1 | # Open Agent Platform Docs 2 | 3 | The OAP docs are built with Mintlify. To preview the docs locally, run the following command: 4 | 5 | ```bash 6 | npx mintlify dev 7 | ``` 8 | 9 | Or install mint globally: 10 | 11 | ```bash 12 | npm i -g mintlify 13 | mintlify dev 14 | ``` 15 | 16 | This will start a local development server at http://localhost:3000. You can now view and edit your docs in real-time. 17 | -------------------------------------------------------------------------------- /apps/docs/custom-agents/overview.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Custom Agents Overview' 3 | description: 'Building your own agents for the Open Agent Platform' 4 | --- 5 | 6 | # Building Your Own Agents 7 | 8 | We built Open Agent Platform with custom agents in mind. Although we offer a few pre-built agents, we encourage you to build your own agents, and use OAP as a platform to prototype, test and use them! This guide will help you build agents that are compatible with all of Open Agent Platform's features. 9 | 10 | ## Platform Requirements 11 | 12 | OAP is built on top of LangGraph Platform, which means all agents which you build to be used in OAP must be LangGraph agents deployed on LangGraph Platform. 13 | 14 | ## Agent Types 15 | 16 | When building custom agents, you can create three main types: 17 | 18 | 1. **Standard Agents**: These are single-purpose agents that handle specific tasks. 19 | 2. **Tools Agents**: Agents that can access external tools via the MCP protocol. 20 | 3. **Supervisor Agents**: Agents that can orchestrate and coordinate multiple other agents. 21 | 22 | ## Development Flow 23 | 24 | The typical development flow for creating custom agents involves: 25 | 26 | 1. Developing and testing your agent locally using LangGraph 27 | 2. Deploying your agent to LangGraph Platform 28 | 3. Configuring your Open Agent Platform to connect to your deployed agent 29 | 4. Testing and refining your agent through the OAP interface 30 | 31 | ## Getting Started 32 | 33 | To get started with building your own agents, we recommend: 34 | 35 | 1. Familiarizing yourself with the [LangGraph framework](https://github.com/langchain-ai/langgraph) 36 | 2. Studying the example agents we provide: 37 | - [Tools Agent](https://github.com/langchain-ai/oap-langgraph-tools-agent) 38 | - [Supervisor Agent](https://github.com/langchain-ai/oap-agent-supervisor) 39 | 3. Understanding how to make your agent configurable, as detailed in the [Configuration](/custom-agents/configuration) section 40 | 41 | Building custom agents allows you to create specialized AI assistants that can be easily managed and used through the Open Agent Platform interface. 42 | -------------------------------------------------------------------------------- /apps/docs/docs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://mintlify.com/docs.json", 3 | "theme": "mint", 4 | "name": "Open Agent Platform", 5 | "colors": { 6 | "primary": "#0ea5e9", 7 | "light": "#38bdf8", 8 | "dark": "#0369a1" 9 | }, 10 | "favicon": "/favicon.svg", 11 | "navigation": { 12 | "tabs": [ 13 | { 14 | "tab": "Guides", 15 | "groups": [ 16 | { 17 | "group": "Get Started", 18 | "pages": [ 19 | "index", 20 | "quickstart" 21 | ] 22 | }, 23 | { 24 | "group": "Setup", 25 | "pages": [ 26 | "setup/agents", 27 | "setup/authentication", 28 | "setup/rag-server", 29 | "setup/mcp-server" 30 | ] 31 | }, 32 | { 33 | "group": "Custom Agents", 34 | "pages": [ 35 | "custom-agents/overview", 36 | "custom-agents/configuration" 37 | ] 38 | } 39 | ] 40 | } 41 | ], 42 | "global": { 43 | "anchors": [ 44 | { 45 | "anchor": "Demo", 46 | "href": "https://oap.langchain.com", 47 | "icon": "link" 48 | }, 49 | { 50 | "anchor": "GitHub", 51 | "href": "https://github.com/langchain-ai/open-agent-platform", 52 | "icon": "github" 53 | } 54 | ] 55 | } 56 | }, 57 | "logo": { 58 | "light": "/logo/light.svg", 59 | "dark": "/logo/dark.svg" 60 | }, 61 | "navbar": { 62 | "links": [ 63 | { 64 | "label": "GitHub", 65 | "href": "https://github.com/langchain-ai/open-agent-platform" 66 | } 67 | ] 68 | }, 69 | "footer": { 70 | "socials": { 71 | "github": "https://github.com/langchain-ai/open-agent-platform", 72 | "twitter": "https://twitter.com/langchainai" 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /apps/docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Introduction' 3 | description: 'An introduction to Open Agent Platform' 4 | --- 5 | 6 | Open Agent Platform is a citizen developer platform, allowing non-technical users to build, prototype, and use agents. These agents can be connected to a wide range of tools, RAG servers, and even other agents through an Agent Supervisor! 7 | 8 | 9 | 14 | Get your Open Agent Platform running quickly 15 | 16 | 21 | Deploy and configure your agents 22 | 23 | 28 | Connect your agents to knowledge bases 29 | 30 | 35 | Extend your agents with powerful tools 36 | 37 | 38 | 39 | ## What is Open Agent Platform? 40 | 41 | Open Agent Platform provides a modern, web-based interface for creating, managing, and interacting with LangGraph agents. It's designed with simplicity in mind, making it accessible to users without technical expertise, while still offering advanced capabilities for developers. 42 | 43 | ## Key Features 44 | 45 | - **Agent Management**: Build, configure, and interact with agents through an intuitive interface 46 | - **RAG Integration**: First-class support for Retrieval Augmented Generation with [LangConnect](https://github.com/langchain-ai/langconnect) 47 | - **MCP Tools**: Connect your agents to external tools through MCP servers 48 | - **Agent Supervision**: Orchestrate multiple agents working together through an Agent Supervisor 49 | - **Authentication**: Built-in authentication and access control 50 | 51 | ## Getting Started 52 | 53 | Follow our [quickstart guide](/quickstart) to set up your own instance of Open Agent Platform. 54 | -------------------------------------------------------------------------------- /apps/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@open-agent-platform/docs", 3 | "author": "LangChain", 4 | "repository": "https://github.com/langchain-ai/open-agent-platform", 5 | "private": true, 6 | "scripts": { 7 | "dev": "mint dev" 8 | }, 9 | "devDependencies": { 10 | "mint": "^4.1.19" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/docs/setup/agents.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Agents Setup' 3 | description: 'Deploy and configure your agents for Open Agent Platform' 4 | --- 5 | 6 | The first step in setting up Open Agent Platform is to deploy and configure your agents. To help with this, we're releasing two pre-built agents, customized specifically for Open Agent Platform: 7 | 8 | - [Tools Agent](https://github.com/langchain-ai/oap-langgraph-tools-agent) 9 | - [Supervisor Agent](https://github.com/langchain-ai/oap-agent-supervisor) 10 | 11 | ## Deploying Agents 12 | 13 | To use these agents in your instance, you should: 14 | 15 | 1. Clone the repositories 16 | 2. Follow the instructions in the READMEs 17 | 3. Deploy the agents to LangGraph Platform, or run `langgraph dev` to run the agents locally. 18 | 19 | ## Configuration 20 | 21 | Once deployed or running locally, you can connect them to your instance of Open Agent Platform by setting the configuration environment variables. The configuration object is as follows: 22 | 23 | ```json 24 | { 25 | "id": "The project ID of the deployment. For locally running LangGraph servers, this can be any UUID Version 4.", 26 | "tenantId": "The tenant ID of your LangSmith account. For locally running LangGraph servers, this can be any UUID Version 4.", 27 | "deploymentUrl": "The API URL to your deployment.", 28 | "name": "A custom name for your deployment", 29 | "isDefault": "Whether this deployment is the default deployment. Should only be set to true for one deployment.", 30 | "defaultGraphId": "The graph ID of the default graph for the entire OAP instance. We recommend this is set to the graph ID of a graph which supports RAG & MCP tools. This must be set in the same deployment which isDefault is set to true on. Optional, but required in at least one deployment.", 31 | } 32 | ``` 33 | 34 | If you are running agents locally via `langgraph dev`, the `id` (project ID), and `tenantId` should be any valid UUID version 4, such as those generated by `uuid.uuid4()`. Ensure each graph has a unique `id`, and all graphs share the same `tenantId`. 35 | 36 | 37 | ## Finding Project & Tenant IDs 38 | 39 | To easily find your project & tenant IDs for agents deployed to LangGraph Platform, you can make a GET request to the `/info` endpoint of your deployment URL. Then, copy the `project_id` value into `id`, and `tenant_id` into `tenantId`. 40 | 41 | ## Setting Environment Variables 42 | 43 | After constructing the JSON objects with these values for each of the deployments you want to include in your Open Agent Platform instance, you should stringify them into a single, flat array, then set them under the `NEXT_PUBLIC_DEPLOYMENTS` environment variable inside the `apps/web/` directory. 44 | 45 | The following is an example of what this variable would look like for a single, local deployment: 46 | 47 | ```bash 48 | NEXT_PUBLIC_DEPLOYMENTS=[{"id":"bf63dc89-1de7-4a65-8336-af9ecda479d6","deploymentUrl":"http://localhost:2024","tenantId":"42d732b3-1324-4226-9fe9-513044dceb58","name":"Local deployment","isDefault":true,"defaultGraphId":"agent"}] 49 | ``` 50 | -------------------------------------------------------------------------------- /apps/docs/setup/authentication.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Authentication Setup' 3 | description: 'Configure authentication for Open Agent Platform' 4 | --- 5 | 6 | The default authentication provider Open Agent Platform is configured to use is Supabase. 7 | 8 | ## Setting Up Supabase 9 | 10 | To set up Supabase authentication, you must first create a new Supabase project. After creating a new project, set the following environment variables inside the `apps/web/` directory: 11 | 12 | ```bash 13 | NEXT_PUBLIC_SUPABASE_URL="" 14 | NEXT_PUBLIC_SUPABASE_ANON_KEY="" 15 | ``` 16 | 17 | You should also enable Google authentication in your Supabase project. If you do not want to allow signing up with Google, set `NEXT_PUBLIC_GOOGLE_AUTH_DISABLED=true` in your environment variables to disable showing Google as an authentication option in the UI. 18 | 19 | ## LangGraph Server Authentication 20 | 21 | Since the pre-built LangGraph agents implement custom authentication, there is no need to specify a LangSmith API key when making requests to them. Instead, we pass the user's Supabase access token (JWT token) in the `Authorization` header of the request. 22 | 23 | Inside the auth middleware of the LangGraph server, we extract this token and verify it's valid with Supabase. If it is, we receive back a user ID, which is used to verify each user is *only* able to access their own agents and threads. If you want to allow users access to agents they did not create, you should update the custom authentication middleware in the LangGraph server to allow access to the agents you want users to be able to access. 24 | 25 | Along with the `Authorization` header, we duplicate passing the Supabase JWT via the `x-supabase-access-token` header. This is because all non-LangSmith specific headers which are sent to LangGraph servers which are prefixed with `x-` are included in the configurable fields of the thread. We will need this JWT to later authenticate with the MCP server. 26 | 27 | ## LangSmith API Key Authentication 28 | 29 | If you do *not* want to use custom authentication in your LangGraph server, and instead allow anyone to access your agents, you can do so by setting the `NEXT_PUBLIC_USE_LANGSMITH_AUTH` environment variable to `true`, and setting your `LANGSMITH_API_KEY` in the environment variables inside the `apps/web/` directory. 30 | 31 | Lastly, ensure you have the `NEXT_PUBLIC_BASE_API_URL` environment variable set to the base API URL of your **web** server. For local development, this should be set to: 32 | 33 | ```bash 34 | NEXT_PUBLIC_BASE_API_URL="http://localhost:3000/api" 35 | ``` 36 | 37 | This will cause all requests made to your web client to first pass through a proxy route, which injects the LangSmith API key into the request from the server, as to not expose the API key to the client. The request is then forwarded on to your LangGraph server. 38 | 39 | 40 | Remember *not* to prefix your LangSmith API key environment variable with `NEXT_PUBLIC_`, as this is a **secret** and should never be exposed to the client. 41 | 42 | 43 | ## RAG Authentication 44 | 45 | Authenticating to your LangConnect RAG server from the web client is handled in a similar way to LangGraph authentication. We pass the Supabase JWT in the `Authorization` header of the request. Then, inside the LangConnect RAG server, we extract this token and verify it's valid with Supabase. 46 | 47 | If it is, we receive back a user ID, which is used to verify each user is *only* able to access their own collections. We do not currently support sharing collections between users. 48 | -------------------------------------------------------------------------------- /apps/docs/setup/rag-server.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'RAG Server Setup' 3 | --- 4 | 5 | Open Agent Platform has first class support for RAG with your agents. To use this feature, you must deploy your own instance of a LangConnect RAG server. 6 | 7 | ## About LangConnect 8 | 9 | [LangConnect](https://github.com/langchain-ai/langconnect) is an open source managed retrieval service for RAG applications. It's built on top of LangChain's RAG integrations (vectorstores, document loaders, indexing API, etc.) and allows you to quickly spin up an API server for managing your collections & documents for any RAG application. 10 | 11 | ## Deployment 12 | 13 | To set up LangConnect, follow the instructions in the [LangConnect README](https://github.com/langchain-ai/langconnect/blob/main/README.md). After setting it up, and either running the server locally via Docker, or deploying it to a cloud provider, you should set the `NEXT_PUBLIC_RAG_API_URL` environment variable inside the `apps/web/` directory, to the API URL of your LangConnect server. 14 | 15 | For local development, this should be set to: 16 | 17 | ```bash 18 | NEXT_PUBLIC_RAG_API_URL="http://localhost:8080" 19 | ``` 20 | 21 | ## Using the RAG Feature 22 | 23 | Once this is set, you can visit the `/rag` page in the web app to create your first collection, and upload documents to it. 24 | 25 | After setting up your RAG server, and configuring Open Agent Platform with an agent which can call it (like the Tools Agent), you can start to use it in your agents by selecting a collection when creating/editing an agent. This will give the agent access to a tool which can make requests to your RAG server, and retrieve relevant documents for the user's query. 26 | 27 | ## Best Practices 28 | 29 | Since the RAG server is exposed to the agent as a tool, we recommend setting detailed descriptions on your collections when creating them, since these are the descriptions which will be attached to the tool. 30 | 31 | ## Authentication 32 | 33 | As mentioned in the Authentication section, we pass the Supabase JWT in the `Authorization` header of the request. Then, inside the LangConnect RAG server, we extract this token and verify it's valid with Supabase. 34 | 35 | If it is, we receive back a user ID, which is used to verify each user is *only* able to access their own collections. We do not currently support sharing collections between users. 36 | -------------------------------------------------------------------------------- /apps/web/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | .git 4 | .env -------------------------------------------------------------------------------- /apps/web/.env.example: -------------------------------------------------------------------------------- 1 | # The base API URL for the platform. 2 | # Defaults to `http://localhost:3000/api` for development 3 | NEXT_PUBLIC_BASE_API_URL="http://localhost:3000/api" 4 | 5 | # LangSmith API key required for some admin tasks. 6 | LANGSMITH_API_KEY="lsv2_..." 7 | # Whether or not to always use LangSmith auth (API key). If true, you will 8 | # not get user scoped auth by default 9 | NEXT_PUBLIC_USE_LANGSMITH_AUTH="false" 10 | 11 | # The deployments to make available in the UI 12 | NEXT_PUBLIC_DEPLOYMENTS="[]" 13 | 14 | # The RAG API URL for the platform. 15 | NEXT_PUBLIC_RAG_API_URL="http://localhost:8080" 16 | 17 | # The base URL to the MCP server. Do not include the `/mcp` at the end. 18 | NEXT_PUBLIC_MCP_SERVER_URL="" 19 | # Whether or not the MCP server requires authentication. 20 | # If true, all requests to the MCP server will go through a proxy 21 | # route first. 22 | NEXT_PUBLIC_MCP_AUTH_REQUIRED="true" 23 | 24 | # Supabase Authentication 25 | NEXT_PUBLIC_SUPABASE_ANON_KEY="" 26 | NEXT_PUBLIC_SUPABASE_URL="" 27 | 28 | # Disable showing Google Auth in the UI 29 | # Defaults to false. 30 | NEXT_PUBLIC_GOOGLE_AUTH_DISABLED="false" -------------------------------------------------------------------------------- /apps/web/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | # LangGraph API 27 | .langgraph_api 28 | .env 29 | .next/ 30 | next-env.d.ts -------------------------------------------------------------------------------- /apps/web/README.md: -------------------------------------------------------------------------------- 1 | # Open Agent Platform Web App 2 | 3 | This is the web app for the Open Agent Platform. 4 | -------------------------------------------------------------------------------- /apps/web/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } 22 | -------------------------------------------------------------------------------- /apps/web/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from "@eslint/js"; 2 | import globals from "globals"; 3 | import reactHooks from "eslint-plugin-react-hooks"; 4 | import reactRefresh from "eslint-plugin-react-refresh"; 5 | import tseslint from "typescript-eslint"; 6 | 7 | export default tseslint.config( 8 | { ignores: ["dist"] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ["**/*.{ts,tsx}"], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | "react-hooks": reactHooks, 18 | "react-refresh": reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | "@typescript-eslint/no-explicit-any": 0, 23 | "@typescript-eslint/no-unused-vars": [ 24 | "error", 25 | { 26 | args: "none", 27 | argsIgnorePattern: "^_", 28 | varsIgnorePattern: "^_", 29 | caughtErrorsIgnorePattern: "^_", 30 | }, 31 | ], 32 | "react-refresh/only-export-components": [ 33 | "warn", 34 | { allowConstantExport: true }, 35 | ], 36 | "no-console": ["error", { allow: ["warn", "error"] }], 37 | }, 38 | }, 39 | ); 40 | -------------------------------------------------------------------------------- /apps/web/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /apps/web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@open-agent-platform/web", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "next dev", 8 | "build": "turbo build:internal --filter=@open-agent-platform/web", 9 | "build:internal": "next build", 10 | "start": "next start", 11 | "lint": "next lint", 12 | "lint:fix": "next lint --fix", 13 | "format": "prettier --write .", 14 | "format:check": "prettier --check ." 15 | }, 16 | "dependencies": { 17 | "@langchain/core": "^0.3.44", 18 | "@langchain/langgraph-sdk": "^0.0.76", 19 | "@modelcontextprotocol/sdk": "^1.11.4", 20 | "@radix-ui/react-alert-dialog": "^1.1.11", 21 | "@radix-ui/react-avatar": "^1.1.4", 22 | "@radix-ui/react-checkbox": "1.1.2", 23 | "@radix-ui/react-collapsible": "^1.1.4", 24 | "@radix-ui/react-dialog": "^1.1.7", 25 | "@radix-ui/react-dropdown-menu": "^2.1.7", 26 | "@radix-ui/react-hover-card": "1.1.2", 27 | "@radix-ui/react-icons": "^1.3.2", 28 | "@radix-ui/react-label": "^2.1.3", 29 | "@radix-ui/react-popover": "^1.1.7", 30 | "@radix-ui/react-progress": "1.1.0", 31 | "@radix-ui/react-scroll-area": "^1.2.5", 32 | "@radix-ui/react-select": "^2.2.2", 33 | "@radix-ui/react-separator": "^1.1.3", 34 | "@radix-ui/react-slider": "^1.3.2", 35 | "@radix-ui/react-slot": "^1.2.0", 36 | "@radix-ui/react-switch": "^1.2.2", 37 | "@radix-ui/react-tabs": "^1.1.7", 38 | "@radix-ui/react-toast": "1.1.0", 39 | "@radix-ui/react-tooltip": "^1.2.3", 40 | "@supabase/ssr": "^0.6.1", 41 | "@supabase/supabase-js": "^2.49.4", 42 | "class-variance-authority": "^0.7.1", 43 | "clsx": "^2.1.1", 44 | "cmdk": "^1.1.1", 45 | "date-fns": "4.1.0", 46 | "framer-motion": "^12.7.3", 47 | "katex": "latest", 48 | "langgraph-nextjs-api-passthrough": "^0.1.0", 49 | "lodash": "^4.17.21", 50 | "lucide-react": "^0.488.0", 51 | "next-themes": "^0.4.6", 52 | "nuqs": "^2.4.1", 53 | "react": "^19.0.0", 54 | "react-dom": "^19.0.0", 55 | "react-markdown": "^10.1.0", 56 | "react-resizable-panels": "^3.0.2", 57 | "react-syntax-highlighter": "^15.6.1", 58 | "rehype-katex": "^7.0.1", 59 | "rehype-raw": "7.0.0", 60 | "remark-gfm": "^4.0.1", 61 | "remark-math": "^6.0.0", 62 | "sonner": "^2.0.3", 63 | "tailwind-merge": "^3.0.2", 64 | "tailwindcss-animate": "^1.0.7", 65 | "use-stick-to-bottom": "^1.1.0", 66 | "uuid": "^11.1.0", 67 | "zod": "3.23.8", 68 | "zustand": "^5.0.3" 69 | }, 70 | "devDependencies": { 71 | "@eslint/js": "^9.19.0", 72 | "@tailwindcss/postcss": "^4.0.13", 73 | "@types/lodash": "^4.17.16", 74 | "@types/node": "22.15.2", 75 | "@types/react": "^19.0.8", 76 | "@types/react-dom": "^19.1.2", 77 | "@types/react-syntax-highlighter": "^15.5.13", 78 | "@types/uuid": "10.0.0", 79 | "autoprefixer": "^10.4.20", 80 | "dotenv": "^16.5.0", 81 | "eslint": "^9.19.0", 82 | "eslint-config-next": "15.2.2", 83 | "eslint-plugin-react-hooks": "^5.0.0", 84 | "eslint-plugin-react-refresh": "^0.4.18", 85 | "globals": "^15.14.0", 86 | "next": "^15.3.1", 87 | "postcss": "^8.5.3", 88 | "prettier": "^3.5.2", 89 | "prettier-plugin-tailwindcss": "^0.6.11", 90 | "tailwind-scrollbar": "3.1.0", 91 | "tailwindcss": "^4.0.13", 92 | "turbo": "^2.5.0", 93 | "typescript": "~5.7.2", 94 | "typescript-eslint": "^8.22.0" 95 | }, 96 | "overrides": { 97 | "react-is": "^19.0.0-rc-69d4b800-20241021" 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /apps/web/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | "@tailwindcss/postcss": {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /apps/web/prettier.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://prettier.io/docs/configuration 3 | * @type {import("prettier").Config} 4 | */ 5 | const config = { 6 | endOfLine: "auto", 7 | singleAttributePerLine: true, 8 | plugins: ["prettier-plugin-tailwindcss"], 9 | }; 10 | 11 | export default config; 12 | -------------------------------------------------------------------------------- /apps/web/scripts/update-agents-mcp-auth-status.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import { getDeployments } from "@/lib/environment/deployments"; 3 | import { Assistant, Client } from "@langchain/langgraph-sdk"; 4 | import { 5 | extractConfigurationsFromAgent, 6 | getConfigurableDefaults, 7 | } from "@/lib/ui-config"; 8 | 9 | async function main() { 10 | const deployments = getDeployments(); 11 | 12 | const authRequired = process.env.NEXT_PUBLIC_MCP_AUTH_REQUIRED === "true"; 13 | const mcpServerUrl = process.env.NEXT_PUBLIC_MCP_SERVER_URL; 14 | if (!mcpServerUrl) { 15 | throw new Error("MCP URL env variable is not set"); 16 | } 17 | 18 | const newMCPUrl = new URL(mcpServerUrl); 19 | newMCPUrl.pathname = `${newMCPUrl.pathname}${newMCPUrl.pathname.endsWith("/") ? "" : "/"}mcp`; 20 | 21 | for await (const deployment of deployments) { 22 | const client = new Client({ 23 | apiUrl: deployment.deploymentUrl, 24 | apiKey: process.env.LANGSMITH_API_KEY, 25 | defaultHeaders: { 26 | "x-auth-scheme": "langsmith", 27 | }, 28 | }); 29 | 30 | // Collect all agents using pagination 31 | const allAgents: Assistant[] = []; 32 | const pageSize = 100; 33 | let hasMore = true; 34 | let offset = 0; 35 | 36 | // Continue fetching until there are no more pages 37 | while (hasMore) { 38 | const agents = await client.assistants.search({ 39 | limit: pageSize, 40 | offset, 41 | }); 42 | 43 | // Add the current page of agents to our collection 44 | if (agents.length === 0) { 45 | hasMore = false; 46 | } else { 47 | allAgents.push(...agents); 48 | offset += pageSize; 49 | } 50 | } 51 | 52 | const agentsUpdatePromise = allAgents.map(async (agent) => { 53 | // First get the agent schema. We need this to verify this agent has support 54 | // for MCP servers 55 | const agentSchema = await client.assistants.getSchemas( 56 | agent.assistant_id, 57 | ); 58 | // Extract the configs 59 | const agentConfigs = extractConfigurationsFromAgent({ 60 | agent, 61 | schema: agentSchema.config_schema, 62 | }); 63 | if (!agentConfigs.toolConfig || !agentConfigs.toolConfig[0]) { 64 | // Agent does not support MCP servers, skip 65 | return; 66 | } 67 | const mcpConfigAuthStatus = 68 | agentConfigs.toolConfig[0].default?.auth_required; 69 | if (mcpConfigAuthStatus === authRequired) { 70 | // Agent already has latest MCP URL, skip 71 | return; 72 | } 73 | const existingConfig = getConfigurableDefaults( 74 | agentConfigs.configFields, 75 | agentConfigs.toolConfig, 76 | agentConfigs.ragConfig, 77 | agentConfigs.agentsConfig, 78 | ); 79 | 80 | await client.assistants.update(agent.assistant_id, { 81 | config: { 82 | configurable: { 83 | ...existingConfig, 84 | // Ensure we only update the MCP config field. 85 | [agentConfigs.toolConfig[0].label]: { 86 | ...agentConfigs.toolConfig[0].default, 87 | auth_required: authRequired, 88 | }, 89 | }, 90 | }, 91 | }); 92 | }); 93 | await Promise.all(agentsUpdatePromise); 94 | } 95 | } 96 | 97 | main().catch(console.error); 98 | -------------------------------------------------------------------------------- /apps/web/scripts/update-agents-mcp-url.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import { getDeployments } from "@/lib/environment/deployments"; 3 | import { Assistant, Client } from "@langchain/langgraph-sdk"; 4 | import { 5 | extractConfigurationsFromAgent, 6 | getConfigurableDefaults, 7 | } from "@/lib/ui-config"; 8 | 9 | async function main() { 10 | const deployments = getDeployments(); 11 | 12 | const newMCPUrlStr = process.env.NEXT_PUBLIC_MCP_SERVER_URL; 13 | if (!newMCPUrlStr) { 14 | throw new Error("MCP URL env variable is not set"); 15 | } 16 | 17 | const newMCPUrl = new URL(newMCPUrlStr); 18 | newMCPUrl.pathname = `${newMCPUrl.pathname}/mcp`; 19 | 20 | for await (const deployment of deployments) { 21 | const client = new Client({ 22 | apiUrl: deployment.deploymentUrl, 23 | apiKey: process.env.LANGSMITH_API_KEY, 24 | defaultHeaders: { 25 | "x-auth-scheme": "langsmith", 26 | }, 27 | }); 28 | 29 | // Collect all agents using pagination 30 | const allAgents: Assistant[] = []; 31 | const pageSize = 100; 32 | let hasMore = true; 33 | let offset = 0; 34 | 35 | // Continue fetching until there are no more pages 36 | while (hasMore) { 37 | const agents = await client.assistants.search({ 38 | limit: pageSize, 39 | offset, 40 | }); 41 | 42 | // Add the current page of agents to our collection 43 | if (agents.length === 0) { 44 | hasMore = false; 45 | } else { 46 | allAgents.push(...agents); 47 | offset += pageSize; 48 | } 49 | } 50 | 51 | const agentsUpdatePromise = allAgents.map(async (agent) => { 52 | // First get the agent schema. We need this to verify this agent has support 53 | // for MCP servers 54 | const agentSchema = await client.assistants.getSchemas( 55 | agent.assistant_id, 56 | ); 57 | // Extract the configs 58 | const agentConfigs = extractConfigurationsFromAgent({ 59 | agent, 60 | schema: agentSchema.config_schema, 61 | }); 62 | if (!agentConfigs.toolConfig || !agentConfigs.toolConfig[0]) { 63 | // Agent does not support MCP servers, skip 64 | return; 65 | } 66 | const mcpConfigDefaultUrl = agentConfigs.toolConfig[0].default?.url; 67 | if (newMCPUrl.href === mcpConfigDefaultUrl) { 68 | // Agent already has latest MCP URL, skip 69 | return; 70 | } 71 | const existingConfig = getConfigurableDefaults( 72 | agentConfigs.configFields, 73 | agentConfigs.toolConfig, 74 | agentConfigs.ragConfig, 75 | agentConfigs.agentsConfig, 76 | ); 77 | 78 | await client.assistants.update(agent.assistant_id, { 79 | config: { 80 | configurable: { 81 | ...existingConfig, 82 | // Ensure we only update the MCP config field. 83 | [agentConfigs.toolConfig[0].label]: { 84 | ...agentConfigs.toolConfig[0].default, 85 | url: newMCPUrl.href, 86 | }, 87 | }, 88 | }, 89 | }); 90 | }); 91 | await Promise.all(agentsUpdatePromise); 92 | } 93 | } 94 | 95 | main().catch(console.error); 96 | -------------------------------------------------------------------------------- /apps/web/src/app/(app)/agents/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import AgentsInterface from "@/features/agents"; 4 | import { 5 | Breadcrumb, 6 | BreadcrumbItem, 7 | BreadcrumbList, 8 | BreadcrumbPage, 9 | } from "@/components/ui/breadcrumb"; 10 | import { SidebarTrigger } from "@/components/ui/sidebar"; 11 | import { Toaster } from "@/components/ui/sonner"; 12 | import React from "react"; 13 | 14 | /** 15 | * The /agents page. 16 | * Contains the list of all agents the user has access to. 17 | */ 18 | export default function AgentsPage(): React.ReactNode { 19 | return ( 20 | Loading (layout)...}> 21 | 22 |
23 |
24 | 25 | 26 | 27 | 28 | Agents 29 | 30 | 31 | 32 |
33 |
34 | 35 |
36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /apps/web/src/app/(app)/inbox/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { AgentInbox } from "@/components/agent-inbox"; 4 | import React from "react"; 5 | import { ThreadsProvider } from "@/components/agent-inbox/contexts/ThreadContext"; 6 | import { SidebarTrigger } from "@/components/ui/sidebar"; 7 | import { Toaster } from "@/components/ui/sonner"; 8 | import { InboxSidebar, InboxSidebarTrigger } from "@/components/inbox-sidebar"; 9 | import { SidebarProvider } from "@/components/ui/sidebar"; 10 | import { 11 | Breadcrumb, 12 | BreadcrumbItem, 13 | BreadcrumbList, 14 | BreadcrumbPage, 15 | } from "@/components/ui/breadcrumb"; 16 | 17 | export default function InboxPage(): React.ReactNode { 18 | return ( 19 | Loading...}> 20 | 21 | 22 |
23 | {/* Header */} 24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | Inbox 33 | 34 | 35 | 36 |
37 |
38 | 39 | {/* Main content */} 40 |
41 | 42 |
43 |
44 | 45 | {/* Right sidebar for inbox */} 46 |
47 | 48 | 49 | 50 | 51 |
52 |
53 |
54 |
55 | ); 56 | } 57 | -------------------------------------------------------------------------------- /apps/web/src/app/(app)/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import "../globals.css"; 3 | import { Inter } from "next/font/google"; 4 | import React from "react"; 5 | import { NuqsAdapter } from "nuqs/adapters/next/app"; 6 | import { SidebarLayout } from "@/components/sidebar"; 7 | import { AuthProvider } from "@/providers/Auth"; 8 | import { DOCS_LINK } from "@/constants"; 9 | 10 | const inter = Inter({ 11 | subsets: ["latin"], 12 | preload: true, 13 | display: "swap", 14 | }); 15 | 16 | export const metadata: Metadata = { 17 | title: "Open Agent Platform", 18 | description: "Open Agent Platform by LangChain", 19 | }; 20 | 21 | export default function RootLayout({ 22 | children, 23 | }: Readonly<{ 24 | children: React.ReactNode; 25 | }>) { 26 | const isDemoApp = process.env.NEXT_PUBLIC_DEMO_APP === "true"; 27 | return ( 28 | 29 | 30 | {process.env.NODE_ENV !== "production" && ( 31 |