mistral_rb 0.1.1 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69d426e25d1c19668cbde210ee7269a98e5769cb852c5184220c99460c7c2657
4
- data.tar.gz: d0b6828a2313d6bdfd18e0879c8ba8b05a1559a3e4c045d0d26970a2e40fa1c9
3
+ metadata.gz: 8826573e4021a69c7f6c560357c79a75fc80a63ff97b6610143fe3505f4d9138
4
+ data.tar.gz: 04bf840637ab24c388b28b175b987083f9786579d58dec9f8e5366f0f7a1d541
5
5
  SHA512:
6
- metadata.gz: 647b05e72b0699d8e6c3bf74408cdb3b8cbc633b37221f0b53e074d1a28e7bf21ff74023c921f83b6a3df8882693d726716a328644e9b9bec53fc4d8dbebc333
7
- data.tar.gz: ae4b88b5773aa88981220b8cf3c1c301ca262275be1f67c6d37b26e195896df099512632d405afd0ec85a4e985873e48670b9a282614b9e74a20289c7b0e70ef
6
+ metadata.gz: b3aee45181ce35cd5b34df3b10f091ef084bc00bba078452f0a5485e47eb0b19374d07219f6a8a258884410c9cc4557d4e8ac07f0bf0cfcccbe25def5f5baea4
7
+ data.tar.gz: 886665f3b0e2db01b155421c6680b6523cbae26c61ef260de303cb9ad90a6e69c1a60b433d2fcfc78167d450e842016629f40a02d51d714cf4d89bfb58d98bd4
data/README.md CHANGED
@@ -41,6 +41,21 @@ model_list_response.data.each do |model|
41
41
  end
42
42
  ```
43
43
 
44
+ Here is how to use streaming:
45
+
46
+ ```ruby
47
+ api = MistralAPI.new("api_key")
48
+
49
+ api.create_chat_completion(
50
+ model: 'mistral-tiny',
51
+ messages: [{ 'role' => 'user', 'content' => 'Who is Barack Obama ?' }],
52
+ stream: true
53
+ ) do |chunk|
54
+ puts chunk.inspect
55
+ end
56
+
57
+ ```
58
+
44
59
 
45
60
  ## Development
46
61
 
@@ -71,3 +71,34 @@ class Model
71
71
  @permissions = model_hash["permission"] # This could be further parsed into Permission objects if detailed parsing is required
72
72
  end
73
73
  end
74
+
75
+ class StreamedCompletionResponse
76
+ attr_reader :id, :object, :created, :model, :choices
77
+
78
+ def initialize(response_hash)
79
+ @id = response_hash["id"]
80
+ @object = response_hash["object"]
81
+ @created = response_hash["created"]
82
+ @model = response_hash["model"]
83
+ @choices = response_hash["choices"].map { |choice| StreamedChoice.new(choice) }
84
+ end
85
+ end
86
+
87
+ class StreamedChoice
88
+ attr_reader :index, :delta, :finish_reason
89
+
90
+ def initialize(choice_hash)
91
+ @index = choice_hash["index"]
92
+ @delta = Delta.new(choice_hash["delta"]) if choice_hash["delta"]
93
+ @finish_reason = choice_hash["finish_reason"]
94
+ end
95
+ end
96
+
97
+ class Delta
98
+ attr_reader :role, :content
99
+
100
+ def initialize(delta_hash)
101
+ @role = delta_hash["role"]
102
+ @content = delta_hash["content"]
103
+ end
104
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MistralRb
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/mistral_rb.rb CHANGED
@@ -16,7 +16,7 @@ class MistralAPI
16
16
  self.class.base_uri base_uri
17
17
  end
18
18
 
19
- def create_chat_completion(model, messages, temperature = 0.7, top_p = 1, max_tokens = nil, stream = false, safe_mode = false, random_seed = nil)
19
+ def create_chat_completion(model:, messages:, temperature: 0.7, top_p: 1, max_tokens: nil, stream: false, safe_mode: false, random_seed: nil)
20
20
  body = {
21
21
  model: model,
22
22
  messages: messages,
@@ -26,11 +26,20 @@ class MistralAPI
26
26
  stream: stream,
27
27
  safe_mode: safe_mode,
28
28
  random_seed: random_seed
29
- }.compact.to_json # compact to remove nil values
29
+ }.compact.to_json
30
30
 
31
- response = self.class.post("/chat/completions", body: body, headers: @headers)
32
- parsed_response = handle_response(response)
33
- CompletionResponse.new(parsed_response)
31
+ if stream
32
+ # Use on_data callback for streaming
33
+ self.class.post("/chat/completions", body: body, headers: @headers, stream_body: true) do |fragment, _, _|
34
+ processed_chunk = handle_stream_chunk(fragment)
35
+ yield(processed_chunk) if block_given? && processed_chunk
36
+ end
37
+ else
38
+ # Handle non-streaming response
39
+ response = self.class.post("/chat/completions", body: body, headers: @headers)
40
+ parsed_response = handle_response(response)
41
+ CompletionResponse.new(parsed_response)
42
+ end
34
43
  end
35
44
 
36
45
  def create_embeddings(model, input, encoding_format = "float")
@@ -60,4 +69,20 @@ class MistralAPI
60
69
  raise "API Error: #{response.code} - #{response.body}"
61
70
  end
62
71
  end
72
+
73
+ def handle_stream_chunk(chunk)
74
+ # Skip processing if the chunk indicates the end of the stream.
75
+ return nil if chunk.strip == "data: [DONE]"
76
+
77
+ if chunk.strip.start_with?("data:")
78
+ data_content = chunk.split("data:").last.strip
79
+ begin
80
+ # Only parse the JSON content if it's not the end-of-stream indicator
81
+ json_content = JSON.parse(data_content)
82
+ StreamedCompletionResponse.new(json_content)
83
+ rescue JSON::ParserError => e
84
+ puts "Error parsing JSON: #{e.message}"
85
+ end
86
+ end
87
+ end
63
88
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mistral_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franck Stephane Ndzomga
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-22 00:00:00.000000000 Z
11
+ date: 2023-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty