cloudflare-ai 0.5.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -6
- data/lib/cloudflare/ai/client.rb +23 -3
- data/lib/cloudflare/ai/clients/image_helpers.rb +20 -0
- data/lib/cloudflare/ai/models.rb +1 -1
- data/lib/cloudflare/ai/result.rb +1 -1
- data/lib/cloudflare/ai/results/image_classification.rb +3 -0
- data/lib/cloudflare/ai/results/text_to_image.rb +5 -0
- data/lib/cloudflare/ai/version.rb +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f16a1fd5c112fb69440d4d89b1f27d167e854c537ca952b91e1f3f673c0efb5
|
4
|
+
data.tar.gz: 59f999e994f5bd21071ee2f125b5e138ba353feb857912b1df472f35acc05006
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d258b49887ca664f616aad4dbc74afc4bb8d49d0452933c2ee907306af56cf81da0bf084c260ddbe4db9d96f522812cc5abfb771c3d94757f12342334b16fd6
|
7
|
+
data.tar.gz: 133fcfd21cedbdb324604ec0e9bd4aacb0750b9f486df7bc217998e4dd117f4e6d482572ba1feee8b629e3362857cb8b8f28d2f1e3c6f1d89acddd18b73752e9
|
data/README.md
CHANGED
@@ -23,8 +23,8 @@ It's still early days, and here are my immediate priorities:
|
|
23
23
|
* [x] [Text Embeddings](https://developers.cloudflare.com/workers-ai/models/text-embeddings/)
|
24
24
|
* [x] [Text Classification](https://developers.cloudflare.com/workers-ai/models/text-classification/)
|
25
25
|
* [x] [Translation](https://developers.cloudflare.com/workers-ai/models/translation/)
|
26
|
-
* [
|
27
|
-
* [
|
26
|
+
* [x] [Image Classification](https://developers.cloudflare.com/workers-ai/models/image-classification/)
|
27
|
+
* [x] [Text-to-Image](https://developers.cloudflare.com/workers-ai/models/text-to-image/)
|
28
28
|
* [ ] [Automatic Speech Recognition](https://developers.cloudflare.com/workers-ai/models/speech-recognition/)
|
29
29
|
|
30
30
|
# Table of Contents
|
@@ -75,7 +75,8 @@ The full list of supported models is available here: [models.rb](lib/cloudflare/
|
|
75
75
|
More information is available [in the cloudflare documentation](https://developers.cloudflare.com/workers-ai/models/).
|
76
76
|
The default model used is the first enumerated model in the applicable set in [models.rb](lib/cloudflare/ai/models.rb).
|
77
77
|
|
78
|
-
### Text generation
|
78
|
+
### Text generation
|
79
|
+
#### (chat / scoped prompt)
|
79
80
|
```ruby
|
80
81
|
messages = [
|
81
82
|
Cloudflare::AI::Message.new(role: "system", content: "You are a big fan of Cloudflare and Ruby."),
|
@@ -86,6 +87,11 @@ messages = [
|
|
86
87
|
result = client.chat(messages: messages)
|
87
88
|
puts result.response # => "Yes, I love Cloudflare!"
|
88
89
|
```
|
90
|
+
#### (string prompt)
|
91
|
+
```ruby
|
92
|
+
result = client.complete(prompt: "What is your name?", max_tokens: 512)
|
93
|
+
puts result.response # => "My name is Jonas."
|
94
|
+
```
|
89
95
|
|
90
96
|
#### Streaming responses
|
91
97
|
Responses will be streamed back to the client using Server Side Events (SSE) if a block is passed to the `chat` or `complete` method.
|
@@ -101,9 +107,6 @@ result = client.complete(prompt: "Hi!") { |data| puts data}
|
|
101
107
|
```
|
102
108
|
#### Token limits
|
103
109
|
Invocations of the `prompt` and `chat` can take an optional `max_tokens` argument that defaults to 256.
|
104
|
-
```ruby
|
105
|
-
result = client.complete(prompt: "What is your name?", max_tokens: 512)
|
106
|
-
```
|
107
110
|
|
108
111
|
#### Result object
|
109
112
|
All invocations of the `prompt` and `chat` methods return a `Cloudflare::AI::Results::TextGeneration` object. This object's serializable JSON output is
|
@@ -149,6 +152,29 @@ p result.result # => [{"label"=>"NEGATIVE", "score"=>0.6647962927818298}, {"labe
|
|
149
152
|
#### Result object
|
150
153
|
All invocations of the `classify` methods return a `Cloudflare::AI::Results::TextClassification`.
|
151
154
|
|
155
|
+
### Image classification
|
156
|
+
The image classification endpoint accepts either a path to a file or a file stream.
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
result = client.classify(image: "/path/to/cat.jpg")
|
160
|
+
p result.result # => {"result":[{"label":"TABBY","score":0.6159140467643738},{"label":"TIGER CAT","score":0.12016300112009048},{"label":"EGYPTIAN CAT","score":0.07523812353610992},{"label":"DOORMAT","score":0.018854796886444092},{"label":"ASHCAN","score":0.01314085815101862}],"success":true,"errors":[],"messages":[]}
|
161
|
+
|
162
|
+
result = client.classify(image: File.open("/path/to/cat.jpg"))
|
163
|
+
p result.result # => {"result":[{"label":"TABBY","score":0.6159140467643738},{"label":"TIGER CAT","score":0.12016300112009048},{"label":"EGYPTIAN CAT","score":0.07523812353610992},{"label":"DOORMAT","score":0.018854796886444092},{"label":"ASHCAN","score":0.01314085815101862}],"success":true,"errors":[],"messages":[]}
|
164
|
+
```
|
165
|
+
|
166
|
+
#### Result object
|
167
|
+
All invocations of the `classify` method returns a `Cloudflare::AI::Results::TextClassification`.
|
168
|
+
|
169
|
+
### Text to Image
|
170
|
+
```ruby
|
171
|
+
result = client.draw(prompt: "robot with blue eyes")
|
172
|
+
p result.result # => File:0x0000000110deed68 (png tempfile)
|
173
|
+
```
|
174
|
+
|
175
|
+
#### Result object
|
176
|
+
All invocations of the `draw` method returns a `Cloudflare::AI::Results::TextToImage`.
|
177
|
+
|
152
178
|
### Translation
|
153
179
|
```ruby
|
154
180
|
result = client.translate(text: "Hello Jello", source_lang: "en", target_lang: "fr")
|
data/lib/cloudflare/ai/client.rb
CHANGED
@@ -2,6 +2,7 @@ require "event_stream_parser"
|
|
2
2
|
require "faraday"
|
3
3
|
|
4
4
|
class Cloudflare::AI::Client
|
5
|
+
include Cloudflare::AI::Clients::ImageHelpers
|
5
6
|
include Cloudflare::AI::Clients::TextGenerationHelpers
|
6
7
|
|
7
8
|
attr_reader :url, :account_id, :api_token
|
@@ -18,11 +19,19 @@ class Cloudflare::AI::Client
|
|
18
19
|
post_streamable_request(url, payload, &block)
|
19
20
|
end
|
20
21
|
|
21
|
-
def classify(text
|
22
|
+
def classify(text: nil, image: nil, model_name: nil)
|
23
|
+
raise ArgumentError, "Must provide either text or image (and not both)" if [text, image].compact.size != 1
|
24
|
+
|
25
|
+
model_name ||= text ? Cloudflare::AI::Models.text_classification.first : Cloudflare::AI::Models.image_classification.first
|
22
26
|
url = service_url_for(account_id: account_id, model_name: model_name)
|
23
|
-
payload = {text: text}.to_json
|
24
27
|
|
25
|
-
|
28
|
+
if text
|
29
|
+
payload = {text: text}.to_json
|
30
|
+
Cloudflare::AI::Results::TextClassification.new(connection.post(url, payload).body)
|
31
|
+
else
|
32
|
+
image = File.open(image) if image.is_a?(String)
|
33
|
+
Cloudflare::AI::Results::ImageClassification.new(post_request_with_binary_file(url, image).body)
|
34
|
+
end
|
26
35
|
end
|
27
36
|
|
28
37
|
def complete(prompt:, model_name: default_text_generation_model_name, max_tokens: default_max_tokens, &block)
|
@@ -32,6 +41,17 @@ class Cloudflare::AI::Client
|
|
32
41
|
post_streamable_request(url, payload, &block)
|
33
42
|
end
|
34
43
|
|
44
|
+
def draw(prompt:, num_steps: 20, model_name: Cloudflare::AI::Models.text_to_image.first)
|
45
|
+
url = service_url_for(account_id: account_id, model_name: model_name)
|
46
|
+
payload = {prompt: prompt, num_steps: num_steps}.to_json
|
47
|
+
|
48
|
+
result = connection.post(url, payload).body
|
49
|
+
binary_data = result.split(",").map(&:to_i).pack("C*")
|
50
|
+
Cloudflare::AI::Results::TextToImage.new(
|
51
|
+
Tempfile.new(["cloudflare-ai", ".png"], binmode: true).tap { |result| result.write(binary_data) }
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
35
55
|
def embed(text:, model_name: Cloudflare::AI::Models.text_embedding.first)
|
36
56
|
url = service_url_for(account_id: account_id, model_name: model_name)
|
37
57
|
payload = {text: text}.to_json
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "faraday/multipart"
|
2
|
+
|
3
|
+
module Cloudflare
|
4
|
+
module AI
|
5
|
+
module Clients
|
6
|
+
module ImageHelpers
|
7
|
+
private
|
8
|
+
|
9
|
+
def post_request_with_binary_file(url, file)
|
10
|
+
connection.post do |req|
|
11
|
+
req.url url
|
12
|
+
req.headers["Transfer-Encoding"] = "chunked"
|
13
|
+
req.headers["Content-Type"] = "multipart/form-data"
|
14
|
+
req.body = ::Faraday::UploadIO.new(file, "octet/stream")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/cloudflare/ai/models.rb
CHANGED
data/lib/cloudflare/ai/result.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudflare-ai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ajay Krishnan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: faraday-multipart
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: zeitwerk
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,14 +107,17 @@ files:
|
|
93
107
|
- README.md
|
94
108
|
- lib/cloudflare/ai.rb
|
95
109
|
- lib/cloudflare/ai/client.rb
|
110
|
+
- lib/cloudflare/ai/clients/image_helpers.rb
|
96
111
|
- lib/cloudflare/ai/clients/text_generation_helpers.rb
|
97
112
|
- lib/cloudflare/ai/contextual_logger.rb
|
98
113
|
- lib/cloudflare/ai/message.rb
|
99
114
|
- lib/cloudflare/ai/models.rb
|
100
115
|
- lib/cloudflare/ai/result.rb
|
116
|
+
- lib/cloudflare/ai/results/image_classification.rb
|
101
117
|
- lib/cloudflare/ai/results/text_classification.rb
|
102
118
|
- lib/cloudflare/ai/results/text_embedding.rb
|
103
119
|
- lib/cloudflare/ai/results/text_generation.rb
|
120
|
+
- lib/cloudflare/ai/results/text_to_image.rb
|
104
121
|
- lib/cloudflare/ai/results/translation.rb
|
105
122
|
- lib/cloudflare/ai/version.rb
|
106
123
|
homepage: https://rubygems.org/gems/cloudflare-ai
|