hinow-ai 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 32e08f0d016478c52bbe52d51e564988a29148b4f08592718e7cf567a2c12d32
4
+ data.tar.gz: 8b55afc8c05105fb2b22441c3ca694fcc01e959d19e4bd7f1fe0cfe4ab11e87c
5
+ SHA512:
6
+ metadata.gz: 1a2d25c9d1494378145321d314a6777e6f6d9921b1b824b5c8c161702e6fef0a702dee313a1764d5c9dac62fd7652ca51912ce4b44fa3d94ddb9351be1efc0e7
7
+ data.tar.gz: 625638213fa9486a6a46ebfab675fe900ed5a46aa1ee20680581af1f1414b5951436aeec25ff13a136d1fae48d3e3e7e264d7fddb41a08f39c89710e561879b9
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 HINOW AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,201 @@
1
+ # HINOW Ruby SDK
2
+
3
+ Official Ruby SDK for the [HINOW AI Inference API](https://hinow.ai).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install hinow-ai
9
+ ```
10
+
11
+ Or add to your Gemfile:
12
+
13
+ ```ruby
14
+ gem 'hinow-ai'
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```ruby
20
+ require 'hinow'
21
+
22
+ client = Hinow::Client.new(api_key: 'hi_your_api_key')
23
+
24
+ # Chat completion
25
+ response = client.chat.completions.create(
26
+ model: 'deepseek-ai/deepseek-v3.2',
27
+ messages: [{ role: 'user', content: 'Hello!' }],
28
+ temperature: 0.7
29
+ )
30
+
31
+ puts response['choices'][0]['message']['content']
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ ### Global Configuration
37
+
38
+ ```ruby
39
+ Hinow.configure do |config|
40
+ config.api_key = 'hi_your_api_key'
41
+ config.base_url = 'https://api.hinow.ai'
42
+ config.timeout = 120
43
+ end
44
+
45
+ # Then use the global client
46
+ response = Hinow.client.chat.completions.create(...)
47
+ ```
48
+
49
+ ### Environment Variable
50
+
51
+ ```bash
52
+ export HINOW_API_KEY=hi_your_api_key
53
+ ```
54
+
55
+ ```ruby
56
+ client = Hinow::Client.new # Uses HINOW_API_KEY
57
+ ```
58
+
59
+ ## Features
60
+
61
+ ### Chat Completions
62
+
63
+ ```ruby
64
+ response = client.chat.completions.create(
65
+ model: 'deepseek-ai/deepseek-v3.2',
66
+ messages: [
67
+ { role: 'system', content: 'You are a helpful assistant.' },
68
+ { role: 'user', content: 'What is the capital of France?' }
69
+ ],
70
+ temperature: 0.7,
71
+ max_tokens: 1000
72
+ )
73
+ ```
74
+
75
+ ### Function Calling
76
+
77
+ ```ruby
78
+ response = client.chat.completions.create(
79
+ model: 'deepseek-ai/deepseek-v3.2',
80
+ messages: [{ role: 'user', content: "What's the weather in Paris?" }],
81
+ tools: [{
82
+ type: 'function',
83
+ function: {
84
+ name: 'get_weather',
85
+ description: 'Get the current weather in a city',
86
+ parameters: {
87
+ type: 'object',
88
+ properties: {
89
+ location: { type: 'string', description: 'City name' }
90
+ },
91
+ required: ['location']
92
+ }
93
+ }
94
+ }]
95
+ )
96
+
97
+ if response['choices'][0]['message']['tool_calls']
98
+ response['choices'][0]['message']['tool_calls'].each do |tool_call|
99
+ puts "Function: #{tool_call['function']['name']}"
100
+ puts "Arguments: #{tool_call['function']['arguments']}"
101
+ end
102
+ end
103
+ ```
104
+
105
+ ### Image Generation
106
+
107
+ ```ruby
108
+ response = client.images.generate(
109
+ model: 'dall-e-3',
110
+ prompt: 'A beautiful sunset over mountains',
111
+ size: '1024x1024',
112
+ quality: 'hd'
113
+ )
114
+
115
+ response['data']['urls'].each { |url| puts "Image URL: #{url}" }
116
+ ```
117
+
118
+ ### Text to Speech
119
+
120
+ ```ruby
121
+ response = client.audio.speech(
122
+ model: 'tts-1',
123
+ input: 'Hello, how are you today?',
124
+ voice: 'alloy',
125
+ speed: 1.0
126
+ )
127
+
128
+ response['data']['urls'].each { |url| puts "Audio URL: #{url}" }
129
+ ```
130
+
131
+ ### Speech to Text
132
+
133
+ ```ruby
134
+ response = client.audio.transcribe(
135
+ model: 'whisper-1',
136
+ file: '/path/to/audio.mp3',
137
+ language: 'en'
138
+ )
139
+
140
+ puts "Transcription: #{response['data']['text']}"
141
+ ```
142
+
143
+ ### Video Generation
144
+
145
+ ```ruby
146
+ response = client.video.generate(
147
+ model: 'video-model',
148
+ prompt: 'A cat playing piano',
149
+ duration: 5,
150
+ resolution: '1080p'
151
+ )
152
+
153
+ response['data']['urls'].each { |url| puts "Video URL: #{url}" }
154
+ ```
155
+
156
+ ### Embeddings
157
+
158
+ ```ruby
159
+ response = client.embeddings.create(
160
+ model: 'text-embedding-ada-002',
161
+ input: 'Hello world'
162
+ )
163
+
164
+ embedding = response['data'][0]['embedding']
165
+ puts "Embedding dimensions: #{embedding.length}"
166
+ ```
167
+
168
+ ### List Models
169
+
170
+ ```ruby
171
+ response = client.models.list
172
+ response['data'].each { |model| puts "Model: #{model['id']}" }
173
+ ```
174
+
175
+ ### Check Balance
176
+
177
+ ```ruby
178
+ balance = client.get_balance
179
+ puts "Balance: #{balance['data']['balance']} #{balance['data']['currency']}"
180
+ ```
181
+
182
+ ## Error Handling
183
+
184
+ ```ruby
185
+ begin
186
+ response = client.chat.completions.create(...)
187
+ rescue Hinow::Error => e
188
+ puts "Error: #{e.message}"
189
+ puts "Status code: #{e.status_code}"
190
+ end
191
+ ```
192
+
193
+ ## Links
194
+
195
+ - [HINOW Website](https://hinow.ai)
196
+ - [API Platform](https://platform.hinow.ai)
197
+ - [GitHub](https://github.com/hinow-ai/sdk-ruby)
198
+
199
+ ## License
200
+
201
+ MIT License
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hinow
4
+ class Audio
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def speech(model:, input:, voice: nil, speed: nil)
10
+ body = { model: model, prompt: input } # API uses "prompt" not "input"
11
+
12
+ parameters = {}
13
+ parameters[:voice] = voice if voice
14
+ parameters[:speed] = speed.to_s if speed
15
+
16
+ body[:parameters] = parameters unless parameters.empty?
17
+
18
+ @client.post("/v1/audio/speech", body)
19
+ end
20
+
21
+ def transcribe(model:, file:, language: nil)
22
+ payload = {
23
+ model: model,
24
+ file: Faraday::Multipart::FilePart.new(file, "audio/*")
25
+ }
26
+ payload[:language] = language if language
27
+
28
+ @client.post_multipart("/v1/audio/transcriptions", payload)
29
+ end
30
+ end
31
+ end
data/lib/hinow/chat.rb ADDED
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hinow
4
+ class Chat
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def completions
10
+ @completions ||= ChatCompletions.new(@client)
11
+ end
12
+ end
13
+
14
+ class ChatCompletions
15
+ def initialize(client)
16
+ @client = client
17
+ end
18
+
19
+ def create(model:, messages:, temperature: nil, max_tokens: nil, top_p: nil,
20
+ repetition_penalty: nil, response_format: nil, tools: nil, tool_choice: nil)
21
+ body = {
22
+ model: model,
23
+ messages: messages
24
+ }
25
+
26
+ parameters = {}
27
+ parameters[:temperature] = temperature.to_s if temperature
28
+ parameters[:max_tokens] = max_tokens.to_s if max_tokens
29
+ parameters[:top_p] = top_p.to_s if top_p
30
+ parameters[:repetition_penalty] = repetition_penalty.to_s if repetition_penalty
31
+
32
+ body[:parameters] = parameters unless parameters.empty?
33
+ body[:response_format] = response_format if response_format
34
+ body[:tools] = tools if tools
35
+ body[:tool_choice] = tool_choice if tool_choice
36
+
37
+ @client.post("/v1/chat/completions", body)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hinow
4
+ class Client
5
+ DEFAULT_BASE_URL = "https://api.hinow.ai"
6
+ DEFAULT_TIMEOUT = 120
7
+
8
+ attr_reader :chat, :images, :audio, :video, :embeddings, :models
9
+
10
+ def initialize(api_key: nil, base_url: nil, timeout: nil)
11
+ @api_key = api_key || ENV["HINOW_API_KEY"]
12
+ raise Error, "API key is required. Set HINOW_API_KEY environment variable or pass api_key parameter." if @api_key.nil? || @api_key.empty?
13
+
14
+ @base_url = (base_url || DEFAULT_BASE_URL).chomp("/")
15
+ @timeout = timeout || DEFAULT_TIMEOUT
16
+
17
+ @connection = Faraday.new(url: @base_url) do |f|
18
+ f.request :multipart
19
+ f.request :url_encoded
20
+ f.headers["Authorization"] = "Bearer #{@api_key}"
21
+ f.headers["Content-Type"] = "application/json"
22
+ f.headers["User-Agent"] = "hinow-ruby/#{VERSION}"
23
+ f.options.timeout = @timeout
24
+ f.adapter Faraday.default_adapter
25
+ end
26
+
27
+ @chat = Chat.new(self)
28
+ @images = Images.new(self)
29
+ @audio = Audio.new(self)
30
+ @video = Video.new(self)
31
+ @embeddings = Embeddings.new(self)
32
+ @models = Models.new(self)
33
+ end
34
+
35
+ def get_balance
36
+ get("/v1/balance")
37
+ end
38
+
39
+ def get(path)
40
+ response = @connection.get(path)
41
+ handle_response(response)
42
+ end
43
+
44
+ def post(path, body)
45
+ response = @connection.post(path) do |req|
46
+ req.body = body.to_json
47
+ end
48
+ handle_response(response)
49
+ end
50
+
51
+ def post_multipart(path, payload)
52
+ response = @connection.post(path) do |req|
53
+ req.headers.delete("Content-Type")
54
+ req.body = payload
55
+ end
56
+ handle_response(response)
57
+ end
58
+
59
+ private
60
+
61
+ def handle_response(response)
62
+ body = JSON.parse(response.body) rescue response.body
63
+
64
+ unless response.success?
65
+ raise Error.new(
66
+ "Request failed with status #{response.status}: #{body}",
67
+ status_code: response.status,
68
+ response_body: body
69
+ )
70
+ end
71
+
72
+ body
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hinow
4
+ class Embeddings
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def create(model:, input:)
10
+ @client.post("/v1/embeddings", { model: model, input: input })
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hinow
4
+ class Error < StandardError
5
+ attr_reader :status_code, :response_body
6
+
7
+ def initialize(message = nil, status_code: nil, response_body: nil)
8
+ @status_code = status_code
9
+ @response_body = response_body
10
+ super(message)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hinow
4
+ class Images
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def generate(model:, prompt:, n: nil, size: nil, quality: nil, style: nil)
10
+ body = { model: model, prompt: prompt }
11
+
12
+ parameters = {}
13
+ parameters[:n] = n.to_s if n
14
+ parameters[:size] = size if size
15
+ parameters[:quality] = quality if quality
16
+ parameters[:style] = style if style
17
+
18
+ body[:parameters] = parameters unless parameters.empty?
19
+
20
+ @client.post("/v1/images", body)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hinow
4
+ class Models
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def list
10
+ @client.get("/v1/models")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hinow
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hinow
4
+ class Video
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def generate(model:, prompt:, duration: nil, resolution: nil, fps: nil)
10
+ body = { model: model, prompt: prompt }
11
+
12
+ parameters = {}
13
+ parameters[:duration] = duration.to_s if duration
14
+ parameters[:resolution] = resolution if resolution
15
+ parameters[:fps] = fps.to_s if fps
16
+
17
+ body[:parameters] = parameters unless parameters.empty?
18
+
19
+ @client.post("/v1/videos", body)
20
+ end
21
+ end
22
+ end
data/lib/hinow.rb ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "faraday/multipart"
5
+ require "json"
6
+
7
+ require_relative "hinow/version"
8
+ require_relative "hinow/error"
9
+ require_relative "hinow/client"
10
+ require_relative "hinow/chat"
11
+ require_relative "hinow/images"
12
+ require_relative "hinow/audio"
13
+ require_relative "hinow/video"
14
+ require_relative "hinow/embeddings"
15
+ require_relative "hinow/models"
16
+
17
+ module Hinow
18
+ class << self
19
+ attr_accessor :api_key, :base_url, :timeout
20
+
21
+ def configure
22
+ yield self
23
+ end
24
+
25
+ def client
26
+ @client ||= Client.new(
27
+ api_key: api_key,
28
+ base_url: base_url,
29
+ timeout: timeout
30
+ )
31
+ end
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hinow-ai
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - HINOW AI
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-03-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday-multipart
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ description: Ruby client library for HINOW AI - Access LLMs, image generation, TTS,
42
+ STT, video generation, and embeddings.
43
+ email:
44
+ - support@hinow.ai
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - LICENSE
50
+ - README.md
51
+ - lib/hinow.rb
52
+ - lib/hinow/audio.rb
53
+ - lib/hinow/chat.rb
54
+ - lib/hinow/client.rb
55
+ - lib/hinow/embeddings.rb
56
+ - lib/hinow/error.rb
57
+ - lib/hinow/images.rb
58
+ - lib/hinow/models.rb
59
+ - lib/hinow/version.rb
60
+ - lib/hinow/video.rb
61
+ homepage: https://hinow.ai
62
+ licenses:
63
+ - MIT
64
+ metadata:
65
+ homepage_uri: https://hinow.ai
66
+ source_code_uri: https://github.com/hinow-ai/sdk-ruby
67
+ changelog_uri: https://github.com/hinow-ai/sdk-ruby/blob/main/CHANGELOG.md
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 2.7.0
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubygems_version: 3.4.20
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Official Ruby SDK for the HINOW AI Inference API
87
+ test_files: []