agentbill-sdk 2.0.1 → 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 +4 -4
- data/CHANGELOG.md +39 -14
- data/README.md +4 -3
- data/SECURITY.md +2 -2
- data/examples/openai_custom_event.rb +50 -0
- data/lib/agentbill/tracer.rb +1 -1
- data/lib/agentbill/version.rb +1 -1
- data/lib/agentbill.rb +40 -11
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7e9b487391274ecb94dbc031a40f6e30a167e6fa0e30bb257464f68e497871f2
|
|
4
|
+
data.tar.gz: cc6bc10bfdddf68981cd5454f80b4cffc6ea10a244f49f7e1f6582dd154e9b6c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
## [
|
|
8
|
+
## [5.0.1] - 2025-11-06
|
|
10
9
|
|
|
11
|
-
###
|
|
12
|
-
-
|
|
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
|
|
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
|
-
|
|
27
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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
|
data/lib/agentbill/tracer.rb
CHANGED
data/lib/agentbill/version.rb
CHANGED
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
|
|
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
|
|
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
|
-
#
|
|
255
|
-
#
|
|
256
|
-
#
|
|
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['
|
|
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
|
-
|
|
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:
|
|
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-
|
|
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
|