devin_api 0.1.0 → 0.2.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: 6c8ff85d6a59c3442dcf00776af4e5b8e80903f2ccdcad81f79db2a89d91cb9f
4
- data.tar.gz: 3f14dc6752122758ae1a95915db964bc1812ce58d07afe26a02b45df1ef13457
3
+ metadata.gz: 8f65f3357eb5cda3b90c012a07739a5396e892b359fc5274bc5cf0e8e6b697b3
4
+ data.tar.gz: 6fe0d5ebf974c419396838577ae169d1d0bf49c9bab6c612f35d69c500de1013
5
5
  SHA512:
6
- metadata.gz: c99ddb448b733f01522c47664ecb8dc223792c7728a999cb87536aca2612893a7c989c21b8d89684f30e82df7210529940aed52cffb4b7de7b3a45b226b1dba9
7
- data.tar.gz: 239eb0b9069025d187350c853d3c9ebd0bc65606dad01c32b1732fa312279d0e11a605066e823047d3f845accc2d5526ea604bb849f23d79ac4bde912f14ce89
6
+ metadata.gz: e262c3d7ee63324bd010ab0c4d4d73f1e6ede29c383b387064933b23a981dfa8f17074a1d5c5ab5f11017c4ad5aa7c2a0feb424edab76a4702b8d27a50531e06
7
+ data.tar.gz: 22c05aeae4df719b243adb4a8d585ce78485cc4d129257ad4bf47eeb00b384f87bbed521bf2900fc97df1f6948bdac108a8471db2185bbc7f302b441d97e0775
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.2.0] - 2025-05-19
6
+
7
+ * Fix pagination in session list
8
+ * Fix send message to session
9
+ * Fix support for uploading files
10
+
5
11
  ## [0.1.0] - 2025-05-18
6
12
 
