slidict 0.4.1 → 0.4.2
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/lib/slidict/cli/app.rb +18 -1
- data/lib/slidict/cli/lint.rb +16 -1
- data/lib/slidict/config.rb +2 -2
- data/lib/slidict/llm/client.rb +18 -5
- data/lib/slidict/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: 829a5806efaa7c29d773818f0683fa3c0525bebfe883bd32261ba29f5a649a5e
|
|
4
|
+
data.tar.gz: e45e42541ba0940a883f470f7d03941df71b5825c0c9b93471fe3b1c991b0de5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ff04a4475b51083d1c8ed884ad10f924000bb6c47adb0947d6c365fa3dd81d83eb09b94b280794bed9d2ef1001b559589c9241d92b0ccc005a7969065a814eb1
|
|
7
|
+
data.tar.gz: a0385b86027802eb018c4c9bda5fc26ee8030df9eee449879bd5dc299faa32382df90e5b8c707b528c846018d1fa8f28b3861ce299ed8d58f7d5ad125bc29b15
|
data/lib/slidict/cli/app.rb
CHANGED
|
@@ -28,6 +28,8 @@ module Slidict
|
|
|
28
28
|
return lint(options[:args]) if options[:command] == "lint"
|
|
29
29
|
|
|
30
30
|
config = build_config(options)
|
|
31
|
+
return print_available_models(config) if config.llm_enabled? && config.model.nil?
|
|
32
|
+
|
|
31
33
|
client = llm_client_for(config)
|
|
32
34
|
return 1 if client && !verify_connection(client)
|
|
33
35
|
|
|
@@ -155,6 +157,21 @@ module Slidict
|
|
|
155
157
|
)
|
|
156
158
|
end
|
|
157
159
|
|
|
160
|
+
def print_available_models(config)
|
|
161
|
+
client = Llm::Client.new(base_url: config.base_url, api_key: config.api_key, model: nil)
|
|
162
|
+
models = client.list_models
|
|
163
|
+
if models.empty?
|
|
164
|
+
@output.puts "No models available at #{config.base_url}"
|
|
165
|
+
else
|
|
166
|
+
@output.puts "Available models (specify one with --llm-model NAME or SLIDICT_LLM_MODEL=NAME):"
|
|
167
|
+
models.each { |m| @output.puts " #{m}" }
|
|
168
|
+
end
|
|
169
|
+
0
|
|
170
|
+
rescue Llm::Client::Error => e
|
|
171
|
+
@output.puts "Error: LLM request failed (#{e.message})"
|
|
172
|
+
1
|
|
173
|
+
end
|
|
174
|
+
|
|
158
175
|
def llm_client_for(config)
|
|
159
176
|
return nil unless config.llm_enabled?
|
|
160
177
|
|
|
@@ -284,7 +301,7 @@ module Slidict
|
|
|
284
301
|
--llm-base-url URL OpenAI Compatible API base URL (env: SLIDICT_LLM_BASE_URL).
|
|
285
302
|
When omitted, the built-in slide template is used instead.
|
|
286
303
|
--llm-api-key KEY API key for the LLM endpoint (env: SLIDICT_LLM_API_KEY)
|
|
287
|
-
--llm-model NAME Model name to request (env: SLIDICT_LLM_MODEL
|
|
304
|
+
--llm-model NAME Model name to request (env: SLIDICT_LLM_MODEL); omit to list available models
|
|
288
305
|
--no-llm Skip the LLM call and use the built-in slide template
|
|
289
306
|
--publish Publish the generated slides to slidict.io as a draft
|
|
290
307
|
(requires `slidict auth`; creates a new slide, or edits
|
data/lib/slidict/cli/lint.rb
CHANGED
|
@@ -31,6 +31,7 @@ module Slidict
|
|
|
31
31
|
def run_lint(options)
|
|
32
32
|
config = build_config(options)
|
|
33
33
|
return llm_required unless config.llm_enabled?
|
|
34
|
+
return print_available_models(config) if config.model.nil?
|
|
34
35
|
|
|
35
36
|
print_findings(lint(options, config))
|
|
36
37
|
end
|
|
@@ -112,6 +113,20 @@ module Slidict
|
|
|
112
113
|
1
|
|
113
114
|
end
|
|
114
115
|
|
|
116
|
+
def print_available_models(config)
|
|
117
|
+
client = Llm::Client.new(base_url: config.base_url, api_key: config.api_key, model: nil)
|
|
118
|
+
models = client.list_models
|
|
119
|
+
if models.empty?
|
|
120
|
+
@output.puts "No models available at #{config.base_url}"
|
|
121
|
+
else
|
|
122
|
+
@output.puts "Available models (specify one with --llm-model NAME or SLIDICT_LLM_MODEL=NAME):"
|
|
123
|
+
models.each { |m| @output.puts " #{m}" }
|
|
124
|
+
end
|
|
125
|
+
0
|
|
126
|
+
rescue Llm::Client::Error => e
|
|
127
|
+
print_error(e)
|
|
128
|
+
end
|
|
129
|
+
|
|
115
130
|
def llm_required
|
|
116
131
|
@output.puts "Error: lint requires an LLM endpoint (--llm-base-url or SLIDICT_LLM_BASE_URL)"
|
|
117
132
|
1
|
|
@@ -124,7 +139,7 @@ module Slidict
|
|
|
124
139
|
--format FORMAT markdown or asciidoc (default: auto-detected from extension)
|
|
125
140
|
--llm-base-url URL OpenAI Compatible API base URL (env: SLIDICT_LLM_BASE_URL)
|
|
126
141
|
--llm-api-key KEY API key for the LLM endpoint (env: SLIDICT_LLM_API_KEY)
|
|
127
|
-
--llm-model NAME Model name to request (env: SLIDICT_LLM_MODEL
|
|
142
|
+
--llm-model NAME Model name to request (env: SLIDICT_LLM_MODEL); omit to list available models
|
|
128
143
|
--translate LANG Translate findings into the given language (e.g. Japanese)
|
|
129
144
|
-h, --help Show this help
|
|
130
145
|
HELP
|
data/lib/slidict/config.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Slidict
|
|
|
6
6
|
|
|
7
7
|
attr_reader :base_url, :api_key, :model
|
|
8
8
|
|
|
9
|
-
def initialize(base_url: nil, api_key: nil, model:
|
|
9
|
+
def initialize(base_url: nil, api_key: nil, model: nil, enabled: true)
|
|
10
10
|
@base_url = base_url
|
|
11
11
|
@api_key = api_key
|
|
12
12
|
@model = model
|
|
@@ -17,7 +17,7 @@ module Slidict
|
|
|
17
17
|
new(
|
|
18
18
|
base_url: env["SLIDICT_LLM_BASE_URL"],
|
|
19
19
|
api_key: env["SLIDICT_LLM_API_KEY"],
|
|
20
|
-
model: env["SLIDICT_LLM_MODEL"]
|
|
20
|
+
model: env["SLIDICT_LLM_MODEL"]
|
|
21
21
|
)
|
|
22
22
|
end
|
|
23
23
|
|
data/lib/slidict/llm/client.rb
CHANGED
|
@@ -21,12 +21,18 @@ module Slidict
|
|
|
21
21
|
# Checks that the endpoint is reachable before the (slower, more
|
|
22
22
|
# expensive) chat completion request is made. Raises Error on failure.
|
|
23
23
|
def verify_connection!
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
response = perform_request(uri, request)
|
|
24
|
+
response = get_models_response
|
|
25
|
+
raise Error, "#{response.code} #{response.message}" unless response.is_a?(Net::HTTPSuccess)
|
|
26
|
+
end
|
|
28
27
|
|
|
28
|
+
# Returns a sorted array of model IDs available at the endpoint.
|
|
29
|
+
def list_models
|
|
30
|
+
response = get_models_response
|
|
29
31
|
raise Error, "#{response.code} #{response.message}" unless response.is_a?(Net::HTTPSuccess)
|
|
32
|
+
|
|
33
|
+
Array(JSON.parse(response.body)["data"]).map { |m| m["id"] }.sort
|
|
34
|
+
rescue JSON::ParserError => e
|
|
35
|
+
raise Error, "could not parse models response: #{e.message}"
|
|
30
36
|
end
|
|
31
37
|
|
|
32
38
|
def generate_slides(deck)
|
|
@@ -44,6 +50,13 @@ module Slidict
|
|
|
44
50
|
|
|
45
51
|
private
|
|
46
52
|
|
|
53
|
+
def get_models_response
|
|
54
|
+
uri = endpoint_uri("models")
|
|
55
|
+
request = Net::HTTP::Get.new(uri)
|
|
56
|
+
request["Authorization"] = "Bearer #{@api_key}"
|
|
57
|
+
perform_request(uri, request)
|
|
58
|
+
end
|
|
59
|
+
|
|
47
60
|
def prompt_for(deck)
|
|
48
61
|
<<~PROMPT
|
|
49
62
|
You are an assistant that designs presentation slide outlines.
|
|
@@ -191,7 +204,7 @@ module Slidict
|
|
|
191
204
|
return candidate if candidate
|
|
192
205
|
end
|
|
193
206
|
|
|
194
|
-
raise Error, "no JSON array found in model response"
|
|
207
|
+
raise Error, "no JSON array found in model response\nThe model may be too small to follow the required output format. Try using a larger model."
|
|
195
208
|
end
|
|
196
209
|
|
|
197
210
|
def json_array_from(content, start)
|
data/lib/slidict/version.rb
CHANGED