diff --git a/README.md b/README.md index 910ef733b4..7b269715bd 100644 --- a/README.md +++ b/README.md @@ -37,13 +37,16 @@ in the `AGENTS` env var. | Var | Required | Purpose | |------------------|----------|---------------------------------------------------------------------| -| `AGENTS` | seed | JSON map of `model -> n8n chat webhook URL` used to seed the store on first boot. e.g. `{"scholar-agent":"https://..."}` | | `ADAPTER_API_KEY`| yes | Bearer key that OpenAI clients send. | -| `ADMIN_API_KEY` | yes | Bearer key for the admin API (manage agents at runtime). | +| `ADMIN_API_KEY` | yes | Bearer key for the admin API / web admin page. | | `AGENTS_FILE` | no | Path to the JSON store (default `/var/lib/n8n-openai/agents.json`). | | `PORT` | no | HTTP port (default `8000`). | | `CHAT_WEBHOOK_BASIC` | no | `"user:password"` if your n8n Chat Trigger is Basic-auth protected. | +Agents are **not** configured via env — they're managed at runtime through the +web admin page / admin API and persisted to `AGENTS_FILE`. The store starts +empty; add agents after boot. + ## Admin API (manage agents at runtime) Agents are persisted to `AGENTS_FILE` and can be added/removed without a @@ -63,8 +66,7 @@ curl -X DELETE -H "Authorization: Bearer $ADMIN_API_KEY" \ https://openai.bueso.eu/admin/agents/media-agent ``` -The `AGENTS` env var only seeds the store on first boot; after that the file is -authoritative. +The store is authoritative and persists across restarts; no env config needed. ## Building & running diff --git a/config/test.exs b/config/test.exs index 8e170f44bb..2cff8bd6e4 100644 --- a/config/test.exs +++ b/config/test.exs @@ -1,13 +1,7 @@ import Config -# Test environment: seed agents via application env (AgentRegistry falls back to -# this when the AGENTS_FILE doesn't exist yet). ADAPTER_API_KEY / ADMIN_API_KEY -# are set in test/test_helper.exs. AGENTS_FILE must be set HERE (config loads -# before the app boots) to a writable tmp path. -config :n8n_openai_adapter, - agents: %{ - "scholar-agent" => "https://n8n.bueso.eu/webhook/scholar-id/chat", - "media-agent" => "https://n8n.bueso.eu/webhook/media-id/chat" - } - +# Test environment: the app starts with an empty agent store (no AGENTS env +# seeding — agents are managed via the admin API). ADAPTER_API_KEY / +# ADMIN_API_KEY are set in test/test_helper.exs. AGENTS_FILE must be set HERE +# (config loads before the app boots) to a writable tmp path. System.put_env("AGENTS_FILE", Path.join(System.tmp_dir!(), "n8n-openai-test-agents.json")) diff --git a/lib/n8n_openai_adapter/application.ex b/lib/n8n_openai_adapter/application.ex index f6c105acb6..9a6868ee3c 100644 --- a/lib/n8n_openai_adapter/application.ex +++ b/lib/n8n_openai_adapter/application.ex @@ -18,28 +18,8 @@ defmodule N8nOpenaiAdapter.Application do defp port, do: String.to_integer(System.get_env("PORT", "8000")) - defp configured_agents do - # Prefer application env (:agents) — settable from config/*.exs, which loads - # before the app boots. Falls back to the AGENTS env var (JSON map of - # model -> n8n chat webhook URL). - case Application.fetch_env(:n8n_openai_adapter, :agents) do - {:ok, agents} when is_map(agents) -> - agents - - _ -> - case System.get_env("AGENTS") do - nil -> - # single agent from old N8N_WEBHOOK_URL / MODEL_NAME env - model = System.get_env("MODEL_NAME", "default-agent") - - case System.get_env("N8N_WEBHOOK_URL") do - nil -> %{} - webhook -> %{model => webhook} - end - - json -> - Jason.decode!(json) - end - end - end + # Agents are managed at runtime via the admin API and persisted to AGENTS_FILE. + # We start with an empty store (no AGENTS env seeding) — the web admin is the + # single source of truth for which agents are exposed. + defp configured_agents, do: %{} end diff --git a/test/router_test.exs b/test/router_test.exs index 69da3162a0..10659b873d 100644 --- a/test/router_test.exs +++ b/test/router_test.exs @@ -3,8 +3,17 @@ defmodule N8nOpenaiAdapter.RouterTest do import Plug.Test import Plug.Conn + alias N8nOpenaiAdapter.AgentRegistry alias N8nOpenaiAdapter.Router + setup do + # The app starts with an empty store (no AGENTS env seeding). Seed the two + # test agents via the registry so the base tests have something to list. + AgentRegistry.put("scholar-agent", "https://n8n.bueso.eu/webhook/scholar-id/chat") + AgentRegistry.put("media-agent", "https://n8n.bueso.eu/webhook/media-id/chat") + :ok + end + test "GET /v1/models lists configured agents" do conn = conn(:get, "/v1/models")