7
13
  * Initial version of the Devin API client
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Devin API Client
2
2
  [![Test](https://github.com/smasato/devin_api_client_rb/actions/workflows/rspec.yml/badge.svg)](https://github.com/smasato/devin_api_client_rb/actions/workflows/rspec.yml?query=branch%3Amain)
3
+ [![Gem Version](https://badge.fury.io/rb/devin_api.svg)](https://badge.fury.io/rb/devin_api)
3
4
 
4
5
  This Ruby gem is a client for the Devin API.
5
6
 
@@ -42,7 +43,7 @@ sessions = client.list_sessions(limit: 10)
42
43
  puts "Sessions: #{sessions}"
43
44
 
44
45
  new_session = client.create_session(prompt: 'Build a simple web app')
45
- session_id = new_session['id']
46
+ session_id = new_session['session_id']
46
47
  puts "Created session: #{session_id}"
47
48
 
48
49
  session_details = client.get_session(session_id)
@@ -76,7 +77,7 @@ new_knowledge = client.create_knowledge(
76
77
  knowledge_id = new_knowledge['id']
77
78
  puts "Created knowledge: #{knowledge_id}"
78
79
 
79
- # Enterprise (for enterprise customers)
80
+ # Enterprise (for enterprise customers), Currently not tested!
80
81
  audit_logs = client.list_audit_logs(start_time: '2023-01-01T00:00:00Z')
81
82
  puts "Audit logs: #{audit_logs}"
82
83
 
@@ -98,7 +99,7 @@ end
98
99
  # Get a collection of sessions
99
100
  sessions = client.sessions
100
101
  sessions.each do |session|
101
- puts "Session ID: #{session.id}, Prompt: #{session[:prompt]}"
102
+ puts "Session ID: #{session.session_id}, Prompt: #{session[:prompt]}"
102
103
  end
103
104
 
104
105
  # Create a new session
@@ -111,9 +112,9 @@ session = client.session('session_id')
111
112
  # Send a message to the session
112
113
  response = session.send_message('How do I start?')
113
114
 
114
- # Upload files to the session
115
- files = [File.open('path/to/file.txt')]
116
- upload_response = session.upload_files(files)
115
+ # Upload file
116
+ file = File.open('path/to/file.txt')
117
+ upload_response = client.attachment.upload_file(file)
117
118
 
118
119
  # Update session tags
119
120
  session.update_tags(['web', 'app'])
@@ -53,10 +53,16 @@ module DevinApi
53
53
  # Executes a POST request
54
54
  # @param [String] path The path to request
55
55
  # @param [Hash] params Body parameters
56
- # @return [Hash] Response body
56
+ # @return [Hash, String] Response body
57
57
  def post(path, params = {})
58
58
  response = connection.post(path) do |req|
59
- req.body = params.to_json
59
+ if params.values.any? { |v| v.is_a?(Faraday::UploadIO) }
60
+ req.headers['Content-Type'] = 'multipart/form-data'
61
+ req.body = params
62
+ else
63
+ req.headers['Content-Type'] = 'application/json'
64
+ req.body = params.to_json
65
+ end
60
66
  end
61
67
  parse_response(response)
62
68
  end
@@ -93,8 +99,8 @@ module DevinApi
93
99
  conn.response :json, content_type: /\bjson$/
94
100
 
95
101
  # Request middlewares
96
- conn.request :json
97
102
  conn.request :multipart
103
+ conn.request :json
98
104
 
99
105
  # Authentication
100
106
  conn.headers['Authorization'] = "Bearer #{config.access_token}"
@@ -35,7 +35,6 @@ module DevinApi
35
35
  []
36
36
  end
37
37
 
38
- @next_cursor = response['pagination'] && response['pagination']['next_cursor']
39
38
  @resources
40
39
  end
41
40
 
@@ -49,10 +48,10 @@ module DevinApi
49
48
  end
50
49
 
51
50
  def next_page
52
- return nil unless @next_cursor
51
+ raise DevinApi::Error::PaginationNotSupported, "Pagination is not supported for #{resource_class.name}" unless resource_class.pagination_supported?
53
52
 
54
53
  new_options = @options.dup
55
- new_options[:cursor] = @next_cursor
54
+ new_options[:offset] = calculate_next_offset
56
55
  self.class.new(@client, @resource_class, new_options)
57
56
  end
58
57
 
@@ -64,5 +63,15 @@ module DevinApi
64
63
  response = client.post(path, attributes)
65
64
  resource_class.new(client, response)
66
65
  end
66
+
67
+ private
68
+
69
+ def offset
70
+ @options[:offset] || 0
71
+ end
72
+
73
+ def calculate_next_offset
74
+ offset + (@options[:limit] || @resources.size)
75
+ end
67
76
  end
68
77
  end
@@ -8,13 +8,9 @@ module DevinApi
8
8
  # @see https://docs.devin.ai/api-reference/attachments/upload-files-for-devin-to-work-with
9
9
  #
10
10
  # @param [File] file File object to upload
11
- # @return [Hash] Response body
11
+ # @return [String] URL where the uploaded file can be accessed
12
12
  def upload_file(file)
13
- payload = Faraday::UploadIO.new(
14
- file.path,
15
- file.content_type || 'application/octet-stream',
16
- File.basename(file.path)
17
- )
13
+ payload = { file: Faraday::UploadIO.new(file.path, 'application/octet-stream', File.basename(file.path)) }
18
14
 
19
15
  connection.post('/v1/attachments', payload).body
20
16
  end
@@ -21,7 +21,7 @@ module DevinApi
21
21
  # @option params [String] :message The message to send (required)
22
22
  # @return [Hash] Response body
23
23
  def send_message(session_id, params = {})
24
- post("/v1/session/#{session_id}/messages", params)
24
+ post("/v1/session/#{session_id}/message", params)
25
25
  end
26
26
 
27
27
  # Update session tags
@@ -32,5 +32,6 @@ module DevinApi
32
32
  class Forbidden < ClientError; end
33
33
  class NotFound < ClientError; end
34
34
  class RateLimited < ClientError; end
35
+ class PaginationNotSupported < ClientError; end
35
36
  end
36
37
  end
@@ -10,12 +10,13 @@ module DevinApi
10
10
  '/v1/attachments'
11
11
  end
12
12
 
13
+ # Upload a file for Devin to work with during sessions
14
+ # @see https://docs.devin.ai/api-reference/attachments/upload-files-for-devin-to-work-with
15
+ #
16
+ # @param [File] file File object to upload
17
+ # @return [String] URL where the uploaded file can be accessed
13
18
  def upload_file(file)
14
- payload = Faraday::UploadIO.new(
15
- file.path,
16
- file.content_type || 'application/octet-stream',
17
- File.basename(file.path)
18
- )
19
+ payload = { file: Faraday::UploadIO.new(file.path, 'application/octet-stream', File.basename(file.path)) }
19
20
 
20
21
  client.connection.post(path, payload).body
21
22
  end
@@ -56,6 +56,10 @@ module DevinApi
56
56
  response = client.post(resource_path, attributes)
57
57
  new(client, response)
58
58
  end
59
+
60
+ def pagination_supported?
61
+ false
62
+ end
59
63
  end
60
64
  end
61
65
  end
@@ -6,12 +6,16 @@ module DevinApi
6
6
  module Resources
7
7
  # Session resource for the Devin API
8
8
  class Session < Base
9
+ def self.pagination_supported?
10
+ true
11
+ end
12
+
9
13
  def path
10
14
  "/v1/session/#{session_id}"
11
15
  end
12
16
 
13
17
  def send_message(message)
14
- client.post("#{path}/messages", { message: message })
18
+ client.post("#{path}/message", { message: message })
15
19
  end
16
20
 
17
21
  def update_tags(tags)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DevinApi
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devin_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masato Sugiyama
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-05-18 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -105,7 +104,6 @@ metadata:
105
104
  source_code_uri: https://github.com/smasato/devin_api_client_rb
106
105
  changelog_uri: https://github.com/smasato/devin_api_client_rb/blob/main/CHANGELOG.md
107
106
  rubygems_mfa_required: 'true'
108
- post_install_message:
109
107
  rdoc_options: []
110
108
  require_paths:
111
109
  - lib
@@ -120,8 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
118
  - !ruby/object:Gem::Version
121
119
  version: '0'
122
120
  requirements: []
123
- rubygems_version: 3.5.22
124
- signing_key:
121
+ rubygems_version: 3.6.7
125
122
  specification_version: 4
126
123
  summary: Unofficial Ruby client for the Devin API
127
124
  test_files: []