### Clojure: Environment-based LLM Setup with Dscloj Source: https://github.com/unravel-team/dscloj/blob/main/MIGRATION.md Demonstrates dscloj's approach to environment-based setup, offering a quick setup function for development that reads API keys from the environment, and advocating for explicit provider registration in production for better control. ```clojure ;; Quick setup for development (dscloj/quick-setup!) ; Reads all API keys from environment ;; Production: explicit registration (dscloj/register-provider! :production-gpt4 {...}) ``` -------------------------------- ### DSCloj Quick Setup for Providers (Clojure) Source: https://github.com/unravel-team/dscloj/blob/main/MIGRATION.md Demonstrates using `dscloj/quick-setup!` to automatically register common providers based on environment variables. Useful for quick prototyping. ```clojure ;; One-time setup - reads from environment variables (dscloj/quick-setup!) ;; Automatically registers :openai, :anthropic, :gemini, etc. (dscloj/predict :gpt4 qa-module input :openai) ``` -------------------------------- ### Registering Multiple Providers with DSCloj (Clojure) Source: https://github.com/unravel-team/dscloj/blob/main/MIGRATION.md Example of registering multiple providers like OpenAI and Anthropic using `dscloj/register-provider!`. This is recommended for production environments. ```clojure ;; One-time setup (e.g., in your app initialization) (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) (dscloj/register-provider! :claude {:provider :anthropic :model "claude-3-5-sonnet-20241022" :config {:api-key (System/getenv "ANTHROPIC_API_KEY")}}) ;; Use throughout your app (dscloj/predict :gpt4 qa-module input :gpt4) (dscloj/predict :gpt4 qa-module input :claude) ``` -------------------------------- ### Clojure: Runtime Provider Switching Example Source: https://github.com/unravel-team/dscloj/blob/main/MIGRATION.md Illustrates how to register multiple LLM providers and then switch between them at runtime by simply changing the keyword argument to the predict function. This enhances flexibility in applications that utilize various LLMs. ```clojure ;; Register multiple providers (dscloj/register-provider! :gpt4 {...}) (dscloj/register-provider! :claude {...}) (dscloj/register-provider! :gemini {...}) ;; Switch providers at runtime - just change the keyword (dscloj/predict provider-config module input :gpt4) (dscloj/predict provider-config module input :claude) (dscloj/predict provider-config module input :gemini) ``` -------------------------------- ### Quick Deployment with Makefile Source: https://github.com/unravel-team/dscloj/blob/main/DEPLOYMENT.md A simplified sequence for quick deployment using the Makefile, including setting credentials and optionally the project version, followed by running `make deploy`. ```bash # 1. Set your credentials export CLOJARS_USERNAME="your-username" export CLOJARS_PASSWORD="your-deploy-token" # 2. (Optional) Set version if not in deps.edn export PROJECT_VERSION="0.1.0" # 3. Run make deploy make deploy ``` -------------------------------- ### Manual Deployment Command Source: https://github.com/unravel-team/dscloj/blob/main/DEPLOYMENT.md Performs a manual deployment using the `clojure -X:deploy` command. This is an alternative to using the Makefile and relies on `deps-deploy` to handle the deployment. ```bash clojure -X:deploy ``` -------------------------------- ### Run Project Tests Source: https://github.com/unravel-team/dscloj/blob/main/DEPLOYMENT.md Executes the project's test suite using the `clojure` command-line tool with the `:test` alias and `kaocha.runner` namespace. This ensures code quality before deployment. ```bash clojure -M:test -m kaocha.runner ``` -------------------------------- ### Clojure: Migrate Testing to New Dscloj API Source: https://github.com/unravel-team/dscloj/blob/main/MIGRATION.md Shows how to adapt tests when migrating to the new dscloj API. The example demonstrates using an ad-hoc provider configuration directly within the `dscloj/predict` call for testing purposes, mirroring the new API's flexibility. ```clojure ;; Before (deftest predict-test (let [result (dscloj/predict provider-config module input {:model "gpt-3.5-turbo" :api-key test-key})] (is (= expected result)))) ;; After (deftest predict-test ;; Use ad-hoc provider for tests (let [result (dscloj/predict provider-config module input {:provider :openai :model "gpt-3.5-turbo" :config {:api-key test-key}})] (is (= expected result)))) ``` -------------------------------- ### Tagging a Git Release Source: https://github.com/unravel-team/dscloj/blob/main/DEPLOYMENT.md Demonstrates how to create a Git tag for a release, typically done after a successful deployment. This helps in version control and identifying specific release points. ```bash git tag v0.1.0 ``` -------------------------------- ### Deploy Artifacts using Makefile Source: https://github.com/unravel-team/dscloj/blob/main/DEPLOYMENT.md Triggers the deployment process using the `make deploy` command. This command automates several steps including credential checking, test execution, POM generation, and deployment to Clojars. ```bash make deploy ``` -------------------------------- ### Pushing Git Tags Source: https://github.com/unravel-team/dscloj/blob/main/DEPLOYMENT.md Pushes all local Git tags to the remote repository. This ensures that tags are available to collaborators and CI/CD systems. ```bash git push origin --tags ``` -------------------------------- ### Clojure: Multi-Provider Support for Result Comparison Source: https://github.com/unravel-team/dscloj/blob/main/MIGRATION.md Shows how to leverage multi-provider support in dscloj to fetch results from different LLMs and compare them. This is useful for evaluating model performance or ensuring consistency across providers. ```clojure ;; Compare results from different providers (def openai-result (dscloj/predict provider-config module input :gpt4)) (def anthropic-result (dscloj/predict provider-config module input :claude)) (when (not= openai-result anthropic-result) (println "Different results!")) ``` -------------------------------- ### Set Project Version as Environment Variable Source: https://github.com/unravel-team/dscloj/blob/main/DEPLOYMENT.md An alternative to updating `deps.edn` directly, this method sets the project version using an environment variable (`PROJECT_VERSION`) before deployment. ```bash export PROJECT_VERSION="0.1.0" ``` -------------------------------- ### Register LLM Providers in Clojure Source: https://context7.com/unravel-team/dscloj/llms.txt Register LLM provider configurations for reuse in your application. Supports individual registration, multiple registrations, and quick setup from environment variables. Lists all registered providers. ```clojure (require '[dscloj.core :as dscloj]) ;; Register a single provider (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) ;; Register multiple providers (dscloj/register-provider! :claude {:provider :anthropic :model "claude-3-5-sonnet-20241022" :config {:api-key (System/getenv "ANTHROPIC_API_KEY")}}) (dscloj/register-provider! :gemini {:provider :gemini :model "gemini-pro" :config {:api-key (System/getenv "GOOGLE_API_KEY")}}) ;; Quick setup from environment variables (registers common providers automatically) (dscloj/quick-setup!) ;; List all registered providers (dscloj/list-providers) ;; => {:gpt4 {:provider :openai, :model "gpt-4", :config {...}} ;; :claude {:provider :anthropic, :model "claude-3-5-sonnet-20241022", :config {...}}} ``` -------------------------------- ### Set Clojars Credentials for Deployment Source: https://github.com/unravel-team/dscloj/blob/main/DEPLOYMENT.md Sets the necessary Clojars username and deploy token as environment variables. These are required by `deps-deploy` for authentication. Ensure these are kept secure and not committed to version control. ```bash export CLOJARS_USERNAME="your-clojars-username" export CLOJARS_PASSWORD="your-deploy-token" ``` -------------------------------- ### Clojure: Predict Stream with New API Configuration Source: https://github.com/unravel-team/dscloj/blob/main/MIGRATION.md Demonstrates using dscloj/predict-stream with the new API, which requires registering providers and then referencing them by keyword. This allows for cleaner separation of concerns and easier management of LLM configurations. ```clojure ;; Register provider first (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) (let [stream-ch (dscloj/predict-stream whales-module {:query "Tell me about whales"} :gpt4 ; provider-config {:debounce-ms 100})] ; options (go-loop [] (when-let [result ( "Paris" ``` -------------------------------- ### Clojure: Troubleshooting 'Wrong number of arguments' Error in Dscloj Source: https://github.com/unravel-team/dscloj/blob/main/MIGRATION.md Addresses the 'Wrong number of arguments to predict' error in dscloj, explaining that it arises from using the old API signature. The fix involves providing the provider configuration as the third argument, correctly formatted for the new API. ```clojure ;; Wrong (dscloj/predict provider-config module input {:model "gpt-4" :api-key "..."}) ;; Right (dscloj/predict provider-config module input {:provider :openai :model "gpt-4" :config {:api-key "..."}}) ``` -------------------------------- ### Fix DSCloj Predict Options Positioning in Clojure Source: https://github.com/unravel-team/dscloj/blob/main/MIGRATION.md Demonstrates the correct way to pass sampling options to the dscloj/predict function. Options must be provided as a map in the 4th argument position, not as separate keyword arguments. This fixes a common migration issue where options were placed in the wrong position. ```clojure ;; Wrong - options in wrong position (dscloj/predict provider-config module input :gpt4 :temperature 0.7) ;; Right - options as map in 4th argument (dscloj/predict provider-config module input :gpt4 {:temperature 0.7}) ``` -------------------------------- ### Register Multiple LLM Providers in DSCloj Source: https://github.com/unravel-team/dscloj/blob/main/README.md Configure and manage multiple LLM providers using DSCloj's registration API. Supports OpenAI, Anthropic, and other providers via litellm-clj, with options for registration, quick-setup from environment variables, or ad-hoc provider configuration. ```clojure ;; Option 1: Register providers (recommended) (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) (dscloj/register-provider! :claude {:provider :anthropic :model "claude-3-5-sonnet-20241022" :config {:api-key (System/getenv "ANTHROPIC_API_KEY")}}) ;; Use registered providers (dscloj/predict :gpt4 qa-module {:question "..."} :gpt4) (dscloj/predict :gpt4 qa-module {:question "..."} :claude) ;; Option 2: Quick setup from environment (dscloj/quick-setup!) ; Reads OPENAI_API_KEY, ANTHROPIC_API_KEY, etc. ;; Option 3: Ad-hoc provider (no registration) (dscloj/predict :gpt4 qa-module {:question "..."} {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) ``` -------------------------------- ### Create and Use Basic Q&A Module in Clojure Source: https://context7.com/unravel-team/dscloj/llms.txt Define a simple Question-Answering module with typed inputs and outputs using Malli specs. Allows prediction using registered providers and demonstrates switching between providers for the same module. ```clojure (require '[dscloj.core :as dscloj]) ;; Define module with Malli specs (def qa-module {:inputs [{:name :question :spec :string :description "The question to answer"}] :outputs [{:name :answer :spec :string :description "The answer to the question"}] :instructions "Provide concise and accurate answers."}) ;; Register provider (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) ;; Make prediction (def result (dscloj/predict :gpt4 qa-module {:question "What is the capital of France?"})) (:answer result) ;; => "Paris" ;; Use different provider for same module (dscloj/register-provider! :claude {:provider :anthropic :model "claude-haiku-4-5" :config {:api-key (System/getenv "ANTHROPIC_API_KEY")}}) (def result2 (dscloj/predict :claude qa-module {:question "What is the capital of France?"})) (:answer result2) ;; => "Paris is the capital of France." ``` -------------------------------- ### Inspect Generated Prompt Template in dscloj Source: https://context7.com/unravel-team/dscloj/llms.txt Demonstrates how to define a QA module with input and output specifications, then generate and inspect the resulting prompt template. Includes viewing the template structure for both simple and complex modules with various field types and constraints. The module->prompt function generates formatted prompts showing all fields and validation rules. ```clojure (require '[dscloj.core :as dscloj]) (def qa-module {:inputs [{:name :question :spec :string :description "The question to answer"}] :outputs [{:name :answer :spec :string :description "The answer to the question"}] :instructions "Provide concise and accurate answers."}) ;; View the generated prompt template (def prompt-template (dscloj/module->prompt qa-module)) (println prompt-template) ;; => "Your input fields are: ;; => 1. `question` (str): The question to answer ;; => Your output fields are: ;; => 1. `answer` (str): The answer to the question ;; => All interactions will be structured in the following way, with the appropriate values filled in. ;; => ;; => [[ ## question ## ]] ;; => {question} ;; => ;; => [[ ## answer ## ]] ;; => {answer} ;; => [[ ## completed ## ]] ;; => In adhering to this structure, your instructions are: Provide concise and accurate answers." ;; Inspect complex module prompts (def complex-module {:inputs [{:name :age :spec [:int {:min 0 :max 150}]} {:name :name :spec [:string {:min 1}]}] :outputs [{:name :message :spec :string} {:name :is_adult :spec :boolean}] :instructions "Generate a personalized message and determine if adult."}) (println (dscloj/module->prompt complex-module)) ``` -------------------------------- ### Define Input/Output Constraints with Malli Specs Source: https://context7.com/unravel-team/dscloj/llms.txt Illustrates defining input and output constraints using Malli schema specifications. This module requires dscloj.core and an OPENAI_API_KEY. It analyzes text, checks minimum length, and provides a confidence score, with validation ensuring adherence to defined specs. ```clojure (require '[dscloj.core :as dscloj]) (def analysis-module {:inputs [{:name :text :spec [:string {:min 1}] :description "Text to analyze"} {:name :min_length :spec [:int {:min 0}] :description "Minimum length requirement"}] :outputs [{:name :summary :spec :string :description "Summary of the text"} {:name :is_valid :spec :boolean :description "Whether text meets requirements"} {:name :confidence :spec [:double {:min 0.0 :max 1.0}] :description "Confidence score 0.0-1.0"}] :instructions "Analyze the text and check if it meets the minimum length requirement."}) (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) (def analysis-result (dscloj/predict :gpt4 analysis-module {:text "This is a sample text for analysis." :min_length 10})) ;; All outputs validated against Malli specs (:summary analysis-result) ;; => "Text discusses a sample for analysis purposes." (:is_valid analysis-result) ;; => true (:confidence analysis-result) ;; => 0.92 ;; Invalid input throws validation error (try (dscloj/predict :gpt4 analysis-module {:text "" ; Invalid: min length is 1 :min_length 10}) (catch clojure.lang.ExceptionInfo e (println "Error:" (.getMessage e)) (println "Details:" (ex-data e)))) ;; => "Error: Validation failed for field :text" ;; => "Details: {:field :text, :spec [:string {:min 1}], :value "", :errors ...}" ``` -------------------------------- ### Define and Reuse Malli Specs in Clojure Source: https://context7.com/unravel-team/dscloj/llms.txt Demonstrates how to define reusable Malli specifications for inputs and outputs in Clojure and use them across different modules. It also shows how to register a provider and make predictions. ```clojure (require '[dscloj.core :as dscloj]) ;; Define reusable specs (def QuestionSpec [:string {:min 1 :description "The question to answer"}]) (def AnswerSpec [:string {:min 1 :description "The answer"}]) (def ConfidenceSpec [:double {:min 0.0 :max 1.0 :description "Confidence score"}]) ;; Use specs in modules (def qa-with-context-module {:inputs [{:name :question :spec QuestionSpec} {:name :context :spec [:string {:description "Additional context"}]}] :outputs [{:name :answer :spec AnswerSpec} {:name :confidence :spec ConfidenceSpec}] :instructions "Answer based on the question and context."})) (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) (def result (dscloj/predict :gpt4 qa-with-context-module {:question "What is the capital?" :context "We are discussing France." })) (:answer result) ;; => "Paris" (:confidence result) ;; => 0.98 ;; Reuse specs in another module (def sentiment-module {:inputs [{:name :text :spec [:string {:min 1}]}] :outputs [{:name :sentiment :spec AnswerSpec} {:name :confidence :spec ConfidenceSpec}] :instructions "Analyze sentiment."})) ``` -------------------------------- ### Compare LLM Responses by Switching Providers in Clojure Source: https://context7.com/unravel-team/dscloj/llms.txt Register and switch between multiple LLM providers dynamically using `dscloj/register-provider!` and `dscloj/predict`. This enables comparison of responses from different models (e.g., OpenAI, Anthropic, Gemini) for the same query. It also allows for conditional provider selection based on runtime logic. Dependencies include `dscloj.core`. ```clojure (require '[dscloj.core :as dscloj]) (def qa-module {:inputs [{:name :question :spec :string}] :outputs [{:name :answer :spec :string}] :instructions "Provide accurate answers."}) ;; Register multiple providers (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) (dscloj/register-provider! :claude {:provider :anthropic :model "claude-3-5-sonnet-20241022" :config {:api-key (System/getenv "ANTHROPIC_API_KEY")}}) (dscloj/register-provider! :gemini {:provider :gemini :model "gemini-pro" :config {:api-key (System/getenv "GOOGLE_API_KEY")}}) ;; Compare responses across providers (def question {:question "What is artificial intelligence?"}) (def openai-result (dscloj/predict :gpt4 qa-module question)) (def anthropic-result (dscloj/predict :claude qa-module question)) (def gemini-result (dscloj/predict :gemini qa-module question)) (println "OpenAI:" (:answer openai-result)) ;; => "OpenAI: Artificial intelligence (AI) refers to computer systems..." (println "Anthropic:" (:answer anthropic-result)) ;; => "Anthropic: Artificial intelligence is the simulation of human intelligence..." (println "Gemini:" (:answer gemini-result)) ;; => "Gemini: AI is a branch of computer science that aims to create intelligent machines..." ;; Dynamic provider selection based on conditions (defn get-answer [question provider-key] (let [result (dscloj/predict provider-key qa-module {:question question})] (:answer result))) (def fast-answer (get-answer "What is 2+2?" :gpt4)) (def thoughtful-answer (get-answer "Explain quantum computing" :claude)) ``` -------------------------------- ### Stream Structured LLM Output with Progressive Parsing in dscloj Source: https://context7.com/unravel-team/dscloj/llms.txt Demonstrates streaming LLM responses using dscloj with progressive parsing and validation. Includes registering a provider, streaming predictions with debouncing options, and consuming updates via core.async channels. Supports custom callbacks for chunk processing and progressive validation of structured outputs. ```clojure (require '[dscloj.core :as dscloj] '[clojure.core.async :refer [go-loop "Hola, ¿cómo estás?" ;; High temperature for creative translations (def creative-result (dscloj/predict :gpt4 translation-module {:text "The cat sat on the mat" :target_language "French"} {:temperature 0.9})) (:translation creative-result) ;; => "Le chat s'est installé sur le tapis." ``` -------------------------------- ### Malli Spec Support for Input/Output Validation in DSCloj (Clojure) Source: https://github.com/unravel-team/dscloj/blob/main/README.md Demonstrates how DSCloj uses Malli specs to define and validate input and output fields for LLM modules. It shows simple, complex, and reusable spec definitions, including how to register providers, perform predictions, and optionally disable validation. Invalid inputs trigger validation errors. ```clojure ;; Simple specs (def qa-module {:inputs [{:name :question :spec :string :description "The question to answer"}] :outputs [{:name :answer :spec :string :description "The answer"}] :instructions "Provide concise and accurate answers."}) ;; Complex specs with constraints (def constrained-module {:inputs [{:name :age :spec [:int {:min 0 :max 150}]} {:name :email :spec [:string {:pattern #"^[^@]+@[^@]+$"}]}] :outputs [{:name :message :spec :string}]}) ;; Reusable specs (def QuestionSpec [:string {:min 1 :description "The question"}]) (def AnswerSpec [:string {:min 1 :description "The answer"}]) (def module-with-reusable-specs {:inputs [{:name :question :spec QuestionSpec}] :outputs [{:name :answer :spec AnswerSpec}]}) ;; Setup provider (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) ;; Invalid inputs/outputs are automatically validated (dscloj/predict :gpt4 qa-module {:question 123} ; Throws validation error - should be string :gpt4) ;; Disable validation if needed (dscloj/predict :gpt4 qa-module {:question "..."} :gpt4 {:validate? false}) ; Skip validation (4th argument for options) ``` -------------------------------- ### Handle Multiple Output Types with Type Conversion Source: https://context7.com/unravel-team/dscloj/llms.txt Showcases handling boolean, float, and string outputs with automatic type conversion and validation. This module requires the dscloj.core library and an OPENAI_API_KEY. It answers a question and provides a confidence score and a boolean indicating confidence. ```clojure (require '[dscloj.core :as dscloj]) (def qa-with-confidence-module {:inputs [{:name :question :spec :string :description "Question to answer"}] :outputs [{:name :answer :spec :string :description "The answer"} {:name :is_confident :spec :boolean :description "Whether the answer is confident"} {:name :confidence_score :spec :double :description "Confidence from 0.0 to 1.0"}] :instructions "Answer with confidence assessment."}) (dscloj/register-provider! :gpt4 {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY")}}) (def qa-result (dscloj/predict :gpt4 qa-with-confidence-module {:question "What is the speed of light?"})) ;; Types are automatically converted and validated (:answer qa-result) ;; => "The speed of light in vacuum is approximately 299,792,458 meters per second." (:is_confident qa-result) ;; => true (boolean) (:confidence_score qa-result) ;; => 0.95 (double) ;; Use in conditional logic (when (:is_confident qa-result) (if (> (:confidence_score qa-result) 0.8) (println "High confidence:" (:answer qa-result)) (println "Low confidence:" (:answer qa-result)))) ;; => "High confidence: The speed of light in vacuum is approximately 299,792,458 meters per second." ``` -------------------------------- ### Ad-Hoc LLM Provider Usage in Clojure Source: https://context7.com/unravel-team/dscloj/llms.txt Utilize LLM providers directly for one-off calls without pre-registration. This method works with any supported provider by passing the configuration directly to the predict function. ```clojure (require '[dscloj.core :as dscloj]) (def qa-module {:inputs [{:name :question :spec :string :description "The question to answer"}] :outputs [{:name :answer :spec :string :description "The answer"}] :instructions "Provide concise answers."}) ;; Use provider directly without registration (def result (dscloj/predict {:provider :openai :model "gpt-4" :config {:api-key (System/getenv "OPENAI_API_KEY" )}} qa-module {:question "What is 2+2?"})) (:answer result) ;; => "4" ;; Works with any supported provider (def anthropic-result (dscloj/predict {:provider :anthropic :model "claude-3-5-sonnet-20241022" :config {:api-key (System/getenv "ANTHROPIC_API_KEY")}} qa-module {:question "What is 2+2?"})) (:answer anthropic-result) ;; => "2+2 equals 4." ``` -------------------------------- ### Stream Responses with Ad-Hoc Providers in Clojure Source: https://context7.com/unravel-team/dscloj/llms.txt Stream LLM responses without pre-registering providers using `dscloj/predict-stream`. This function allows for dynamic provider configuration, input data, and stream options like debounce. It returns a channel that emits parsed results, suitable for real-time updates. Dependencies include `dscloj.core` and `clojure.core.async`. ```clojure (require '[dscloj.core :as dscloj] '[clojure.core.async :refer [go-loop