Skip to content

Commit 6b479f3

Browse files
committed
Improve login support
1 parent 283c800 commit 6b479f3

File tree

5 files changed

+250
-165
lines changed

5 files changed

+250
-165
lines changed

src/eca/features/commands.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
:clear-history-after-finished? true
149149
:prompt (f.prompt/build-init-prompt db)}
150150
"login" (let [[msg error?] (if-let [provider (first args)]
151-
(let [{:keys [message error]} (f.login/start-login chat-id provider db*)]
151+
(let [{:keys [message error]} (f.login/start chat-id provider db*)]
152152
(if error
153153
[error true]
154154
[message]))

src/eca/features/login.clj

Lines changed: 47 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,57 @@
22
(:require
33
[clojure.string :as string]
44
[eca.db :as db]
5-
[eca.llm-providers.anthropic :as llm-providers.anthropic]
6-
[eca.llm-providers.copilot :as llm-providers.copilot]
75
[eca.messenger :as messenger]))
86

9-
(defn start-login [chat-id provider db*]
10-
(case provider
11-
"anthropic"
12-
(let [{:keys [verifier url]} (llm-providers.anthropic/oauth-url :console)]
13-
(swap! db* assoc-in [:chats chat-id :login-provider] provider)
14-
(swap! db* assoc-in [:auth provider] {:step :login/waiting-provider-code
15-
:verifier verifier})
16-
{:message (format "Open your browser at `%s` and authenticate at Anthropic.\nThen paste the code generated in the chat and send it to continue the authentication."
17-
url)})
18-
"github-copilot"
19-
(let [{:keys [user-code device-code url]} (llm-providers.copilot/oauth-url)]
20-
(swap! db* assoc-in [:chats chat-id :login-provider] provider)
21-
(swap! db* assoc-in [:auth provider] {:step :login/waiting-user-confirmation
22-
:device-code device-code})
23-
{:message (format "Open your browser at `%s` and authenticate using the code: `%s`\nThen type anything in the chat and send it to continue the authentication."
24-
url
25-
user-code)})
26-
{:message "Unknown provider-id"}))
7+
(defmulti login-step (fn [ctx] [(:provider ctx) (:step ctx)]))
8+
9+
(defmethod login-step :default [_] "Unkown provider-id")
10+
11+
(defn start [chat-id provider db*]
12+
(let [result (login-step {:chat-id chat-id
13+
:step :login/start
14+
:provider provider
15+
:db* db*})]
16+
result))
2717

2818
(defn continue [{:keys [message chat-id request-id]} db* messenger]
2919
(let [provider (get-in @db* [:chats chat-id :login-provider])
30-
step (get-in @db* [:auth provider :step])]
31-
(case step
32-
:login/waiting-provider-code
33-
(case provider
34-
"anthropic" (let [provider-code (string/trim message)
35-
{:keys [access-token refresh-token expires-at]} (llm-providers.anthropic/oauth-credentials provider-code (get-in @db* [:auth provider :verifier]))
36-
api-key (llm-providers.anthropic/create-api-key access-token)]
37-
(swap! db* update-in [:auth provider] merge {:step :login/done
38-
:access-token access-token
39-
:refresh-token refresh-token
40-
:api-token api-key
41-
:expires-at expires-at})
42-
(swap! db* update-in [:chats chat-id :status] :idle)
43-
(messenger/chat-content-received
44-
messenger
45-
{:chat-id chat-id
46-
:request-id request-id
47-
:role "system"
48-
:content {:type :text
49-
:text "Login successful! You can now use the 'anthropic' models."}})
50-
(messenger/chat-content-received
51-
messenger
52-
{:chat-id chat-id
53-
:request-id request-id
54-
:role "system"
55-
:content {:type :progress
56-
:state :finished}})))
57-
:login/waiting-user-confirmation
58-
(case provider
59-
"github-copilot" (let [access-token (llm-providers.copilot/oauth-access-token (get-in @db* [:auth provider :device-code]))
60-
{:keys [api-token expires-at]} (llm-providers.copilot/oauth-renew-token access-token)]
61-
(swap! db* update-in [:auth provider] merge {:step :login/done
62-
:access-token access-token
63-
:api-token api-token
64-
:expires-at expires-at})
65-
(swap! db* update-in [:chats chat-id :status] :idle)
66-
(messenger/chat-content-received
67-
messenger
68-
{:chat-id chat-id
69-
:request-id request-id
70-
:role "system"
71-
:content {:type :text
72-
:text "Login successful! You can now use the 'github-copilot' models."}})
73-
(messenger/chat-content-received
74-
messenger
75-
{:chat-id chat-id
76-
:request-id request-id
77-
:role "system"
78-
:content {:type :progress
79-
:state :finished}}))))
80-
(db/update-global-cache! @db*)))
20+
step (get-in @db* [:auth provider :step])
21+
input (string/trim message)
22+
ctx {:chat-id chat-id
23+
:step step
24+
:input input
25+
:db* db*
26+
:provider provider
27+
:send-msg! (fn [msg]
28+
(messenger/chat-content-received
29+
messenger
30+
{:chat-id chat-id
31+
:request-id request-id
32+
:role "system"
33+
:content {:type :text
34+
:text msg}})
35+
(messenger/chat-content-received
36+
messenger
37+
{:chat-id chat-id
38+
:request-id request-id
39+
:role "system"
40+
:content {:type :progress
41+
:state :finished}}))}]
42+
(messenger/chat-content-received
43+
messenger
44+
{:chat-id chat-id
45+
:request-id request-id
46+
:role "user"
47+
:content {:type :text
48+
:text (str input "\n")}})
49+
(login-step ctx)
50+
(db/update-global-cache! @db*)
51+
{:chat-id chat-id
52+
:status step}))
8153

