cohere-ai 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/cohere-ai.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'static/gem'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = Cohere::GEM[:name]
7
+ spec.version = Cohere::GEM[:version]
8
+ spec.authors = [Cohere::GEM[:author]]
9
+
10
+ spec.summary = Cohere::GEM[:summary]
11
+ spec.description = Cohere::GEM[:description]
12
+
13
+ spec.homepage = Cohere::GEM[:github]
14
+
15
+ spec.license = Cohere::GEM[:license]
16
+
17
+ spec.required_ruby_version = Gem::Requirement.new(">= #{Cohere::GEM[:ruby]}")
18
+
19
+ spec.metadata['allowed_push_host'] = Cohere::GEM[:gem_server]
20
+
21
+ spec.metadata['homepage_uri'] = spec.homepage
22
+ spec.metadata['source_code_uri'] = Cohere::GEM[:github]
23
+
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{\A(?:test|spec|features)/})
27
+ end
28
+ end
29
+
30
+ spec.require_paths = ['ports/dsl']
31
+
32
+ spec.add_dependency 'faraday', '~> 2.8', '>= 2.8.1'
33
+
34
+ spec.metadata['rubygems_mfa_required'] = 'true'
35
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cohere
4
+ module Errors
5
+ class CohereError < StandardError
6
+ def initialize(message = nil)
7
+ super(message)
8
+ end
9
+ end
10
+
11
+ class MissingAPIKeyError < CohereError; end
12
+ class BlockWithoutServerSentEventsError < CohereError; end
13
+
14
+ class RequestError < CohereError
15
+ attr_reader :request, :payload
16
+
17
+ def initialize(message = nil, request: nil, payload: nil)
18
+ @request = request
19
+ @payload = payload
20
+
21
+ super(message)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'json'
5
+
6
+ require_relative '../ports/dsl/cohere-ai/errors'
7
+
8
+ module Cohere
9
+ module Controllers
10
+ class Client
11
+ DEFAULT_ADDRESS = 'https://api.cohere.ai'
12
+
13
+ ALLOWED_REQUEST_OPTIONS = %i[timeout open_timeout read_timeout write_timeout].freeze
14
+
15
+ def initialize(config)
16
+ @api_key = config.dig(:credentials, :api_key)
17
+ @server_sent_events = config.dig(:options, :server_sent_events)
18
+
19
+ @address = if config[:credentials][:address].nil? || config[:credentials][:address].to_s.strip.empty?
20
+ "#{DEFAULT_ADDRESS}/"
21
+ else
22
+ "#{config[:credentials][:address].to_s.sub(%r{/$}, '')}/"
23
+ end
24
+
25
+ if @api_key.nil? && @address == "#{DEFAULT_ADDRESS}/"
26
+ raise MissingAPIKeyError, 'Missing API Key, which is required.'
27
+ end
28
+
29
+ @request_options = config.dig(:options, :connection, :request)
30
+
31
+ @request_options = if @request_options.is_a?(Hash)
32
+ @request_options.select do |key, _|
33
+ ALLOWED_REQUEST_OPTIONS.include?(key)
34
+ end
35
+ else
36
+ {}
37
+ end
38
+ end
39
+
40
+ def chat(payload, server_sent_events: nil, &callback)
41
+ server_sent_events = false if payload[:stream] != true
42
+ request('v1/chat', payload, server_sent_events:, &callback)
43
+ end
44
+
45
+ def generate(payload, server_sent_events: nil, &callback)
46
+ server_sent_events = false if payload[:stream] != true
47
+ request('v1/generate', payload, server_sent_events:, &callback)
48
+ end
49
+
50
+ def embed(payload, _server_sent_events: nil, &callback)
51
+ request('v1/embed', payload, server_sent_events: false, &callback)
52
+ end
53
+
54
+ def rerank(payload, _server_sent_events: nil, &callback)
55
+ request('v1/rerank', payload, server_sent_events: false, &callback)
56
+ end
57
+
58
+ def classify(payload, _server_sent_events: nil, &callback)
59
+ request('v1/classify', payload, server_sent_events: false, &callback)
60
+ end
61
+
62
+ def detect_language(payload, _server_sent_events: nil, &callback)
63
+ request('v1/detect-language', payload, server_sent_events: false, &callback)
64
+ end
65
+
66
+ def summarize(payload, _server_sent_events: nil, &callback)
67
+ request('v1/summarize', payload, server_sent_events: false, &callback)
68
+ end
69
+
70
+ def tokenize(payload, _server_sent_events: nil, &callback)
71
+ request('v1/tokenize', payload, server_sent_events: false, &callback)
72
+ end
73
+
74
+ def detokenize(payload, _server_sent_events: nil, &callback)
75
+ request('v1/detokenize', payload, server_sent_events: false, &callback)
76
+ end
77
+
78
+ def request(path, payload = nil, server_sent_events: nil, request_method: 'POST', &callback)
79
+ server_sent_events_enabled = server_sent_events.nil? ? @server_sent_events : server_sent_events
80
+ url = "#{@address}#{path}"
81
+
82
+ if !callback.nil? && !server_sent_events_enabled
83
+ raise BlockWithoutServerSentEventsError,
84
+ 'You are trying to use a block without Server Sent Events (SSE) enabled.'
85
+ end
86
+
87
+ results = []
88
+
89
+ method_to_call = request_method.to_s.strip.downcase.to_sym
90
+
91
+ response = Faraday.new(request: @request_options) do |faraday|
92
+ faraday.response :raise_error
93
+ end.send(method_to_call) do |request|
94
+ request.url url
95
+ request.headers['Content-Type'] = 'application/json'
96
+
97
+ request.headers['Authorization'] = "Bearer #{@api_key}" unless @api_key.nil?
98
+
99
+ request.body = payload.to_json unless payload.nil?
100
+
101
+ if server_sent_events_enabled
102
+ request.options.on_data = proc do |chunk, bytes, env|
103
+ if env && env.status != 200
104
+ raise_error = Faraday::Response::RaiseError.new
105
+ raise_error.on_complete(env.merge(body: chunk))
106
+ end
107
+
108
+ result = { event: safe_parse_json(chunk), raw: { chunk:, bytes:, env: } }
109
+
110
+ callback.call(result[:event], result[:raw]) unless callback.nil?
111
+
112
+ results << result
113
+ end
114
+ end
115
+ end
116
+
117
+ return safe_parse_json(response.body) unless server_sent_events_enabled
118
+
119
+ results.map { |result| result[:event] }
120
+ rescue Faraday::ServerError => e
121
+ raise RequestError.new(e.message, request: e, payload:)
122
+ end
123
+
124
+ def safe_parse_json(raw)
125
+ raw.start_with?('{', '[') ? JSON.parse(raw) : raw
126
+ rescue JSON::ParserError
127
+ raw
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../components/errors'
4
+
5
+ include Cohere::Errors
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../static/gem'
4
+ require_relative '../../controllers/client'
5
+
6
+ module Cohere
7
+ def self.new(...)
8
+ Controllers::Client.new(...)
9
+ end
10
+
11
+ def self.version
12
+ Cohere::GEM[:version]
13
+ end
14
+ end
data/static/gem.rb ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cohere
4
+ GEM = {
5
+ name: 'cohere-ai',
6
+ version: '1.0.0',
7
+ author: 'gbaptista',
8
+ summary: 'Interact with Cohere AI.',
9
+ description: "A Ruby gem for interacting with Cohere AI platform.",
10
+ github: 'https://github.com/gbaptista/cohere-ai',
11
+ gem_server: 'https://rubygems.org',
12
+ license: 'MIT',
13
+ ruby: '3.1.0'
14
+ }.freeze
15
+ end
@@ -0,0 +1,39 @@
1
+ (require '[clojure.string :as str])
2
+
3
+ (defn slugify [text]
4
+ (-> text
5
+ (clojure.string/lower-case)
6
+ (clojure.string/replace " " "-")
7
+ (clojure.string/replace #"[^a-z0-9\-_]" "")))
8
+
9
+ (defn remove-code-blocks [content]
10
+ (let [code-block-regex #"(?s)```.*?```"]
11
+ (clojure.string/replace content code-block-regex "")))
12
+
13
+ (defn process-line [line]
14
+ (when-let [[_ hashes title] (re-find #"^(\#{2,}) (.+)" line)]
15
+ (let [link (slugify title)]
16
+ {:level (count hashes) :title title :link link})))
17
+
18
+ (defn create-index [content]
19
+ (let [processed-content (remove-code-blocks content)
20
+ processed-lines (->> processed-content
21
+ clojure.string/split-lines
22
+ (map process-line)
23
+ (remove nil?))]
24
+ (->> processed-lines
25
+ (map (fn [{:keys [level title link]}]
26
+ (str (apply str (repeat (* 4 (- level 2)) " "))
27
+ "- ["
28
+ title
29
+ "](#"
30
+ link
31
+ ")")))
32
+ (clojure.string/join "\n"))))
33
+
34
+
35
+ (let [content (slurp "template.md")
36
+ index (create-index content)
37
+ updated-content (clojure.string/replace content "{index}" index)]
38
+ (spit "README.md" updated-content)
39
+ (println "README.md successfully generated."))