bandcamp-discover 0.7.0 → 0.7.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/Gemfile.lock +1 -1
- data/lib/bandcamp-discover/analyzer.rb +17 -1
- data/lib/bandcamp-discover/version.rb +1 -1
- data/test/analyzer_test.rb +28 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '094dffa15caad4bbabef29bd4b3d87789425e4736c2d06461d6917efc8fe600d'
|
|
4
|
+
data.tar.gz: de1a1d20425f1ecb984878b10541208849abbf7300cd46f80834e5197730ef1c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a6a057d4869da1039b00b9c2ffd5b4019123c4ee055cf392fd3fefc4b8fa7f427d2346081554e960a5416c95b52d507d9244912112dada5d0ddedec06820ac33
|
|
7
|
+
data.tar.gz: ae37374ebc23a193aedaed32cd741f01af048502cb9853596d6e9bf1438ec2040fcacdaee67f226951accf6bd9d674191faf8667f5bf86cc3b9216d84a408bbc
|
data/Gemfile.lock
CHANGED
|
@@ -3,6 +3,10 @@ require_relative "configuration"
|
|
|
3
3
|
|
|
4
4
|
module BandcampDiscover
|
|
5
5
|
class Analyzer
|
|
6
|
+
# The model replied, but not with the object asked for. Carries the reply so
|
|
7
|
+
# a failed job says what was said instead of where JSON.parse gave up.
|
|
8
|
+
class NoAnswer < StandardError; end
|
|
9
|
+
|
|
6
10
|
# A per-call model still wins over the configured one so existing callers
|
|
7
11
|
# keep their behaviour.
|
|
8
12
|
def initialize(description, model = nil, credits: [])
|
|
@@ -17,10 +21,14 @@ module BandcampDiscover
|
|
|
17
21
|
@description.to_s.match?(/label|platform|records/i)
|
|
18
22
|
end
|
|
19
23
|
|
|
24
|
+
# The prompt says to default to false; a reply that never reached an answer
|
|
25
|
+
# is that default, not a reason to lose the whole scrape.
|
|
20
26
|
def accepts_demos?
|
|
21
27
|
return false unless llm?
|
|
22
28
|
|
|
23
29
|
ask(BandcampDiscover.configuration.demos_prompt)
|
|
30
|
+
rescue NoAnswer
|
|
31
|
+
false
|
|
24
32
|
end
|
|
25
33
|
|
|
26
34
|
private
|
|
@@ -43,7 +51,15 @@ module BandcampDiscover
|
|
|
43
51
|
extras: {response_format: {type: "json_object"}}
|
|
44
52
|
)
|
|
45
53
|
|
|
46
|
-
|
|
54
|
+
answer(response["choices"][0]["message"]["content"])["answer"]&.to_s&.downcase == "true"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# response_format is advisory on OpenRouter: Anthropic models return the
|
|
58
|
+
# object inside a ```json fence, and some prepend a sentence.
|
|
59
|
+
def answer(content)
|
|
60
|
+
JSON.parse(content[/\{.*\}/m] || content)
|
|
61
|
+
rescue JSON::ParserError
|
|
62
|
+
raise NoAnswer, "model replied without a JSON object: #{content.to_s.strip[0, 200].inspect}"
|
|
47
63
|
end
|
|
48
64
|
|
|
49
65
|
# The bio alone cannot tell one person releasing under aliases from a
|
data/test/analyzer_test.rb
CHANGED
|
@@ -23,12 +23,12 @@ module OpenRouter
|
|
|
23
23
|
|
|
24
24
|
class Client
|
|
25
25
|
class << self
|
|
26
|
-
attr_accessor :requests, :answer
|
|
26
|
+
attr_accessor :requests, :answer, :raw
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def complete(messages, model:, extras:)
|
|
30
30
|
self.class.requests << {messages: messages, model: model, extras: extras}
|
|
31
|
-
{"choices" => [{"message" => {"content" => JSON.generate("answer" => self.class.answer)}}]}
|
|
31
|
+
{"choices" => [{"message" => {"content" => self.class.raw || JSON.generate("answer" => self.class.answer)}}]}
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
end
|
|
@@ -41,6 +41,7 @@ class AnalyzerTest < Minitest::Test
|
|
|
41
41
|
OpenRouter.configuration.access_token = "token"
|
|
42
42
|
OpenRouter::Client.requests = []
|
|
43
43
|
OpenRouter::Client.answer = true
|
|
44
|
+
OpenRouter::Client.raw = nil
|
|
44
45
|
end
|
|
45
46
|
|
|
46
47
|
def teardown
|
|
@@ -99,6 +100,31 @@ class AnalyzerTest < Minitest::Test
|
|
|
99
100
|
assert_equal "", OpenRouter::Client.requests.last[:messages].last[:content]
|
|
100
101
|
end
|
|
101
102
|
|
|
103
|
+
def test_reads_the_answer_out_of_a_markdown_fence
|
|
104
|
+
OpenRouter::Client.raw = "```json\n{\"answer\": false}\n```"
|
|
105
|
+
|
|
106
|
+
refute Analyzer.new("bio").label?
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_reads_the_answer_out_of_surrounding_prose
|
|
110
|
+
OpenRouter::Client.raw = "Sure. {\"answer\": true} Hope that helps."
|
|
111
|
+
|
|
112
|
+
assert Analyzer.new("bio").label?
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_label_raises_a_named_error_carrying_a_reply_without_an_object
|
|
116
|
+
OpenRouter::Client.raw = "I don't see enough information to decide."
|
|
117
|
+
|
|
118
|
+
error = assert_raises(BandcampDiscover::Analyzer::NoAnswer) { Analyzer.new("bio").label? }
|
|
119
|
+
assert_includes error.message, "I don't see enough information"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def test_demos_defaults_to_false_on_a_reply_without_an_object
|
|
123
|
+
OpenRouter::Client.raw = "I don't see any mention of demos here."
|
|
124
|
+
|
|
125
|
+
refute Analyzer.new("bio").accepts_demos?
|
|
126
|
+
end
|
|
127
|
+
|
|
102
128
|
def test_parses_the_answer
|
|
103
129
|
OpenRouter::Client.answer = false
|
|
104
130
|
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bandcamp-discover
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Julian RUbisch
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-09-
|
|
10
|
+
date: 2026-09-04 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rake
|