agentbill-sdk 2.0.0 → 5.0.1

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: d9f3faf536ea2cdd78d8d97f3200ab80bab8889654b924a2f035a35685aa210f
4
- data.tar.gz: 4397d5f95b5e13bee80a28f7a27165a4f8b5e60c5f478bbfd19b11030651413f
3
+ metadata.gz: 7e9b487391274ecb94dbc031a40f6e30a167e6fa0e30bb257464f68e497871f2
4
+ data.tar.gz: cc6bc10bfdddf68981cd5454f80b4cffc6ea10a244f49f7e1f6582dd154e9b6c
5
5
  SHA512:
6
- metadata.gz: 625bad2690c2dd452d299a5664cca0db3d2e806ab0318ce0a0ce7330b6ce6b873db4213b63e2123286ade6593b13ece94de3b1550e96f5f26b4dd2122c6921ba
7
- data.tar.gz: 3257333096fda49a819738485c457e69741c556b35281648890533e58a3819d631289e9fc170575a55bf598d41a6d2aafe3c7e42bee8c7ea4c25b95bf9937672
6
+ metadata.gz: a4409ffa8bac425a994a09c45d513877d5167e7ca9706c86229de4a6a50f8bf1da729ec1ccab5448c1dda808ed43cb04b2c314840f894801bd203cd8ca608aff
7
+ data.tar.gz: 285d37fb82ae7b3173474c72c47647e2585d8cf983730b16a24adf068a7baae3004078e10c79c493f66960d19921fd531d4aac1b7b6f35688ec7b9e1b541c987
data/CHANGELOG.md CHANGED
@@ -1,27 +1,57 @@
1
1
  # Changelog
2
- # Force sync - Updated to 1.0.2
3
2
 
4
3
  All notable changes to this project will be documented in this file.
5
4
 
6
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
7
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
7
 
9
- ## [1.0.2] - 2025-10-27
8
+ ## [5.0.1] - 2025-11-06
10
9
 
11
- ### Changed
12
- - Version bump for consistency across SDKs
10
+ ### Added
11
+ - **OTEL Correlation Support** - `track_signal()` now accepts optional `trace_id` and `span_id` parameters
12
+ - Enables cost reconciliation by correlating OTEL spans (provider costs) with signals (customer revenue)
13
+ - Parameters are optional - use only when OTEL tracking is enabled for profit margin analysis
14
+
15
+ ### Example
16
+ ```ruby
17
+ # With OTEL correlation for cost reconciliation
18
+ span = agentbill.tracer.start_span('ai_completion')
19
+ # ... make AI call ...
20
+ agentbill.track_signal(
21
+ event_name: 'ai_request',
22
+ revenue: 5.00,
23
+ trace_id: span.trace_id, # Optional
24
+ span_id: span.span_id # Optional
25
+ )
26
+ ```
27
+
28
+ ## [2.0.2] - 2025-11-04
29
+
30
+ ### Fixed
31
+ - **CRITICAL**: Fixed authentication header to use `X-API-Key` instead of `Authorization: Bearer` format
32
+ - Updated `track_signal()` method in agentbill.rb to use correct authentication
33
+ - Updated `flush()` method in tracer.rb to use correct authentication
34
+ - Signals now properly authenticate with record-signals and otel-collector edge functions
35
+
36
+ ## [2.0.1] - 2025-10-25
37
+
38
+ ### Added
39
+ - Enhanced error messages and validation
40
+
41
+ ## [2.0.0] - 2025-10-25
42
+
43
+ ### Added
44
+ - Comprehensive input validation
45
+ - Support for all signal parameters
13
46
 
14
47
  ## [1.0.0] - 2025-10-21
15
48
 
16
49
  ### Added
17
50
  - Initial release of AgentBill Ruby SDK
18
51
  - OpenAI client wrapping with automatic usage tracking
