skillrouter 0.1.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: 86d4927e3c17824677d528040ea63bf5f763f7b981fb64e6d623785bfc34f46f
4
+ data.tar.gz: e1b61db17c4c136b13d05b4d1bf373e0bff04e2e9e04cb19a1b19de8f38a32f7
5
+ SHA512:
6
+ metadata.gz: 03bfaca3966c6deb0c74bd72d2c47fcb013ca769dfaeec230c8386d0297aed9af95459a7026b09b1cc632437204b090ffdde54b652f4b5ece014c95d7c10acfc
7
+ data.tar.gz: 51a4bcb5891e0a52b062767bc4a7ad1b91e404cd934730345285a467fee01270cad2ec43f3ad14381dc09c04178e21e47fff0a34d0095227c01a184e182fd44a
@@ -0,0 +1,152 @@
1
+ require "net/http"
2
+ require "uri"
3
+ require "json"
4
+
5
+ module SkillRouter
6
+ class Client
7
+ attr_reader :api_key, :base_url, :timeout, :max_retries
8
+
9
+ def initialize(api_key: nil, base_url: nil, timeout: nil, max_retries: nil)
10
+ config = SkillRouter.configuration
11
+ @api_key = api_key || config.api_key
12
+ @base_url = base_url || config.base_url
13
+ @timeout = timeout || config.timeout
14
+ @max_retries = max_retries || config.max_retries
15
+
16
+ raise AuthenticationError, "API key is required. Set it via SkillRouter.configure or pass api_key:" unless @api_key
17
+ end
18
+
19
+ # List skills with optional filters
20
+ def skills(category: nil, provider: nil, search: nil, page: 1, per_page: 20)
21
+ params = { page: page, per_page: per_page }
22
+ params[:category] = category if category
23
+ params[:provider] = provider if provider
24
+ params[:search] = search if search
25
+ request(:get, "/v1/skills", params: params)
26
+ end
27
+
28
+ # Get a single skill by ID or slug
29
+ def skill(id)
30
+ request(:get, "/v1/skills/#{id}")
31
+ end
32
+
33
+ # Discover skills using natural language
34
+ def discover(query, category: nil, limit: 5)
35
+ body = { query: query, limit: limit }
36
+ body[:category] = category if category
37
+ request(:post, "/v1/skills/discover", body: body)
38
+ end
39
+
40
+ # Execute a skill
41
+ def execute(skill_id:, params:, async: false, timeout_ms: nil)
42
+ body = { skill_id: skill_id, params: params }
43
+ body[:async] = async if async
44
+ body[:timeout_ms] = timeout_ms if timeout_ms
45
+ request(:post, "/v1/execute", body: body)
46
+ end
47
+
48
+ # List executions
49
+ def executions(page: 1, per_page: 20)
50
+ request(:get, "/v1/executions", params: { page: page, per_page: per_page })
51
+ end
52
+
53
+ # Get a single execution
54
+ def execution(id)
55
+ request(:get, "/v1/executions/#{id}")
56
+ end
57
+
58
+ # Get usage stats
59
+ def usage
60
+ request(:get, "/v1/usage")
61
+ end
62
+
63
+ # Get account info
64
+ def account
65
+ request(:get, "/v1/account")
66
+ end
67
+
68
+ # List skillsets
69
+ def skillsets
70
+ request(:get, "/v1/skillsets")
71
+ end
72
+
73
+ # Create a skillset
74
+ def create_skillset(name:, description: nil, skill_ids: [])
75
+ body = { name: name, skill_ids: skill_ids }
76
+ body[:description] = description if description
77
+ request(:post, "/v1/skillsets", body: body)
78
+ end
79
+
80
+ # Delete a skillset
81
+ def delete_skillset(id)
82
+ request(:delete, "/v1/skillsets/#{id}")
83
+ end
84
+
85
+ private
86
+
87
+ def request(method, path, params: {}, body: nil)
88
+ uri = URI("#{@base_url}#{path}")
89
+ uri.query = URI.encode_www_form(params) unless params.empty?
90
+
91
+ retries = 0
92
+ begin
93
+ response = make_request(method, uri, body)
94
+ handle_response(response)
95
+ rescue RateLimitError, ServerError => e
96
+ retries += 1
97
+ raise e if retries > @max_retries
98
+ sleep(2 ** retries * 0.5)
99
+ retry
100
+ end
101
+ end
102
+
103
+ def make_request(method, uri, body)
104
+ http = Net::HTTP.new(uri.host, uri.port)
105
+ http.use_ssl = uri.scheme == "https"
106
+ http.open_timeout = @timeout
107
+ http.read_timeout = @timeout
108
+
109
+ req = case method
110
+ when :get then Net::HTTP::Get.new(uri)
111
+ when :post then Net::HTTP::Post.new(uri)
112
+ when :delete then Net::HTTP::Delete.new(uri)
113
+ else raise ArgumentError, "Unsupported HTTP method: #{method}"
114
+ end
115
+
116
+ req["Authorization"] = "Bearer #{@api_key}"
117
+ req["Content-Type"] = "application/json"
118
+ req["User-Agent"] = "skillrouter-ruby/#{VERSION}"
119
+
120
+ if body
121
+ req.body = body.to_json
122
+ end
123
+
124
+ http.request(req)
125
+ rescue Net::OpenTimeout, Net::ReadTimeout
126
+ raise TimeoutError, "Request timed out after #{@timeout}s"
127
+ end
128
+
129
+ def handle_response(response)
130
+ body = response.body ? JSON.parse(response.body, symbolize_names: true) : {}
131
+
132
+ case response.code.to_i
133
+ when 200..299
134
+ body
135
+ when 401
136
+ raise AuthenticationError, body[:error] || "Invalid API key"
137
+ when 404
138
+ raise NotFoundError, body[:error] || "Resource not found"
139
+ when 422
140
+ raise ValidationError, body[:error] || "Validation failed"
141
+ when 429
142
+ raise RateLimitError, body[:error] || "Rate limit exceeded"
143
+ when 500..599
144
+ raise ServerError, body[:error] || "Server error (#{response.code})"
145
+ else
146
+ raise Error, body[:error] || "Unexpected response (#{response.code})"
147
+ end
148
+ rescue JSON::ParserError
149
+ raise Error, "Invalid JSON response from server"
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,12 @@
1
+ module SkillRouter
2
+ class Configuration
3
+ attr_accessor :api_key, :base_url, :timeout, :max_retries
4
+
5
+ def initialize
6
+ @api_key = ENV["SKILLROUTER_API_KEY"]
7
+ @base_url = "https://api.skillrouter.dev"
8
+ @timeout = 30
9
+ @max_retries = 2
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ module SkillRouter
2
+ class Error < StandardError; end
3
+ class AuthenticationError < Error; end
4
+ class RateLimitError < Error; end
5
+ class NotFoundError < Error; end
6
+ class ValidationError < Error; end
7
+ class ServerError < Error; end
8
+ class TimeoutError < Error; end
9
+ end
@@ -0,0 +1,3 @@
1
+ module SkillRouter
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "skillrouter/version"
2
+ require_relative "skillrouter/configuration"
3
+ require_relative "skillrouter/client"
4
+ require_relative "skillrouter/errors"
5
+
6
+ module SkillRouter
7
+ class << self
8
+ attr_writer :configuration
9
+
10
+ def configuration
11
+ @configuration ||= Configuration.new
12
+ end
13
+
14
+ def configure
15
+ yield(configuration)
16
+ end
17
+
18
+ def reset!
19
+ @configuration = Configuration.new
20
+ end
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: skillrouter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - SkillRouter
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Discover, validate, and execute skills for AI agents via the SkillRouter
13
+ API. One API to give your agents access to 1,000+ tools.
14
+ email: developers@skillrouter.dev
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/skillrouter.rb
20
+ - lib/skillrouter/client.rb
21
+ - lib/skillrouter/configuration.rb
22
+ - lib/skillrouter/errors.rb
23
+ - lib/skillrouter/version.rb
24
+ homepage: https://skillrouter.dev
25
+ licenses:
26
+ - MIT
27
+ metadata:
28
+ homepage_uri: https://skillrouter.dev
29
+ source_code_uri: https://github.com/skillrouter/ruby-sdk
30
+ documentation_uri: https://skillrouter.dev/docs/sdk/ruby
31
+ bug_tracker_uri: https://github.com/skillrouter/ruby-sdk/issues
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 3.0.0
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.6.8
47
+ specification_version: 4
48
+ summary: Official Ruby client for the SkillRouter API
49
+ test_files: []