8254
(defn renew-auth! [provider db*]
83-
(case provider
84-
"github-copilot"
85-
(let [access-token (get-in @db* [:auth provider :access-token])
86-
{:keys [api-token expires-at]} (llm-providers.copilot/oauth-renew-token access-token)]
87-
(swap! db* update-in [:auth provider] merge {:api-token api-token
88-
:expires-at expires-at}))))
55+
(login-step
56+
{:provider provider
57+
:step :login/renew-token
58+
:db* db*}))

src/eca/llm_api.clj

Lines changed: 64 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
(defn ^:private provider-api-key [provider provider-auth config]
3535
(or (get-in config [:providers (name provider) :key])
36-
(:api-token provider-auth)
36+
(:api-key provider-auth)
3737
(some-> (get-in config [:providers (name provider) :keyEnv]) config/get-env)))
3838

3939
(defn ^:private provider-api-url [provider config]
@@ -110,6 +110,7 @@
110110
extra-payload (:extraPayload model-config)
111111
provider-api-key (provider-api-key provider provider-auth config)
112112
provider-api-url (provider-api-url provider config)
113+
provider-auth-type (:type provider-auth)
113114
callbacks {:on-message-received on-message-received-wrapper
114115
:on-error on-error-wrapper
115116
:on-prepare-tool-call on-prepare-tool-call-wrapper
@@ -120,64 +121,65 @@
120121
(cond
121122
(= "openai" provider)
122123
(llm-providers.openai/completion!
123-
{:model model
124-
:instructions instructions
125-
:user-messages user-messages
126-
:max-output-tokens max-output-tokens
127-
:reason? reason?
128-
:past-messages past-messages
129-
:tools tools
130-
:web-search web-search
131-
:extra-payload extra-payload
132-
:api-url provider-api-url
133-
:api-key provider-api-key}
134-
callbacks)
124+
{:model model
125+
:instructions instructions
126+
:user-messages user-messages
127+
:max-output-tokens max-output-tokens
128+
:reason? reason?
129+
:past-messages past-messages
130+
:tools tools
131+
:web-search web-search
132+
:extra-payload extra-payload
133+
:api-url provider-api-url
134+
:api-key provider-api-key}
135+
callbacks)
135136

136137
(= "anthropic" provider)
137138
(llm-providers.anthropic/completion!
138-
{:model model
139-
:instructions instructions
140-
:user-messages user-messages
141-
:max-output-tokens max-output-tokens
142-
:reason? reason?
143-
:past-messages past-messages
144-
:tools tools
145-
:web-search web-search
146-
:extra-payload extra-payload
147-
:api-url provider-api-url
148-
:api-key provider-api-key}
149-
callbacks)
139+
{:model model
140+
:instructions instructions
141+
:user-messages user-messages
142+
:max-output-tokens max-output-tokens
143+
:reason? reason?
144+
:past-messages past-messages
145+
:tools tools
146+
:web-search web-search
147+
:extra-payload extra-payload
148+
:api-url provider-api-url
149+
:api-key provider-api-key
150+
:auth-type provider-auth-type}
151+
callbacks)
150152

151153
(= "github-copilot" provider)
152154
(llm-providers.openai-chat/completion!
153-
{:model model
154-
:instructions instructions
155-
:user-messages user-messages
156-
:max-output-tokens max-output-tokens
157-
:reason? reason?
158-
:past-messages past-messages
159-
:tools tools
160-
:extra-payload extra-payload
161-
:api-url provider-api-url
162-
:api-key provider-api-key
163-
:extra-headers {"openai-intent" "conversation-panel"
164-
"x-request-id" (str (random-uuid))
165-
"vscode-sessionid" ""
166-
"vscode-machineid" ""
167-
"copilot-integration-id" "vscode-chat"}}
168-
callbacks)
155+
{:model model
156+
:instructions instructions
157+
:user-messages user-messages
158+
:max-output-tokens max-output-tokens
159+
:reason? reason?
160+
:past-messages past-messages
161+
:tools tools
162+
:extra-payload extra-payload
163+
:api-url provider-api-url
164+
:api-key provider-api-key
165+
:extra-headers {"openai-intent" "conversation-panel"
166+
"x-request-id" (str (random-uuid))
167+
"vscode-sessionid" ""
168+
"vscode-machineid" ""
169+
"copilot-integration-id" "vscode-chat"}}
170+
callbacks)
169171

