Skip to content

Commit 48f0de4

Browse files
committed
Support defaultModel in custom providers
1 parent 5c32f8d commit 48f0de4

File tree

5 files changed

+78
-10
lines changed

5 files changed

+78
-10
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Support defaultModel in custom providers.
6+
57
## 0.6.0
68

79
- Add usage tokens + cost to chat messages.

docs/configuration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ It's possible to configure ECA to be aware of custom LLM providers if they follo
114114
"api": "openai",
115115
"urlEnv": "MY_COMPANY_API_URL", // or "url": "https://litellm.my-company.com",
116116
"keyEnv": "MY_COMPANY_API_KEY", // or "key": "123",
117-
"models": ["gpt-4.1", "deepseek-r1"]
117+
"models": ["gpt-4.1", "deepseek-r1"],
118+
"defaultModel": "deepseek-r1"
118119
}
119120
}
120121
}
@@ -141,6 +142,7 @@ interface Config {
141142
customProviders: {[key: string]: {
142143
api: 'openai' | 'anthropic';
143144
models: string[];
145+
defaultModel?: string;
144146
url?: string;
145147
urlEnv?: string;
146148
key?: string;

src/eca/handlers.clj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
(when-let [custom-providers (seq (:customProviders config))]
1515
(swap! db* update :models merge
1616
(reduce
17-
(fn [models [provider {provider-models :models}]]
17+
(fn [models [provider {provider-models :models default-model :defaultModel}]]
1818
(reduce
1919
(fn [m model]
2020
(assoc m
2121
(str (name provider) "/" model)
22-
{:tools true}))
22+
{:tools true
23+
:custom-provider? true
24+
:default-model? (= model default-model)}))
2325
models
2426
provider-models))
2527
{}

src/eca/llm_api.clj

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
(config/get-env "ANTHROPIC_API_KEY")))
2525

2626
(defn ^:private anthropic-api-url []
27-
(or (System/getenv "ANTHROPIC_API_URL")
27+
(or (config/get-env "ANTHROPIC_API_URL")
2828
llm-providers.anthropic/base-url))
2929

3030
(defn ^:private openai-api-key [config]
@@ -37,17 +37,26 @@
3737

3838
(defn default-model
3939
"Returns the default LLM model checking this waterfall:
40+
- Any custom provider with defaultModel set
4041
- Anthropic api key set
4142
- Openai api key set
4243
- Ollama first model if running
4344
- Anthropic default model."
4445
[db config]
45-
(let [[decision model] (or (first (filter #(string/starts-with? % config/ollama-model-prefix) (vals (:models db))))
46-
(when (anthropic-api-key config)
47-
[:api-key-found "claude-sonnet-4-0"])
48-
(when (openai-api-key config)
49-
[:api-key-found "o4-mini"])
50-
[:default "claude-sonnet-4-0"])]
46+
(let [[decision model]
47+
(or (when-let [custom-provider-default-model (first (keep (fn [[model config]]
48+
(when (and (:custom-provider? config)
49+
(:default-model? config))
50+
model))
51+
(:models db)))]
52+
[:custom-provider-default-model custom-provider-default-model])
53+
(when-let [ollama-model (first (filter #(string/starts-with? % config/ollama-model-prefix) (keys (:models db))))]
54+
[:ollama-running ollama-model])
55+
(when (anthropic-api-key config)
56+
[:api-key-found "claude-sonnet-4-0"])
57+
(when (openai-api-key config)
58+
[:api-key-found "o4-mini"])
59+
[:default "claude-sonnet-4-0"])]
5160
(logger/info logger-tag (format "Default LLM model '%s' decision '%s'" model decision))
5261
model))
5362

test/eca/llm_api_test.clj

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
(ns eca.llm-api-test
2+
(:require
3+
[clojure.test :refer [deftest is testing]]
4+
[eca.config :as config]
5+
[eca.llm-api :as llm-api]
6+
[eca.test-helper :as h]))
7+
8+
(h/reset-components-before-test)
9+
10+
(deftest default-model-test
11+
(testing "Custom provider default-model? present"
12+
(with-redefs [config/get-env (constantly nil)]
13+
(let [db {:models {"my-model" {:custom-provider? true :default-model? true}}}
14+
config {}]
15+
(is (= "my-model" (llm-api/default-model db config))))))
16+
17+
(testing "Ollama running model present"
18+
(with-redefs [config/get-env (constantly nil)]
19+
(let [db {:models {"ollama/foo" {:tools true}
20+
"gpt-4.1" {:tools true}
21+
"other-model" {:tools true}}}
22+
config {}]
23+
(is (= "ollama/foo" (llm-api/default-model db config))))))
24+
25+
(testing "Anthropic API key present in config"
26+
(with-redefs [config/get-env (constantly nil)]
27+
(let [db {:models {}}
28+
config {:anthropicApiKey "something"}]
29+
(is (= "claude-sonnet-4-0" (llm-api/default-model db config))))))
30+
31+
(testing "Anthropic API key present in ENV"
32+
(with-redefs [config/get-env (fn [k] (when (= k "ANTHROPIC_API_KEY") "env-anthropic"))]
33+
(let [db {:models {}}
34+
config {}]
35+
(is (= "claude-sonnet-4-0" (llm-api/default-model db config))))))
36+
37+
(testing "OpenAI API key present in config"
38+
(with-redefs [config/get-env (constantly nil)]
39+
(let [db {:models {}}
40+
config {:openaiapikey "yes!"}]
41+
(is (= "o4-mini" (llm-api/default-model db config))))))
42+
43+
(testing "OpenAI API key present in ENV"
44+
(with-redefs [config/get-env (fn [k] (when (= k "OPENAI_API_KEY") "env-openai"))]
45+
(let [db {:models {}}
46+
config {}]
47+
(is (= "o4-mini" (llm-api/default-model db config))))))
48+
49+
(testing "Fallback default (no keys anywhere)"
50+
(with-redefs [config/get-env (constantly nil)]
51+
(let [db {:models {}}
52+
config {}]
53+
(is (= "claude-sonnet-4-0" (llm-api/default-model db config)))))))

0 commit comments

Comments
 (0)