Remove AGENTS env seeding; agents managed only via admin API
The store now starts empty and agents are added/removed exclusively through the web admin page / admin API, persisted to AGENTS_FILE. No AGENTS env var needed in the sops secret.
This commit is contained in:
@@ -37,13 +37,16 @@ in the `AGENTS` env var.
|
|||||||
|
|
||||||
| Var | Required | Purpose |
|
| 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. |
|
| `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`). |
|
| `AGENTS_FILE` | no | Path to the JSON store (default `/var/lib/n8n-openai/agents.json`). |
|
||||||
| `PORT` | no | HTTP port (default `8000`). |
|
| `PORT` | no | HTTP port (default `8000`). |
|
||||||
| `CHAT_WEBHOOK_BASIC` | no | `"user:password"` if your n8n Chat Trigger is Basic-auth protected. |
|
| `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)
|
## Admin API (manage agents at runtime)
|
||||||
|
|
||||||
Agents are persisted to `AGENTS_FILE` and can be added/removed without a
|
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
|
https://openai.bueso.eu/admin/agents/media-agent
|
||||||
```
|
```
|
||||||
|
|
||||||
The `AGENTS` env var only seeds the store on first boot; after that the file is
|
The store is authoritative and persists across restarts; no env config needed.
|
||||||
authoritative.
|
|
||||||
|
|
||||||
## Building & running
|
## Building & running
|
||||||
|
|
||||||
|
|||||||
+4
-10
@@ -1,13 +1,7 @@
|
|||||||
import Config
|
import Config
|
||||||
|
|
||||||
# Test environment: seed agents via application env (AgentRegistry falls back to
|
# Test environment: the app starts with an empty agent store (no AGENTS env
|
||||||
# this when the AGENTS_FILE doesn't exist yet). ADAPTER_API_KEY / ADMIN_API_KEY
|
# seeding — agents are managed via the admin API). ADAPTER_API_KEY /
|
||||||
# are set in test/test_helper.exs. AGENTS_FILE must be set HERE (config loads
|
# ADMIN_API_KEY are set in test/test_helper.exs. AGENTS_FILE must be set HERE
|
||||||
# before the app boots) to a writable tmp path.
|
# (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"
|
|
||||||
}
|
|
||||||
|
|
||||||
System.put_env("AGENTS_FILE", Path.join(System.tmp_dir!(), "n8n-openai-test-agents.json"))
|
System.put_env("AGENTS_FILE", Path.join(System.tmp_dir!(), "n8n-openai-test-agents.json"))
|
||||||
|
|||||||
@@ -18,28 +18,8 @@ defmodule N8nOpenaiAdapter.Application do
|
|||||||
|
|
||||||
defp port, do: String.to_integer(System.get_env("PORT", "8000"))
|
defp port, do: String.to_integer(System.get_env("PORT", "8000"))
|
||||||
|
|
||||||
defp configured_agents do
|
# Agents are managed at runtime via the admin API and persisted to AGENTS_FILE.
|
||||||
# Prefer application env (:agents) — settable from config/*.exs, which loads
|
# We start with an empty store (no AGENTS env seeding) — the web admin is the
|
||||||
# before the app boots. Falls back to the AGENTS env var (JSON map of
|
# single source of truth for which agents are exposed.
|
||||||
# model -> n8n chat webhook URL).
|
defp configured_agents, do: %{}
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,8 +3,17 @@ defmodule N8nOpenaiAdapter.RouterTest do
|
|||||||
import Plug.Test
|
import Plug.Test
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
|
|
||||||
|
alias N8nOpenaiAdapter.AgentRegistry
|
||||||
alias N8nOpenaiAdapter.Router
|
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
|
test "GET /v1/models lists configured agents" do
|
||||||
conn =
|
conn =
|
||||||
conn(:get, "/v1/models")
|
conn(:get, "/v1/models")
|
||||||
|
|||||||
Reference in New Issue
Block a user