170172
(= "ollama" provider)
171173
(llm-providers.ollama/completion!
172-
{:api-url provider-api-url
173-
:reason? (:reason? model-capabilities)
174-
:model model
175-
:instructions instructions
176-
:user-messages user-messages
177-
:past-messages past-messages
178-
:tools tools
179-
:extra-payload extra-payload}
180-
callbacks)
174+
{:api-url provider-api-url
175+
:reason? (:reason? model-capabilities)
176+
:model model
177+
:instructions instructions
178+
:user-messages user-messages
179+
:past-messages past-messages
180+
:tools tools
181+
:extra-payload extra-payload}
182+
callbacks)
181183

182184
model-config
183185
(let [provider-fn (case (:api provider-config)
@@ -188,18 +190,18 @@
188190
(on-error-wrapper {:message (format "Unknown model %s for provider %s" (:api provider-config) provider)}))
189191
url-relative-path (:completionUrlRelativePath provider-config)]
190192
(provider-fn
191-
{:model model
192-
:instructions instructions
193-
:user-messages user-messages
194-
:max-output-tokens max-output-tokens
195-
:reason? reason?
196-
:past-messages past-messages
197-
:tools tools
198-
:extra-payload extra-payload
199-
:url-relative-path url-relative-path
200-
:api-url provider-api-url
201-
:api-key provider-api-key}
202-
callbacks))
193+
{:model model
194+
:instructions instructions
195+
:user-messages user-messages
196+
:max-output-tokens max-output-tokens
197+
:reason? reason?
198+
:past-messages past-messages
199+
:tools tools
200+
:extra-payload extra-payload
201+
:url-relative-path url-relative-path
202+
:api-url provider-api-url
203+
:api-key provider-api-key}
204+
callbacks))
203205

204206
:else
205207
(on-error-wrapper {:message (format "ECA Unsupported model %s for provider %s" model provider)}))

0 commit comments

Comments
 (0)