19
- - Anthropic client wrapping with automatic usage tracking
20
52
  - OpenTelemetry-based tracing infrastructure
21
53
  - Custom signal tracking support
22
54
  - Comprehensive test suite with RSpec
23
- - GitHub Actions CI/CD workflows
24
- - RuboCop code quality enforcement
25
55
  - Professional documentation and examples
26
56
  - MIT License
27
57
 
@@ -33,16 +63,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
33
63
  - Error tracking and reporting
34
64
  - Customer-specific tracking support
35
65
  - Debug logging capabilities
36
-
37
- ### Supported Providers
38
- - OpenAI (GPT-4, GPT-3.5, etc.)
39
- - Anthropic (Claude 3.5 Sonnet, etc.)
66
+ - Gem packaging support
40
67
 
41
68
  ### Documentation
42
69
  - Complete README with usage examples
43
70
  - API documentation
44
71
  - Contributing guidelines
45
72
  - Security policy
46
- - Code of conduct
47
-
48
- [1.0.0]: https://github.com/Agent-Bill/Ruby/releases/tag/v1.0.0
73
+ - Code examples
data/README.md CHANGED
@@ -23,8 +23,9 @@ bundle install
23
23
 
24
24
  ### From Source
25
25
  ```bash
26
- git clone https://github.com/Agent-Bill/Ruby.git
27
- cd agentbill-ruby
26
+ # Clone your repository and install
27
+ git clone https://github.com/yourusername/agentbill-ruby-sdk.git
28
+ cd agentbill-ruby-sdk
28
29
  gem build agentbill.gemspec
29
30
  gem install agentbill-1.0.0.gem
30
31
  ```
@@ -140,7 +141,7 @@ gem push agentbill-1.0.0.gem
140
141
 
141
142
  ## GitHub Repository Setup
142
143
 
143
- 1. Create repository: `agentbill-ruby`
144
+ 1. Create your GitHub repository (e.g., `agentbill-ruby-sdk`)
144
145
  2. Push all files from `lib/` directory
145
146
  3. Tag releases: `git tag v1.0.0 && git push origin v1.0.0`
146
147
 
data/SECURITY.md CHANGED
@@ -16,7 +16,7 @@ We take security vulnerabilities seriously. If you discover a security issue, pl
16
16
 
17
17
  **DO NOT** create a public GitHub issue for security vulnerabilities.
18
18
 
19
- Instead, please email: security@agentbill.com
19
+ Instead, please email: support@agentbill.io
20
20
 
21
21
  Include:
22
22
  - Description of the vulnerability
@@ -68,6 +68,6 @@ The AgentBill SDK includes:
68
68
 
69
69
  ## Questions?
70
70
 
71
- For general security questions, email: security@agentbill.com
71
+ For general security questions, email: support@agentbill.io
72
72
 
73
73
  Thank you for helping keep AgentBill secure! 🔒
@@ -0,0 +1,50 @@
1
+ =begin
2
+ OpenAI with Custom Event Names Example
3
+
4
+ Shows how to pass custom event_name per AI call for better tracking
5
+ =end
6
+
7
+ require 'agentbill'
8
+ require 'openai'
9
+
10
+ # Initialize AgentBill
11
+ agentbill = AgentBill::Client.init({
12
+ api_key: ENV['AGENTBILL_API_KEY'] || 'your-api-key',
13
+ agent_id: 'agent-uuid', # Your agent UUID
14
+ customer_id: 'customer-123',
15
+ debug: true
16
+ })
17
+
18
+ # Wrap your OpenAI client
19
+ client = agentbill.wrap_openai(OpenAI::Client.new(
20
+ access_token: ENV['OPENAI_API_KEY']
21
+ ))
22
+
23
+ # Make a request with custom event name for code generation
24
+ response = client.chat({
25
+ model: 'gpt-4o-mini',
26
+ messages: [
27
+ { role: 'system', content: 'You are a code generation assistant.' },
28
+ { role: 'user', content: 'Write a function to calculate fibonacci numbers' }
29
+ ],
30
+ agentbill_options: {
31
+ event_name: 'code_generation'
32
+ }
33
+ })
34
+
35
+ puts response['choices'][0]['message']['content']
36
+
37
+ # Different event for chat
38
+ chat_response = client.chat({
39
+ model: 'gpt-4o-mini',
40
+ messages: [
41
+ { role: 'user', content: 'What is the weather like?' }
42
+ ],
43
+ agentbill_options: {
44
+ event_name: 'chat_response'
45
+ }
46
+ })
47
+
48
+ puts chat_response['choices'][0]['message']['content']
49
+
50
+ # All usage (tokens, cost, latency) is automatically tracked with custom event names
@@ -61,7 +61,7 @@ module AgentBill
61
61
  http.use_ssl = true
