completion-kit 0.26.5 → 0.26.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/services/completion_kit/azure_foundry_client.rb +46 -12
- data/app/services/completion_kit/model_discovery_service.rb +36 -5
- data/app/views/completion_kit/provider_credentials/edit.html.erb +1 -1
- data/app/views/completion_kit/provider_credentials/new.html.erb +1 -1
- data/app/views/completion_kit/runs/show.html.erb +6 -0
- data/lib/completion_kit/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a1d7db0abdd990413e60ba5ef164580ef34485396f02598336ddca4e2ce39f4d
|
|
4
|
+
data.tar.gz: 7a8563ba729f30c7296fefd6aab9b3de6b6aee8c1b7823739ed96d545424f96c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e3b52c0043a89ae3fdf78735291fa4caffdd043c98f5ad35c99ea2d9969ba8c3b284ae50d24cde31f528e35cf4a51172b946d150116bc525e71fe02658528108
|
|
7
|
+
data.tar.gz: 946d48be8c7d204cc94d47f97cc0c71856199226e8602d3e94df293204d4cfe87dff50a70d2b71f672e0df0cf82dc7d061de4908ba2dd3599e87cc5640eb59e1
|
|
@@ -12,12 +12,21 @@ module CompletionKit
|
|
|
12
12
|
model = options[:model]
|
|
13
13
|
max_tokens = options[:max_tokens] || 1000
|
|
14
14
|
temperature = options[:temperature] || 0.7
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
max_completion = false
|
|
16
|
+
|
|
17
|
+
response = post_chat(model: model, prompt: prompt, max_tokens: max_tokens, temperature: temperature, max_completion: max_completion)
|
|
18
|
+
|
|
19
|
+
2.times do
|
|
20
|
+
break unless response.status == 400
|
|
21
|
+
if !max_completion && max_tokens_unsupported?(response.body)
|
|
22
|
+
max_completion = true
|
|
23
|
+
elsif !temperature.nil? && temperature_unsupported?(response.body)
|
|
24
|
+
@temperature_dropped = true
|
|
25
|
+
temperature = nil
|
|
26
|
+
else
|
|
27
|
+
break
|
|
28
|
+
end
|
|
29
|
+
response = post_chat(model: model, prompt: prompt, max_tokens: max_tokens, temperature: temperature, max_completion: max_completion)
|
|
21
30
|
end
|
|
22
31
|
|
|
23
32
|
if response.status == 429
|
|
@@ -49,12 +58,12 @@ module CompletionKit
|
|
|
49
58
|
return [] unless configured?
|
|
50
59
|
return [] unless ProviderEndpoint.safe?(api_endpoint)
|
|
51
60
|
|
|
52
|
-
response = build_connection(azure_base_url).get(
|
|
61
|
+
response = build_connection(azure_base_url).get(models_url) do |req|
|
|
53
62
|
req.headers["api-key"] = api_key
|
|
54
63
|
end
|
|
55
64
|
return [] unless response.success?
|
|
56
65
|
|
|
57
|
-
|
|
66
|
+
parse_models(response.body)
|
|
58
67
|
rescue StandardError
|
|
59
68
|
[]
|
|
60
69
|
end
|
|
@@ -92,13 +101,33 @@ module CompletionKit
|
|
|
92
101
|
api_version.blank?
|
|
93
102
|
end
|
|
94
103
|
|
|
95
|
-
def
|
|
96
|
-
|
|
104
|
+
def foundry_project?
|
|
105
|
+
api_endpoint.to_s.include?("/api/projects/")
|
|
97
106
|
end
|
|
98
107
|
|
|
99
|
-
def
|
|
100
|
-
|
|
108
|
+
def models_url
|
|
109
|
+
if foundry_project?
|
|
110
|
+
"#{azure_base_url}/deployments?api-version=v1"
|
|
111
|
+
elsif v1_mode?
|
|
112
|
+
"/openai/v1/models"
|
|
113
|
+
else
|
|
114
|
+
"/openai/deployments?api-version=#{api_version}"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def parse_models(body)
|
|
119
|
+
json = JSON.parse(body)
|
|
120
|
+
if foundry_project?
|
|
121
|
+
json.fetch("value", []).map { |d| { id: d["name"], name: d["name"] } }
|
|
122
|
+
else
|
|
123
|
+
json.fetch("data", []).map { |e| { id: e["id"], name: e["id"] } }
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def post_chat(model:, prompt:, max_tokens:, temperature:, max_completion: false)
|
|
128
|
+
body = { messages: [{ role: "user", content: prompt }] }
|
|
101
129
|
body[:model] = model if v1_mode?
|
|
130
|
+
body[max_completion ? :max_completion_tokens : :max_tokens] = max_tokens
|
|
102
131
|
body[:temperature] = temperature unless temperature.nil?
|
|
103
132
|
|
|
104
133
|
build_connection(azure_base_url, timeout: 30, open_timeout: 5).post do |req|
|
|
@@ -113,5 +142,10 @@ module CompletionKit
|
|
|
113
142
|
s = body.to_s
|
|
114
143
|
s.include?("temperature") && (s.include?("deprecated") || s.include?("not supported") || s.include?("Unsupported parameter"))
|
|
115
144
|
end
|
|
145
|
+
|
|
146
|
+
def max_tokens_unsupported?(body)
|
|
147
|
+
s = body.to_s
|
|
148
|
+
s.include?("max_tokens") && (s.include?("max_completion_tokens") || s.include?("not supported") || s.include?("Unsupported parameter"))
|
|
149
|
+
end
|
|
116
150
|
end
|
|
117
151
|
end
|
|
@@ -156,17 +156,26 @@ module CompletionKit
|
|
|
156
156
|
def fetch_azure_foundry_models
|
|
157
157
|
raise DiscoveryError, "An Azure endpoint URL is required." if @api_endpoint.blank?
|
|
158
158
|
|
|
159
|
-
response = fetch_connection(azure_base_url).get(azure_models_path) do |req|
|
|
159
|
+
response = fetch_connection(azure_base_url).get(azure_foundry_project? ? "#{azure_base_url}/deployments?api-version=v1" : azure_models_path) do |req|
|
|
160
160
|
req.headers["api-key"] = @api_key
|
|
161
161
|
end
|
|
162
162
|
raise DiscoveryError, azure_error_message(response) unless response.success?
|
|
163
|
-
JSON.parse(response.body)
|
|
163
|
+
body = JSON.parse(response.body)
|
|
164
|
+
if azure_foundry_project?
|
|
165
|
+
body.fetch("value", []).map { |d| { id: d["name"], display_name: d["name"] } }
|
|
166
|
+
else
|
|
167
|
+
body.fetch("data", []).map { |e| { id: e["id"], display_name: e["id"] } }
|
|
168
|
+
end
|
|
164
169
|
end
|
|
165
170
|
|
|
166
171
|
def azure_v1_mode?
|
|
167
172
|
@api_version.blank?
|
|
168
173
|
end
|
|
169
174
|
|
|
175
|
+
def azure_foundry_project?
|
|
176
|
+
@api_endpoint.to_s.include?("/api/projects/")
|
|
177
|
+
end
|
|
178
|
+
|
|
170
179
|
def azure_models_path
|
|
171
180
|
azure_v1_mode? ? "/openai/v1/models" : "/openai/deployments?api-version=#{@api_version}"
|
|
172
181
|
end
|
|
@@ -177,8 +186,16 @@ module CompletionKit
|
|
|
177
186
|
|
|
178
187
|
def azure_error_message(response)
|
|
179
188
|
detail = extract_provider_error_message(response.body)
|
|
180
|
-
|
|
181
|
-
|
|
189
|
+
if azure_foundry_project?
|
|
190
|
+
path = "/deployments"
|
|
191
|
+
hint = "Check the project endpoint URL."
|
|
192
|
+
elsif azure_v1_mode?
|
|
193
|
+
path = "/openai/v1/models"
|
|
194
|
+
hint = "Check the endpoint base URL."
|
|
195
|
+
else
|
|
196
|
+
path = "/openai/deployments"
|
|
197
|
+
hint = "Check the endpoint base URL and api-version."
|
|
198
|
+
end
|
|
182
199
|
with_detail("Azure did not return a model list at #{path} (#{response.status}). #{hint}", detail)
|
|
183
200
|
end
|
|
184
201
|
|
|
@@ -437,8 +454,17 @@ module CompletionKit
|
|
|
437
454
|
f.request :retry, max: 1, interval: 0.5
|
|
438
455
|
f.adapter Faraday.default_adapter
|
|
439
456
|
end
|
|
440
|
-
|
|
457
|
+
response = azure_probe_post(conn, model_id, input, max_tokens, max_completion: false)
|
|
458
|
+
if response.status == 400 && azure_max_tokens_unsupported?(response.body)
|
|
459
|
+
response = azure_probe_post(conn, model_id, input, max_tokens, max_completion: true)
|
|
460
|
+
end
|
|
461
|
+
response
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
def azure_probe_post(conn, model_id, input, max_tokens, max_completion:)
|
|
465
|
+
body = { messages: [{ role: "user", content: input }] }
|
|
441
466
|
body[:model] = model_id if azure_v1_mode?
|
|
467
|
+
body[max_completion ? :max_completion_tokens : :max_tokens] = max_tokens
|
|
442
468
|
conn.post do |req|
|
|
443
469
|
req.url(azure_v1_mode? ? "/openai/v1/chat/completions" : "/openai/deployments/#{model_id}/chat/completions?api-version=#{@api_version}")
|
|
444
470
|
req.headers["Content-Type"] = "application/json"
|
|
@@ -446,5 +472,10 @@ module CompletionKit
|
|
|
446
472
|
req.body = body.to_json
|
|
447
473
|
end
|
|
448
474
|
end
|
|
475
|
+
|
|
476
|
+
def azure_max_tokens_unsupported?(body)
|
|
477
|
+
s = body.to_s
|
|
478
|
+
s.include?("max_tokens") && (s.include?("max_completion_tokens") || s.include?("not supported") || s.include?("Unsupported parameter"))
|
|
479
|
+
end
|
|
449
480
|
end
|
|
450
481
|
end
|
|
@@ -64,6 +64,12 @@
|
|
|
64
64
|
<span class="ck-run-config__none">None</span>
|
|
65
65
|
<% end %>
|
|
66
66
|
</div>
|
|
67
|
+
<% if @run.prompt&.llm_model.present? %>
|
|
68
|
+
<div class="ck-run-config__row">
|
|
69
|
+
<span class="ck-run-config__key">Model</span>
|
|
70
|
+
<span style="text-transform: none;"><%= @run.prompt.llm_model %></span>
|
|
71
|
+
</div>
|
|
72
|
+
<% end %>
|
|
67
73
|
<% if @run.judge_model.present? %>
|
|
68
74
|
<div class="ck-run-config__row">
|
|
69
75
|
<span class="ck-run-config__key">Judge</span>
|