fast-deepseek 0.2.2 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db93a692cecf12040497bbd26b9654b36a25f5b30887178dc6250016cd7a3cfe
4
- data.tar.gz: 0add12910cf7304d4d778d1850cc1a09394377d2a04f5ec52b896e4f6f7cbb62
3
+ metadata.gz: 2712981183f90a1d6a5de3571eb4fcc66ae0a29f31c91816a566598b6c7e7d6a
4
+ data.tar.gz: bccffaf9ae7a7c2047f95f5f36bdf9a9e82d28b0c45e558a627d55a7937317cb
5
5
  SHA512:
6
- metadata.gz: c5c8594cd3f42a933aa85bd867ed9b55f74d08a0b8d4c8f926f423f5d52d9698e4b57377fbef3e88be5b7ba32f850ab5300f30956f9522686116cd46ec4a5343
7
- data.tar.gz: d364afefc8880147b8ec64a22f50102cdfbe236770bcd481059b0e15934e3225d73232fd2db976e3d066b5e339a11ad86837012d267e25bff20d2954e6b31b26
6
+ metadata.gz: 355f7001010c8bf9f38316f399a5ebd6ba4dc4e74f8982b20dde51a5c1fefa1459bb8ac7c2f109864f179072e35197c78bc884351d2936dcbdd1b1285848171a
7
+ data.tar.gz: 2e7b1b48184e7f41caec3d2313d91658edda09dcf0be618309671b6baa3bc5db5c10b8a66edfc6bc858b104aa36e42c0ffbe8506198d0eafdefeb44325d3641c
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "faraday"
4
- require "json"
5
- require "logger"
6
3
  require "dotenv/load"
4
+ require_relative "request"
7
5
 
8
6
  module FastDeepseek
9
7
  # Client for interacting with the DeepSeek API.
@@ -14,56 +12,21 @@ module FastDeepseek
14
12
  @api_key = api_key || ENV.fetch("DEEPSEEK_API_KEY", nil)
15
13
  raise Error, "DEEPSEEK_API_KEY is missing! Set it in the .env file or pass it explicitly." unless @api_key
16
14
 
17
- @logger = Logger.new($stdout)
18
- @conn = Faraday.new(url: base_url) do |faraday|
19
- faraday.adapter Faraday.default_adapter
20
- faraday.headers["Content-Type"] = "application/json"
21
- end
15
+ @request = Request.new(api_key: @api_key, base_url: base_url)
22
16
  end
23
17
 
24
18
  def chat(prompt, model:, options: {})
25
- request("chat", { model: model, messages: [{ role: "user", content: prompt }], stream: false }.merge(options))
19
+ payload = { model: model, messages: [{ role: "user", content: prompt }], stream: false }.merge(options)
20
+ @request.call("chat", payload)
26
21
  end
27
22
 
28
- def models
29
- request("models", method: :get)
30
- end
31
-
32
- private
33
-
34
- def request(endpoint, payload = nil, method: :post)
35
- response = send_request(endpoint, payload, method)
36
- handle_response(response)
37
- rescue Faraday::Error => e
38
- @logger.error("API request failed: #{e.message}")
39
- raise Error, "API request failed: #{e.message}"
40
- rescue JSON::ParserError => e
41
- @logger.error("Invalid API response: #{e.message}")
42
- raise Error, "Invalid API response: #{e.message}"
23
+ def chat_stream(prompt, model:, options: {}, &)
24
+ payload = { model: model, messages: [{ role: "user", content: prompt }], stream: true }.merge(options)
25
+ @request.stream("chat", payload, &)
43
26
  end
44
27
 
45
- def send_request(endpoint, payload, method)
46
- path = method == :post ? "#{endpoint}/completions" : endpoint
47
- @conn.public_send(method, path) do |req|
48
- req.headers["Authorization"] = format("Bearer %s", @api_key)
49
- req.body = payload.to_json if payload
50
- end
51
- end
52
-
53
- def handle_response(response)
54
- case response.status
55
- when 429
56
- @logger.error("API rate limit exceeded. Please try again later.")
57
- raise RateLimitError, "API rate limit exceeded. Please try again later."
58
- when 500..599
59
- @logger.error("Server error occurred. Please try again later.")
60
- raise ServerError, "Server error occurred. Please try again later."
61
- when 200..299
62
- JSON.parse(response.body)
63
- else
64
- @logger.error("API request failed: #{response.status} - #{response.body}")
65
- raise Error, "API request failed: #{response.status} - #{response.body}"
66
- end
28
+ def models
29
+ @request.call("models", method: :get)
67
30
  end
68
31
  end
69
32
  end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "json"
