From 86c827fbe475d816b736745dfd704603484e5664 Mon Sep 17 00:00:00 2001 From: Mike Hostetler <84222+mikehostetler@users.noreply.github.com> Date: Mon, 23 Mar 2026 07:11:03 -0500 Subject: [PATCH 1/3] fix: honor req_llm load_dotenv when starting llm_db --- lib/req_llm/application.ex | 20 ++++++- mix.exs | 1 + test/req_llm/application_test.exs | 88 +++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) diff --git a/lib/req_llm/application.ex b/lib/req_llm/application.ex index 71d755266..2be8a3af6 100644 --- a/lib/req_llm/application.ex +++ b/lib/req_llm/application.ex @@ -20,10 +20,15 @@ defmodule ReqLLM.Application do @impl true def start(_type, _args) do - if Application.get_env(:req_llm, :load_dotenv, true) do + req_llm_load_dotenv = Application.get_env(:req_llm, :load_dotenv, true) + + sync_llm_db_dotenv_config(req_llm_load_dotenv) + + if req_llm_load_dotenv do load_dotenv() end + ensure_llm_db_started() initialize_registry() initialize_schema_cache() @@ -127,6 +132,19 @@ defmodule ReqLLM.Application do ]) end + defp sync_llm_db_dotenv_config(req_llm_load_dotenv) do + if Application.get_env(:llm_db, :load_dotenv) == nil do + Application.put_env(:llm_db, :load_dotenv, req_llm_load_dotenv) + end + end + + defp ensure_llm_db_started do + case Application.ensure_all_started(:llm_db) do + {:ok, _} -> :ok + {:error, reason} -> raise "failed to start :llm_db: #{inspect(reason)}" + end + end + defp load_dotenv do env_file = Path.join(File.cwd!(), ".env") diff --git a/mix.exs b/mix.exs index 07e75009a..31e197586 100644 --- a/mix.exs +++ b/mix.exs @@ -185,6 +185,7 @@ defmodule ReqLLM.MixProject do def application do [ extra_applications: [:logger, :xmerl], + included_applications: [:llm_db], mod: {ReqLLM.Application, []} ] end diff --git a/test/req_llm/application_test.exs b/test/req_llm/application_test.exs index be9b922ef..e3001c33c 100644 --- a/test/req_llm/application_test.exs +++ b/test/req_llm/application_test.exs @@ -1,6 +1,26 @@ defmodule ReqLLM.ApplicationTest do use ExUnit.Case, async: false + @dotenv_key "REQ_LLM_ISSUE_527_DOTENV_KEY" + + setup do + original_req_llm_load_dotenv = Application.get_env(:req_llm, :load_dotenv) + original_llm_db_load_dotenv = Application.get_env(:llm_db, :load_dotenv) + + on_exit(fn -> + stop_app(:req_llm) + stop_app(:llm_db) + restore_app_env(:req_llm, :load_dotenv, original_req_llm_load_dotenv) + restore_app_env(:llm_db, :load_dotenv, original_llm_db_load_dotenv) + System.delete_env(@dotenv_key) + Application.ensure_all_started(:llm_db) + LLMDB.load(custom: Application.get_env(:llm_db, :custom, %{})) + Application.ensure_all_started(:req_llm) + end) + + :ok + end + describe "load_dotenv configuration" do test "get_finch_config/0 returns default configuration" do config = ReqLLM.Application.get_finch_config() @@ -40,5 +60,73 @@ defmodule ReqLLM.ApplicationTest do end end end + + test "load_dotenv false prevents llm_db from loading .env during req_llm startup" do + with_apps_stopped(fn -> + with_temp_dir(fn -> + File.write!(".env", "#{@dotenv_key}=from_file\n") + System.delete_env(@dotenv_key) + Application.put_env(:req_llm, :load_dotenv, false) + Application.delete_env(:llm_db, :load_dotenv) + + assert {:ok, _} = Application.ensure_all_started(:req_llm) + assert System.get_env(@dotenv_key) == nil + end) + end) + end + + test "startup does not overwrite existing env vars from .env files" do + with_apps_stopped(fn -> + with_temp_dir(fn -> + File.write!(".env", "#{@dotenv_key}=from_file\n") + System.put_env(@dotenv_key, "from_env") + Application.delete_env(:req_llm, :load_dotenv) + Application.delete_env(:llm_db, :load_dotenv) + + assert {:ok, _} = Application.ensure_all_started(:req_llm) + assert System.get_env(@dotenv_key) == "from_env" + end) + end) + end + + test "explicit llm_db load_dotenv config overrides req_llm default" do + with_apps_stopped(fn -> + with_temp_dir(fn -> + File.write!(".env", "#{@dotenv_key}=from_file\n") + System.delete_env(@dotenv_key) + Application.put_env(:req_llm, :load_dotenv, false) + Application.put_env(:llm_db, :load_dotenv, true) + + assert {:ok, _} = Application.ensure_all_started(:req_llm) + assert System.get_env(@dotenv_key) == "from_file" + end) + end) + end + end + + defp with_apps_stopped(fun) do + stop_app(:req_llm) + stop_app(:llm_db) + fun.() + end + + defp with_temp_dir(fun) do + path = Path.join(System.tmp_dir!(), "req-llm-issue-527-#{System.unique_integer([:positive])}") + File.mkdir_p!(path) + + try do + File.cd!(path, fun) + after + File.rm_rf!(path) + end + end + + defp stop_app(app) do + if Keyword.has_key?(Application.started_applications(), app) do + Application.stop(app) + end end + + defp restore_app_env(app, key, nil), do: Application.delete_env(app, key) + defp restore_app_env(app, key, value), do: Application.put_env(app, key, value) end From 1d227f8801a7435f52fc7dc01ea19a256e1e6d2d Mon Sep 17 00:00:00 2001 From: Mike Hostetler <84222+mikehostetler@users.noreply.github.com> Date: Mon, 23 Mar 2026 07:16:52 -0500 Subject: [PATCH 2/3] refactor: only inherit llm_db load_dotenv when unset --- lib/req_llm/application.ex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/req_llm/application.ex b/lib/req_llm/application.ex index 2be8a3af6..3ea64fa6f 100644 --- a/lib/req_llm/application.ex +++ b/lib/req_llm/application.ex @@ -133,8 +133,12 @@ defmodule ReqLLM.Application do end defp sync_llm_db_dotenv_config(req_llm_load_dotenv) do - if Application.get_env(:llm_db, :load_dotenv) == nil do - Application.put_env(:llm_db, :load_dotenv, req_llm_load_dotenv) + case Application.fetch_env(:llm_db, :load_dotenv) do + :error -> + Application.put_env(:llm_db, :load_dotenv, req_llm_load_dotenv) + + {:ok, _value} -> + :ok end end From efa0d9a81d47a099a8145b7477da30e57ee66afa Mon Sep 17 00:00:00 2001 From: Mike Hostetler <84222+mikehostetler@users.noreply.github.com> Date: Mon, 23 Mar 2026 07:23:12 -0500 Subject: [PATCH 3/3] fix: include llm_db in dialyzer plt apps --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 31e197586..84fd26b2e 100644 --- a/mix.exs +++ b/mix.exs @@ -19,7 +19,7 @@ defmodule ReqLLM.MixProject do # Dialyzer configuration dialyzer: [ - plt_add_apps: [:mix], + plt_add_apps: [:mix, :llm_db], exclude_paths: ["test/support"] ],