Procházet zdrojové kódy

Expose LiteLLM model names in backend (#370)

Jim Su před 1 rokem
rodič
revize
1be355436d

+ 2 - 1
frontend/.env

@@ -1 +1,2 @@
-VITE_TERMINAL_WS_URL="ws://localhost:3000/ws"
+VITE_URL="http://localhost:3000"
+VITE_WS_URL="ws://localhost:3000/ws"

+ 1 - 1
frontend/README.md

@@ -30,6 +30,6 @@ To learn React, check out the [React documentation](https://reactjs.org/).
 
 The OpenDevin terminal is powered by [Xterm.js](https://github.com/xtermjs/xterm.js).
 
-The terminal listens for events over a WebSocket connection. The WebSocket URL is specified by the environment variable `VITE_TERMINAL_WS_URL` (prepending `VITE_` to environment variable names is necessary to expose them).
+The terminal listens for events over a WebSocket connection. The WebSocket URL is specified by the environment variable `VITE_WS_URL` (prepending `VITE_` to environment variable names is necessary to expose them).
 
 A simple websocket server can be found in the `/server` directory.

+ 12 - 4
frontend/src/components/BannerSettings.tsx

@@ -1,13 +1,21 @@
-import React, { ChangeEvent } from "react";
+import React, { ChangeEvent, useEffect, useState } from "react";
 import {
   AGENTS,
-  MODELS,
+  INITIAL_MODELS,
   changeAgent,
   changeModel,
+  fetchModels,
 } from "../services/settingsService";
 import "./BannerSettings.css";
 
 function ModelSelect(): JSX.Element {
+  const [models, setModels] = useState<string[]>(INITIAL_MODELS);
+  useEffect(() => {
+    fetchModels().then((fetchedModels) => {
+      setModels(fetchedModels);
+    });
+  }, []);
+
   return (
     <select
       onChange={(e: ChangeEvent<HTMLSelectElement>) =>
@@ -15,8 +23,8 @@ function ModelSelect(): JSX.Element {
       }
       className="select max-w-xs bg-base-300 xl:w-full w-1/3"
     >
-      {MODELS.map((model) => (
-        <option>{model}</option>
+      {models.map((model) => (
+        <option key={model}>{model}</option>
       ))}
     </select>
   );

+ 8 - 2
frontend/src/services/settingsService.ts

@@ -3,7 +3,13 @@ import { appendAssistantMessage } from "../state/chatSlice";
 import { setInitialized } from "../state/taskSlice";
 import store from "../store";
 
-export const MODELS = [
+const { VITE_URL } = import.meta.env;
+export async function fetchModels() {
+  const response = await fetch(`${VITE_URL}/litellm-models`);
+  return response.json();
+}
+
+export const INITIAL_MODELS = [
   "gpt-3.5-turbo-1106",
   "gpt-4-0125-preview",
   "claude-3-haiku-20240307",
@@ -11,7 +17,7 @@ export const MODELS = [
   "claude-3-sonnet-20240229",
 ];
 
-export type Model = (typeof MODELS)[number];
+export type Model = (typeof INITIAL_MODELS)[number];
 
 export const AGENTS = ["LangchainsAgent", "CodeActAgent"];
 

+ 2 - 2
frontend/src/socket/socket.ts

@@ -6,10 +6,10 @@ import { handleObservationMessage } from "./observations";
 
 type SocketMessage = ActionMessage | ObservationMessage;
 
-const WS_URL = import.meta.env.VITE_TERMINAL_WS_URL;
+const WS_URL = import.meta.env.VITE_WS_URL;
 if (!WS_URL) {
   throw new Error(
-    "The environment variable VITE_TERMINAL_WS_URL is not set. Please set it to the WebSocket URL of the terminal server.",
+    "The environment variable VITE_WS_URL is not set. Please set it to the WebSocket URL of the terminal server.",
   );
 }
 

+ 16 - 0
opendevin/server/listen.py

@@ -1,9 +1,19 @@
 from opendevin.server.session import Session
 from fastapi import FastAPI, WebSocket
+from fastapi.middleware.cors import CORSMiddleware
 import agenthub # noqa F401 (we import this to get the agents registered)
+import litellm
 
 app = FastAPI()
 
+app.add_middleware(
+    CORSMiddleware,
+    allow_origins=["http://localhost:3001"],
+    allow_credentials=True,
+    allow_methods=["*"],
+    allow_headers=["*"],
+)
+
 # This endpoint receives events from the client (i.e. the browser)
 @app.websocket("/ws")
 async def websocket_endpoint(websocket: WebSocket):
@@ -12,3 +22,9 @@ async def websocket_endpoint(websocket: WebSocket):
     # TODO: should this use asyncio instead of await?
     await session.start_listening()
 
+@app.get("/litellm-models")
+async def get_litellm_models():
+    """
+    Get all models supported by LiteLLM.
+    """
+    return litellm.model_list