driftgate-sdk 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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +32 -0
  3. data/lib/driftgate_sdk.rb +149 -0
  4. metadata +48 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7e9548e25eb817913f839fbf3fb79c281555fe93bbf5334a94ecc3547f322fce
4
+ data.tar.gz: 7c059174999ffa60dfe982e29980b4af2aa05e6b7762f4847f8a00db0f54fea5
5
+ SHA512:
6
+ metadata.gz: d820734ab5c4359abd3788eee60da12c0b1e0820853a9b6e8a058abe758698e21656c63d7335465ddbff38f32c8a89d5403e32223349bda826a1ab9161e1ef98
7
+ data.tar.gz: 81c4ac11d3f14b53d5a9c3ba12d7dc7751392c4063a04287b4e3e6df25d4a452f6e89e2f4303415063a2197861cda9f75c62982b368af901bd3f48cd881639e7
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # DriftGate Ruby SDK
2
+
3
+ Canonical V4 envelope SDK for Ruby.
4
+
5
+ See canonical envelope docs: [`docs/sdk/response-envelope.md`](/Users/jordandavis/Documents/Code/DriftGateAI/driftgate-v4-sdk-wt/docs/sdk/response-envelope.md).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ gem install driftgate-sdk -v 0.1.0
11
+ ```
12
+
13
+ ## Hello World (2 lines)
14
+
15
+ ```ruby
16
+ session = DriftGateSDK::Client.new(base_url: "https://api.driftgate.ai").session.start(agent: "refund-agent")
17
+ session.execute(input: { orderId: "123" })
18
+ ```
19
+
20
+ ## Full Example
21
+
22
+ ```ruby
23
+ client = DriftGateSDK::Client.new(base_url: "https://api.driftgate.ai", bearer_token: ENV.fetch("DRIFTGATE_TOKEN"))
24
+ session = client.session.start(
25
+ agent: "refund-agent",
26
+ policy: { ref: "refund", version: "2026-02" },
27
+ route: { provider: "openai", model: "gpt-4.1-mini", region: "us-east-1" },
28
+ risk: { decision: "review" }
29
+ )
30
+ response = session.execute(input: { orderId: "123" })
31
+ puts response.fetch("meta").fetch("requestId")
32
+ ```
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "net/http"
5
+ require "uri"
6
+
7
+ module DriftGateSDK
8
+ ERROR_CODES = %w[
9
+ AUTH_INVALID
10
+ POLICY_DENIED
11
+ RISK_EXCEEDED
12
+ ROUTE_UNAVAILABLE
13
+ TOOL_BLOCKED
14
+ RATE_LIMITED
15
+ TIMEOUT
16
+ INTERNAL
17
+ ].freeze
18
+
19
+ class Error < StandardError
20
+ attr_reader :code, :status, :retryable, :request_id, :details
21
+
22
+ def initialize(code:, message:, status:, retryable:, request_id: nil, details: nil)
23
+ super(message)
24
+ @code = code
25
+ @status = status
26
+ @retryable = retryable
27
+ @request_id = request_id
28
+ @details = details
29
+ end
30
+ end
31
+
32
+ class SessionHandle
33
+ attr_reader :session, :start_envelope
34
+
35
+ def initialize(client:, session:, start_envelope:)
36
+ @client = client
37
+ @session = session
38
+ @start_envelope = start_envelope
39
+ end
40
+
41
+ def session_id
42
+ @session.fetch("sessionId")
43
+ end
44
+
45
+ def execute(input:, policy: nil, route: nil, risk: nil, workflow_version_id: nil)
46
+ payload = { input: input }
47
+ payload[:policy] = policy if policy
48
+ payload[:route] = route if route
49
+ payload[:risk] = risk if risk
50
+ payload[:workflowVersionId] = workflow_version_id if workflow_version_id
51
+ @client.execute_session(session_id: session_id, payload: payload)
52
+ end
53
+ end
54
+
55
+ class Client
56
+ attr_accessor :api_key, :bearer_token
57
+
58
+ def initialize(base_url:, api_key: nil, bearer_token: nil, http: Net::HTTP)
59
+ @base_url = base_url.sub(%r{/$}, "")
60
+ @api_key = api_key
61
+ @bearer_token = bearer_token
62
+ @http = http
63
+ end
64
+
65
+ def session
66
+ self
67
+ end
68
+
69
+ def start(agent:, workspace_id: nil, subject: nil, metadata: nil, policy: nil, route: nil, risk: nil, workflow_version_id: nil, expires_at: nil)
70
+ payload = { agent: agent }
71
+ payload[:workspaceId] = workspace_id if workspace_id
72
+ payload[:subject] = subject if subject
73
+ payload[:metadata] = metadata if metadata
74
+ payload[:policy] = policy if policy
75
+ payload[:route] = route if route
76
+ payload[:risk] = risk if risk
77
+ payload[:workflowVersionId] = workflow_version_id if workflow_version_id
78
+ payload[:expiresAt] = expires_at if expires_at
79
+
80
+ envelope = request(method: "POST", path: "/v4/sessions.start", payload: payload)
81
+ raise_envelope_error(envelope) unless envelope.fetch("ok")
82
+
83
+ SessionHandle.new(client: self, session: envelope.fetch("data").fetch("session"), start_envelope: envelope)
84
+ end
85
+
86
+ def execute_session(session_id:, payload:)
87
+ envelope = request(method: "POST", path: "/v4/sessions/#{session_id}/executions.execute", payload: payload)
88
+ raise_envelope_error(envelope) unless envelope.fetch("ok")
89
+ envelope
90
+ end
91
+
92
+ def execute(agent:, input:, workspace_id: nil, subject: nil, metadata: nil, policy: nil, route: nil, risk: nil, workflow_version_id: nil)
93
+ payload = {
94
+ agent: agent,
95
+ input: input
96
+ }
97
+ payload[:workspaceId] = workspace_id if workspace_id
98
+ payload[:subject] = subject if subject
99
+ payload[:metadata] = metadata if metadata
100
+ payload[:policy] = policy if policy
101
+ payload[:route] = route if route
102
+ payload[:risk] = risk if risk
103
+ payload[:workflowVersionId] = workflow_version_id if workflow_version_id
104
+
105
+ envelope = request(method: "POST", path: "/v4/execute", payload: payload)
106
+ raise_envelope_error(envelope) unless envelope.fetch("ok")
107
+ envelope
108
+ end
109
+
110
+ private
111
+
112
+ def request(method:, path:, payload:)
113
+ uri = URI.parse("#{@base_url}#{path}")
114
+ request_class = Net::HTTP.const_get(method.capitalize)
115
+ request = request_class.new(uri)
116
+ request["content-type"] = "application/json"
117
+ request["x-driftgate-api-key"] = @api_key if @api_key
118
+ request["authorization"] = "Bearer #{@bearer_token}" if @bearer_token
119
+ request.body = JSON.generate(payload)
120
+
121
+ response = @http.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
122
+ http.request(request)
123
+ end
124
+
125
+ body = response.body && !response.body.empty? ? JSON.parse(response.body) : {}
126
+ if response.code.to_i >= 400
127
+ raise_envelope_error(body)
128
+ end
129
+ body
130
+ end
131
+
132
+ def raise_envelope_error(payload)
133
+ if payload.is_a?(Hash) && payload["error"].is_a?(Hash)
134
+ error = payload["error"]
135
+ meta = payload["meta"].is_a?(Hash) ? payload["meta"] : {}
136
+ raise Error.new(
137
+ code: error.fetch("code", "INTERNAL"),
138
+ message: error.fetch("message", "request failed"),
139
+ status: error.fetch("status", 500),
140
+ retryable: error.fetch("retryable", false),
141
+ request_id: meta["requestId"],
142
+ details: error["details"]
143
+ )
144
+ end
145
+
146
+ raise Error.new(code: "INTERNAL", message: "request failed", status: 500, retryable: false)
147
+ end
148
+ end
149
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: driftgate-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - DriftGate
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-03-03 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: DriftGate Ruby SDK for canonical V4 session and execution APIs.
14
+ email:
15
+ - support@driftgate.ai
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - lib/driftgate_sdk.rb
22
+ homepage: https://docs.driftgate.ai
23
+ licenses:
24
+ - Apache-2.0
25
+ metadata:
26
+ homepage_uri: https://docs.driftgate.ai
27
+ source_code_uri: https://github.com/driftgate/driftgate-sdk
28
+ changelog_uri: https://docs.driftgate.ai/changelog
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: 3.0.0
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubygems_version: 3.5.22
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: DriftGate canonical V4 envelope SDK
48
+ test_files: []