5
+ require "logger"
6
+ require_relative "errors"
7
+
8
+ module FastDeepseek
9
+ # Handles HTTP requests and API response parsing.
10
+ class Request
11
+ def initialize(api_key:, base_url:, logger: nil)
12
+ @api_key = api_key
13
+ @logger = logger || Logger.new($stdout)
14
+ @conn = Faraday.new(url: base_url) do |faraday|
15
+ faraday.adapter Faraday.default_adapter
16
+ faraday.headers["Content-Type"] = "application/json"
17
+ end
18
+ end
19
+
20
+ def call(endpoint, payload = nil, method: :post)
21
+ response = send_request(endpoint, payload, method)
22
+ handle_response(response)
23
+ rescue Faraday::Error => e
24
+ @logger.error("API request failed: #{e.message}")
25
+ raise Error, "API request failed: #{e.message}"
26
+ rescue JSON::ParserError => e
27
+ @logger.error("Invalid API response: #{e.message}")
28
+ raise Error, "Invalid API response: #{e.message}"
29
+ end
30
+
31
+ def stream(endpoint, payload, &block)
32
+ raise ArgumentError, "a block is required for streaming" unless block
33
+
34
+ buffer = +""
35
+ response = send_stream_request(endpoint, payload) do |chunk|
36
+ process_stream_chunk(buffer, chunk, &block)
37
+ end
38
+
39
+ handle_status(response)
40
+ rescue Faraday::Error => e
41
+ @logger.error("API request failed: #{e.message}")
42
+ raise Error, "API request failed: #{e.message}"
43
+ rescue JSON::ParserError => e
44
+ @logger.error("Invalid streaming response: #{e.message}")
45
+ raise Error, "Invalid streaming response: #{e.message}"
46
+ end
47
+
48
+ private
49
+
50
+ def send_request(endpoint, payload, method)
51
+ path = method == :post ? "#{endpoint}/completions" : endpoint
52
+ @conn.public_send(method, path) do |req|
53
+ req.headers["Authorization"] = format("Bearer %s", @api_key)
54
+ req.body = payload.to_json if payload
55
+ end
56
+ end
57
+
58
+ def send_stream_request(endpoint, payload, &)
59
+ @conn.post("#{endpoint}/completions") do |req|
60
+ req.headers["Authorization"] = format("Bearer %s", @api_key)
61
+ req.headers["Accept"] = "text/event-stream"
62
+ req.body = payload.to_json
63
+ req.options.on_data = proc do |chunk, _bytes_received, _env|
64
+ yield chunk
65
+ end
66
+ end
67
+ end
68
+
69
+ def process_stream_chunk(buffer, chunk, &)
70
+ buffer << chunk
71
+ process_stream_buffer(buffer, &)
72
+ end
73
+
74
+ def handle_response(response)
75
+ handle_status(response)
76
+ JSON.parse(response.body)
77
+ end
78
+
79
+ def handle_status(response)
80
+ case response.status
81
+ when 429
82
+ @logger.error("API rate limit exceeded. Please try again later.")
83
+ raise RateLimitError, "API rate limit exceeded. Please try again later."
84
+ when 500..599
85
+ @logger.error("Server error occurred. Please try again later.")
86
+ raise ServerError, "Server error occurred. Please try again later."
87
+ when 200..299
88
+ true
89
+ else
90
+ @logger.error("API request failed: #{response.status} - #{response.body}")
91
+ raise Error, "API request failed: #{response.status} - #{response.body}"
92
+ end
93
+ end
94
+
95
+ def process_stream_buffer(buffer)
96
+ while (line = buffer.slice!(/.*\n/))
97
+ next unless line.start_with?("data: ")
98
+
99
+ data = line.delete_prefix("data: ").strip
100
+ next if data.empty? || data == "[DONE]"
101
+
102
+ content = JSON.parse(data).dig("choices", 0, "delta", "content")
103
+ yield content if content
104
+ end
105
+ end
106
+ end
107
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # lib/fast_deepseek/version.rb
4
4
  module FastDeepseek
5
- VERSION = "0.2.2"
5
+ VERSION = "0.3.0"
6
6
  end
data/lib/fast_deepseek.rb CHANGED
@@ -2,4 +2,5 @@
2
2
 
3
3
  require_relative "fast_deepseek/version"
4
4
  require_relative "fast_deepseek/errors"
5
+ require_relative "fast_deepseek/request"
5
6
  require_relative "fast_deepseek/client"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast-deepseek
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uday Kadaboina
@@ -49,6 +49,7 @@ files:
49
49
  - lib/fast_deepseek.rb
50
50
  - lib/fast_deepseek/client.rb
51
51
  - lib/fast_deepseek/errors.rb
52
+ - lib/fast_deepseek/request.rb
52
53
  - lib/fast_deepseek/version.rb
53
54
  homepage: https://github.com/udaykadaboina/fast-deepseek
54
55
  licenses:
@@ -56,7 +57,7 @@ licenses:
56
57
  metadata:
57
58
  homepage_uri: https://github.com/udaykadaboina/fast-deepseek
58
59
  source_code_uri: https://github.com/udaykadaboina/fast-deepseek
59
- changelog_uri: https://github.com/udaykadaboina/fast-deepseek/releases/tag/v0.2.2
60
+ changelog_uri: https://github.com/udaykadaboina/fast-deepseek/releases/tag/v0.3.0
60
61
  rubygems_mfa_required: 'true'
61
62
  rdoc_options: []
62
63
  require_paths: