From fe2c7d8d98737060909ac815caf5baa1772d2ac1 Mon Sep 17 00:00:00 2001 From: Arunabh Sharma Date: Sat, 29 Mar 2025 13:34:44 -0700 Subject: [PATCH] feat(ollama): Adding ollama for enabling local model agents (#153) * feat(ollama): add ollama package dependency, add two separate deployment docker compose files and add a shell script to toggle between the deployment docker compose files add base ollama.ts implementation add latest attempt to fetch Ollama models dynamically fix ollama dynamic model fetching, models now being rendered on GUI fix package and package-lock.json to remove ollama dependency and add types.ts for ollama switch MODEL_PROVIDERS to getModelProviders make dynamic ollama model dropdown change using zustland store make dynamic ollama model changes to router and evaluator ts too * feat(ollama): fix evaluated options by de-duplicating it * feat(ollama): make README.md change to reflect local model workflow * feat(ollama): add base non-ollama docker compose file, add --local flag to start_simstudio_docker.sh with ollama service * feat(ollama): fix README.md local model instructions * feat(ollama): remove de-duplication logic and separate getModelProviders into two * fix non-local init and translate.ts * create combined docker-compose file and fix start_simstudio_docker script too * update package-lock.json * feat(ollama): fix README.md instructions and docker compose --------- Co-authored-by: Arunabh Sharma --- .gitignore | 5 +- README.md | 38 ++- docker-compose.yml | 51 ++- .../sub-block/components/dropdown.tsx | 19 +- sim/blocks/blocks/agent.ts | 11 +- sim/blocks/blocks/evaluator.ts | 11 +- sim/blocks/blocks/router.ts | 11 +- sim/blocks/blocks/translate.ts | 6 +- sim/blocks/types.ts | 2 +- sim/package-lock.json | 160 +++++----- sim/package.json | 2 +- sim/providers/index.ts | 1 - sim/providers/ollama/index.ts | 299 ++++++++++++++++++ sim/providers/ollama/types.ts | 12 + sim/providers/types.ts | 2 + sim/providers/utils.ts | 69 +++- sim/scripts/ollama_docker.sh | 25 ++ sim/scripts/start_simstudio_docker.sh | 25 -- sim/stores/ollama/store.ts | 20 ++ start_simstudio_docker.sh | 70 ++++ 20 files changed, 691 insertions(+), 148 deletions(-) create mode 100644 sim/providers/ollama/index.ts create mode 100644 sim/providers/ollama/types.ts create mode 100755 sim/scripts/ollama_docker.sh delete mode 100644 sim/scripts/start_simstudio_docker.sh create mode 100644 sim/stores/ollama/store.ts create mode 100755 start_simstudio_docker.sh diff --git a/.gitignore b/.gitignore index 4be9817837..e2d4bcf588 100644 --- a/.gitignore +++ b/.gitignore @@ -62,4 +62,7 @@ next-env.d.ts # docs docs/.source docs/.contentlayer -docs/.content-collections \ No newline at end of file +docs/.content-collections + +# database instantiation +**/postgres_data/ \ No newline at end of file diff --git a/README.md b/README.md index bc55f10d57..13d48de593 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,12 @@ cd sim # Create environment file and update with required environment variables (BETTER_AUTH_SECRET) cp sim/.env.example sim/.env -# Start the Docker environment -docker compose up -d +# Start Sim Studio using the provided script +docker compose up -d --build + +or + +./start_simstudio_docker.sh ``` After running these commands: @@ -66,6 +70,36 @@ After running these commands: docker compose up -d --build ``` +#### Working with Local Models + +To use local models with Sim Studio, follow these steps: + +1. **Pull Local Models** + + ```bash + # Run the ollama_docker.sh script to pull the required models + ./sim/scripts/ollama_docker.sh pull + ``` + +2. **Start Sim Studio with Local Models** + + ```bash + #Start Sim Studio with local model support + ./start_simstudio_docker.sh --local + + # or + + # Start Sim Studio with local model support if you have nvidia GPU + docker compose up --profile local-gpu -d --build + + # or + + # Start Sim Studio with local model support if you don't have nvidia GPU + docker compose up --profile local-cpu -d --build + ``` + +The application will now be configured to use your local models. You can access it at [http://localhost:3000/w/](http://localhost:3000/w/). + ### Option 2: Dev Containers 1. Open VS Code or your favorite VS Code fork (Cursor, Windsurf, etc.) diff --git a/docker-compose.yml b/docker-compose.yml index 9561f2b08c..6cd2d2a829 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,5 +46,54 @@ services: timeout: 5s retries: 5 + local-llm-gpu: + profiles: + - local-gpu # This profile requires both 'local' and 'gpu' + image: ollama/ollama:latest + pull_policy: always + volumes: + - ${HOME}/.ollama:/root/.ollama + ports: + - "11434:11434" + environment: + - NVIDIA_DRIVER_CAPABILITIES=all + - OLLAMA_LOAD_TIMEOUT=-1 + - OLLAMA_KEEP_ALIVE=-1 + - OLLAMA_DEBUG=1 + command: "serve" + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:11434/"] + interval: 10s + timeout: 5s + retries: 5 + + local-llm-cpu: + profiles: + - local-cpu # This profile requires both 'local' and 'cpu' + image: ollama/ollama:latest + pull_policy: always + volumes: + - ${HOME}/.ollama:/root/.ollama + ports: + - "11434:11434" + environment: + - OLLAMA_LOAD_TIMEOUT=-1 + - OLLAMA_KEEP_ALIVE=-1 + - OLLAMA_DEBUG=1 + command: "serve" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:11434/"] + interval: 10s + timeout: 5s + retries: 5 + volumes: - postgres_data: \ No newline at end of file + postgres_data: + diff --git a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/dropdown.tsx b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/dropdown.tsx index ebd8deec20..e299be63d9 100644 --- a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/dropdown.tsx +++ b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/dropdown.tsx @@ -1,4 +1,4 @@ -import { useEffect } from 'react' +import { useEffect, useMemo } from 'react' import { Select, SelectContent, @@ -9,7 +9,7 @@ import { import { useSubBlockValue } from '../hooks/use-sub-block-value' interface DropdownProps { - options: Array + options: Array | (() => Array) defaultValue?: string blockId: string subBlockId: string @@ -18,14 +18,19 @@ interface DropdownProps { export function Dropdown({ options, defaultValue, blockId, subBlockId }: DropdownProps) { const [value, setValue] = useSubBlockValue(blockId, subBlockId, true) + // Evaluate options if it's a function + const evaluatedOptions = useMemo(() => { + return typeof options === 'function' ? options() : options + }, [options]) + // Set the value to the first option if it's not set useEffect(() => { - if (!value && options.length > 0) { - const firstOption = options[0] + if (!value && evaluatedOptions.length > 0) { + const firstOption = evaluatedOptions[0] const firstValue = typeof firstOption === 'string' ? firstOption : firstOption.id setValue(firstValue) } - }, [value, options, defaultValue, setValue]) + }, [value, evaluatedOptions, defaultValue, setValue]) const getOptionValue = (option: string | { label: string; id: string }) => { return typeof option === 'string' ? option : option.id @@ -38,14 +43,14 @@ export function Dropdown({ options, defaultValue, blockId, subBlockId }: Dropdow return (