62
62
 
63
63
  request = Net::HTTP::Post.new(uri.path)
64
- request['Authorization'] = "Bearer #{@api_key}"
64
+ request['X-API-Key'] = @api_key
65
65
  request['Content-Type'] = 'application/json'
66
66
  request.body = payload.to_json
67
67
 
@@ -1,3 +1,3 @@
1
1
  module AgentBill
2
- VERSION = "2.0.0"
2
+ VERSION = "5.0.1"
3
3
  end
data/lib/agentbill.rb CHANGED
@@ -74,12 +74,14 @@ module AgentBill
74
74
  end
75
75
  end
76
76
 
77
- def track_usage(model, provider, input_tokens, output_tokens, latency_ms, cost)
77
+ def track_usage(model, provider, input_tokens, output_tokens, latency_ms, cost, event_name = 'ai_request')
78
78
  uri = URI("#{@config[:base_url] || 'https://bgwyprqxtdreuutzpbgw.supabase.co'}/functions/v1/track-ai-usage")
79
79
 
80
80
  payload = {
81
81
  api_key: @config[:api_key],
82
82
  customer_id: @config[:customer_id],
83
+ agent_id: @config[:agent_id],
84
+ event_name: event_name,
83
85
  model: model,
84
86
  provider: provider,
85
87
  prompt_tokens: input_tokens,
@@ -116,6 +118,10 @@ module AgentBill
116
118
  messages = params[:messages] || []
117
119
  max_tokens = params[:max_tokens] || params[:max_completion_tokens] || 1000
118
120
 
121
+ # Extract event_name from agentbill_options if provided (don't pass to OpenAI)
122
+ agentbill_options = params.delete(:agentbill_options) || {}
123
+ event_name = agentbill_options[:event_name] || 'ai_request'
124
+
119
125
  # Phase 1: Validate budget BEFORE API call
120
126
  validation = config[:_client].send(:validate_request, model, messages, max_tokens)
121
127
  unless validation['allowed']
@@ -142,7 +148,7 @@ module AgentBill
142
148
  output_tokens = response.dig(:usage, :completion_tokens) || 0
143
149
  cost = config[:_client].send(:estimate_cost, model, input_tokens, output_tokens)
144
150
 
145
- config[:_client].send(:track_usage, model, 'openai', input_tokens, output_tokens, latency, cost)
151
+ config[:_client].send(:track_usage, model, 'openai', input_tokens, output_tokens, latency, cost, event_name)
146
152
 
147
153
  span.set_attributes({
148
154
  'response.prompt_tokens' => input_tokens,
@@ -227,10 +233,12 @@ module AgentBill
227
233
  client
228
234
  end
229
235
 
230
- # Track a comprehensive signal with all 68 parameters
236
+ # Track a comprehensive signal with all 68 parameters including trace_id and span_id
231
237
  #
232
- # Supports all parameters:
238
+ # Supports optional trace_id and span_id for OTEL correlation:
233
239
  # - event_name (required)
240
+ # - trace_id (optional) - For correlating with OTEL spans for cost reconciliation
241
+ # - span_id (optional) - For correlating with OTEL spans for cost reconciliation
234
242
  # - data_source, timestamp
235
243
  # - agent_external_id, customer_external_id, account_external_id, user_external_id,
236
244
  # order_external_id, session_id, conversation_id, thread_id
@@ -243,17 +251,25 @@ module AgentBill
243
251
  # - feedback_score, user_satisfaction, error_type, error_message, retry_count, success_rate
244
252
  # - tags, category, priority, severity, compliance_flag, data_classification
245
253
  # - product_id, feature_flag, environment, deployment_version, region, tenant_id
246
- # - parent_span_id, trace_id
254
+ # - parent_span_id
247
255
  # - custom_dimensions, metadata, data
248
256
  #
249
257
  # Example:
258
+ # # Basic tracking
250
259
  # agentbill.track_signal(
251
260
  # event_name: "user_conversion",
252
261
  # revenue: 99.99,
253
- # customer_external_id: "cust_123",
254
- # experiment_id: "exp_abc",
255
- # conversion_type: "purchase",
256
- # tags: ["checkout", "success"]
262
+ # customer_external_id: "cust_123"
263
+ # )
264
+ #
265
+ # # With OTEL correlation
266
+ # span = agentbill.tracer.start_span('ai_completion')
267
+ # # ... make AI call ...
268
+ # agentbill.track_signal(
269
+ # event_name: "ai_request",
270
+ # revenue: 5.00,
271
+ # trace_id: span.trace_id, # Optional
272
+ # span_id: span.span_id # Optional
257
273
  # )
258
274
  def track_signal(**params)
259
275
  raise ArgumentError, "event_name is required" unless params[:event_name]
@@ -263,6 +279,18 @@ module AgentBill
263
279
  # Add timestamp if not provided
264
280
  params[:timestamp] ||= Time.now.to_f
265
281
 
282
+ # Auto-fill customer_id or customer_external_id from config if not provided
283
+ if !params[:customer_id] && !params[:customer_external_id] && @config[:customer_id]
284
+ # Check if it's a UUID format - send as customer_id, else customer_external_id
285
+ uuid_regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
286
+ is_uuid = @config[:customer_id].match?(uuid_regex)
287
+ if is_uuid
288
+ params[:customer_id] = @config[:customer_id]
289
+ else
290
+ params[:customer_external_id] = @config[:customer_id]
291
+ end
292
+ end
293
+
266
294
  # Remove nil values
267
295
  payload = params.reject { |_, v| v.nil? }
268
296
 
@@ -271,14 +299,15 @@ module AgentBill
271
299
  http.use_ssl = true
272
300
 
273
301
  request = Net::HTTP::Post.new(uri.path)
274
- request['Authorization'] = "Bearer #{@config[:api_key]}"
302
+ request['X-API-Key'] = @config[:api_key]
275
303
  request['Content-Type'] = 'application/json'
276
304
  request.body = payload.to_json
277
305
 
278
306
  response = http.request(request)
279
307
 
280
308
  if @config[:debug]
281
- puts "[AgentBill] Signal tracked: #{params[:event_name]}"
309
+ trace_info = params[:trace_id] ? " (trace: #{params[:trace_id]})" : ""
310
+ puts "[AgentBill] Signal tracked: #{params[:event_name]}#{trace_info}"
282
311
  end
283
312
 
284
313
  response.code == '200'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agentbill-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - AgentBill
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-10-31 00:00:00.000000000 Z
11
+ date: 2025-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,7 @@ files:
66
66
  - examples/anthropic_basic.rb
67
67
  - examples/manual_otel_tracking.rb
68
68
  - examples/openai_basic.rb
69
+ - examples/openai_custom_event.rb
69
70
  - examples/zero_config.rb
70
71
  - lib/agentbill.rb
71
72
  - lib/agentbill/tracer.rb