Skip to content

Commit a9d53f7

Browse files
committed
Merge branch 'master' into improve-approval
2 parents 1e77bd4 + 6b3b8a9 commit a9d53f7

File tree

5 files changed

+92
-30
lines changed

5 files changed

+92
-30
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+
- Fix command prompts to allow args with spaces between quotes.
6+
- Fix anthropic token renew when expires.
57
- Considerably improve toolCall approval / permissions config.
68
- Now with thave multiple optiosn to ask or allow tool calls, check config section.
79

docs/models.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,27 @@ Only set this when your provider uses a different path or expects query paramete
230230
}
231231
```
232232

233+
=== "Same model with different settings"
234+
235+
For now, you can create different providers with same model names to achieve that:
236+
237+
```javascript
238+
{
239+
"providers": {
240+
"openai": {
241+
"api": "openai-responses",
242+
"models": { "gpt-5": {} }
243+
},
244+
"openai-high": {
245+
"api": "openai-responses",
246+
"url": "https://api.openai.com",
247+
"keyEnv": "OPENAI_API_KEY",
248+
"models": {
249+
"gpt-5": {
250+
"extraPayload": { "reasoning": { "effort": "high" } }
251+
}
252+
}
253+
}
254+
}
255+
}
256+
```

src/eca/features/chat.clj

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,29 @@
7676
:message-cost (shared/tokens->cost input-tokens input-cache-creation-tokens input-cache-read-tokens output-tokens full-model db)
7777
:session-cost (shared/tokens->cost total-input-tokens total-input-cache-creation-tokens total-input-cache-read-tokens total-output-tokens full-model db)))))
7878

79-
(defn ^:private message->decision [message]
80-
(let [slash? (string/starts-with? message "/")
81-
mcp-prompt? (string/includes? (first (string/split message #" ")) ":")]
82-
(cond
83-
(and slash? mcp-prompt?)
84-
(let [command (subs message 1)
85-
parts (string/split command #" ")
86-
[server] (string/split command #":")]
87-
{:type :mcp-prompt
88-
:server server
89-
:prompt (second (string/split (first parts) #":"))
90-
:args (vec (rest parts))})
79+
(defn ^:private tokenize-args [^String s]
80+
(if (string/blank? s)
81+
[]
82+
(->> (re-seq #"\s*\"([^\"]*)\"|\s*([^\s]+)" s)
83+
(map (fn [[_ quoted unquoted]] (or quoted unquoted)))
84+
(vec))))
9185

92-
slash?
86+
(defn ^:private message->decision [message]
87+
(let [slash? (string/starts-with? message "/")]
88+
(if slash?
9389
(let [command (subs message 1)
94-
parts (string/split command #" ")]
95-
{:type :eca-command
96-
:command (first parts)
97-
:args (vec (rest parts))})
98-
99-
:else
90+
tokens (let [toks (tokenize-args command)] (if (seq toks) toks [""]))
91+
first-token (first tokens)
92+
args (vec (rest tokens))]
93+
(if (and first-token (string/includes? first-token ":"))
94+
(let [[server prompt] (string/split first-token #":" 2)]
95+
{:type :mcp-prompt
96+
:server server
97+
:prompt prompt
98+
:args args})
99+
{:type :eca-command
100+
:command first-token
101+
:args args}))
100102
{:type :prompt-message
101103
:message message})))
102104

@@ -230,15 +232,15 @@
230232
:origin origin)})
231233
(send-content! chat-ctx :assistant
232234
(assoc-some
233-
{:type :toolCalled
234-
:origin origin
235-
:name name
236-
:arguments arguments
237-
:error (:error result)
238-
:id id
239-
:outputs (:contents result)}
240-
:details details
241-
:summary summary))))
235+
{:type :toolCalled
236+
:origin origin
237+
:name name
238+
:arguments arguments
239+
:error (:error result)
240+
:id id
241+
:outputs (:contents result)}
242+
:details details
243+
:summary summary))))
242244
(do
243245
(add-to-history! {:role "tool_call" :content tool-call})
244246
(add-to-history! {:role "tool_call_output"

src/eca/llm_providers/anthropic.clj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@
251251
url
252252
{:headers {"Content-Type" "application/json"}
253253
:body (json/generate-string body)
254+
:throw-exceptions? false
254255
:as :json})]
255256
(if (= 200 status)
256257
{:refresh-token (:refresh_token body)
@@ -341,8 +342,8 @@
341342
(send-msg! (format "Invalid API key '%s'" input))))
342343

343344
(defmethod f.login/login-step ["anthropic" :login/renew-token] [{:keys [db* provider]}]
344-
(let [{:keys [access-token refresh-token expires-at]} (get-in @db* [:auth provider])
345-
{:keys []} (oauth-refresh refresh-token)]
345+
(let [{:keys [refresh-token]} (get-in @db* [:auth provider])
346+
{:keys [refresh-token access-token expires-at]} (oauth-refresh refresh-token)]
346347
(swap! db* update-in [:auth provider] merge {:step :login/done
347348
:type :auth/oauth
348349
:refresh-token refresh-token

test/eca/features/chat_test.clj

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,36 @@
268268
(is (match?
269269
@invoked?
270270
[[{:role :user :content "test"}] test-chat-ctx]))))))
271+
272+
(deftest message->decision-test
273+
(testing "plain prompt message"
274+
(is (= {:type :prompt-message
275+
:message "Hello world"}
276+
(#'f.chat/message->decision "Hello world"))))
277+
(testing "ECA command without args"
278+
(is (= {:type :eca-command
279+
:command "help"
280+
:args []}
281+
(#'f.chat/message->decision "/help"))))
282+
(testing "ECA command with args"
283+
(is (= {:type :eca-command
284+
:command "search"
285+
:args ["foo" "bar"]}
286+
(#'f.chat/message->decision "/search foo bar"))))
287+
(testing "ECA command with args with spaces in quotes"
288+
(is (= {:type :eca-command
289+
:command "search"
290+
:args ["foo bar" "baz" "qux bla blow"]}
291+
(#'f.chat/message->decision "/search \"foo bar\" baz \"qux bla blow\""))))
292+
(testing "MCP prompt without args"
293+
(is (= {:type :mcp-prompt
294+
:server "server"
295+
:prompt "prompt"
296+
:args []}
297+
(#'f.chat/message->decision "/server:prompt"))))
298+
(testing "MCP prompt with args"
299+
(is (= {:type :mcp-prompt
300+
:server "server"
301+
:prompt "prompt"
302+
:args ["arg1" "arg2"]}
303+
(#'f.chat/message->decision "/server:prompt arg1 arg2")))))

0 commit comments

Comments
 (0)