antigravity-sdk 0.5.4 → 0.5.5
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/VERSION +1 -1
- data/lib/antigravity/diagnostics.rb +229 -0
- data/lib/antigravity.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fff0721cd596c0cafa8734522f4a88f26813dfe9afc71941389cb79bf109cfa4
|
|
4
|
+
data.tar.gz: 0f975b13b784c682519ee0f60e9f0cb574535e819b13e9224bdf3abb74fbc91f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fe0700f980ab6d196252151616ecb79181efa484ce824d5a65f63e75826536a9800f8a2f49450296a92aace284f1270e243115d1f90055098a95fce4a986c446
|
|
7
|
+
data.tar.gz: 0174bc0e5167c6d406d32f2f3e244e0f4860c2cb6e65237bbe9d591835f05ba8fcf1ab8d501f80e56fb1130c73f93b138f2d3b18c457d2f16e983f4d668bf79f
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.5.
|
|
1
|
+
0.5.5
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Diagnostics module for Antigravity SDK.
|
|
4
|
+
# Probes environment, API key, harness binary, gems, and Gemini API models.
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# Antigravity::Diagnostics.run! # Full colorful output
|
|
8
|
+
# Antigravity::Diagnostics.summary # Returns hash of all data
|
|
9
|
+
# Antigravity::Diagnostics.check_api_key # Just the key check
|
|
10
|
+
#
|
|
11
|
+
module Antigravity
|
|
12
|
+
module Diagnostics
|
|
13
|
+
C = Antigravity::Colors
|
|
14
|
+
|
|
15
|
+
# Main entry point — prints full colorful diagnostic report
|
|
16
|
+
def self.run!(verbose: false)
|
|
17
|
+
data = summary
|
|
18
|
+
|
|
19
|
+
puts ''
|
|
20
|
+
puts C.bold("💎 Antigravity SDK #{C.cyan("v#{data[:sdk_version]}")} — Diagnostics")
|
|
21
|
+
puts C.dim('=' * 56)
|
|
22
|
+
|
|
23
|
+
# Ruby
|
|
24
|
+
puts section('💻 Runtime')
|
|
25
|
+
puts field('Ruby', "#{data[:ruby_version]} (#{data[:ruby_platform]})")
|
|
26
|
+
puts field('Bundler', data[:bundler_version])
|
|
27
|
+
puts field('rv', data[:rv_version] || C.dim('not detected'))
|
|
28
|
+
|
|
29
|
+
# API Key
|
|
30
|
+
puts section('🔑 Authentication')
|
|
31
|
+
if data[:api_key_present]
|
|
32
|
+
masked = data[:api_key_prefix] + '****' + data[:api_key_suffix]
|
|
33
|
+
source = data[:api_key_source]
|
|
34
|
+
puts field('API Key', "#{C.green(masked)} (#{C.dim(source)})")
|
|
35
|
+
else
|
|
36
|
+
puts field('API Key', C.red('⚠️ NOT SET — export GEMINI_API_KEY'))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Model
|
|
40
|
+
puts field('Model', data[:default_model])
|
|
41
|
+
if data[:model_source] == 'default'
|
|
42
|
+
puts C.dim(" └─ using SDK default (set GEMINI_MODEL or ANTIGRAVITY_MODEL to override)")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Harness
|
|
46
|
+
puts section('📦 Harness')
|
|
47
|
+
if data[:harness_exists]
|
|
48
|
+
size_mb = (data[:harness_size] / 1_048_576.0).round(1)
|
|
49
|
+
mtime = data[:harness_mtime]&.strftime('%Y-%m-%d %H:%M') || '?'
|
|
50
|
+
puts field('Path', data[:harness_path])
|
|
51
|
+
puts field('Size', "#{size_mb}MB")
|
|
52
|
+
puts field('Modified', mtime)
|
|
53
|
+
puts field('Arch', data[:harness_arch] || C.dim('unknown'))
|
|
54
|
+
else
|
|
55
|
+
puts field('Path', C.red("⚠️ NOT FOUND at #{data[:harness_path]}"))
|
|
56
|
+
puts C.dim(" └─ run: just harness-fetch")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Gems
|
|
60
|
+
puts section('📚 Dependencies')
|
|
61
|
+
data[:gems].each do |name, ver|
|
|
62
|
+
status = ver ? C.green(ver) : C.red('missing')
|
|
63
|
+
puts field(name, status)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Timeouts
|
|
67
|
+
puts section('⏱️ Timeouts')
|
|
68
|
+
puts field('LLM', "#{data[:timeout_llm]}s")
|
|
69
|
+
puts field('WebSocket', "#{data[:timeout_ws]}s")
|
|
70
|
+
puts field('Handshake', "#{data[:timeout_handshake]}s")
|
|
71
|
+
|
|
72
|
+
# Gemini API models probe (optional, needs network)
|
|
73
|
+
if data[:api_key_present] && verbose
|
|
74
|
+
puts section('🤖 Gemini API Models')
|
|
75
|
+
models = probe_models(data[:api_key_raw])
|
|
76
|
+
if models
|
|
77
|
+
puts field('Available', "#{C.green(models[:count].to_s)} models")
|
|
78
|
+
flash = models[:names].select { |n| n.include?('flash') }.first(3)
|
|
79
|
+
pro = models[:names].select { |n| n.include?('pro') }.first(3)
|
|
80
|
+
puts field('Flash', flash.join(', ')) unless flash.empty?
|
|
81
|
+
puts field('Pro', pro.join(', ')) unless pro.empty?
|
|
82
|
+
else
|
|
83
|
+
puts field('Status', C.yellow('⚠️ Could not reach Gemini API'))
|
|
84
|
+
end
|
|
85
|
+
elsif data[:api_key_present]
|
|
86
|
+
puts C.dim("\n Tip: run with --verbose to probe Gemini API models")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Overall status
|
|
90
|
+
puts ''
|
|
91
|
+
issues = health_check(data)
|
|
92
|
+
if issues.empty?
|
|
93
|
+
puts C.green('✅ All checks passed — ready to go!')
|
|
94
|
+
else
|
|
95
|
+
puts C.yellow("⚠️ #{issues.length} issue(s) found:")
|
|
96
|
+
issues.each { |i| puts C.yellow(" • #{i}") }
|
|
97
|
+
end
|
|
98
|
+
puts ''
|
|
99
|
+
|
|
100
|
+
data
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Returns a structured hash of all diagnostic data
|
|
104
|
+
def self.summary
|
|
105
|
+
config = Antigravity.config
|
|
106
|
+
api_key = config.api_key&.strip
|
|
107
|
+
|
|
108
|
+
# Detect API key source
|
|
109
|
+
api_key_source = if ENV['GEMINI_API_KEY'] && !ENV['GEMINI_API_KEY'].empty?
|
|
110
|
+
'GEMINI_API_KEY'
|
|
111
|
+
else
|
|
112
|
+
'.env or config'
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Detect model source
|
|
116
|
+
model_source = if ENV['GEMINI_MODEL'] && !ENV['GEMINI_MODEL'].empty?
|
|
117
|
+
'GEMINI_MODEL'
|
|
118
|
+
elsif ENV['ANTIGRAVITY_MODEL'] && !ENV['ANTIGRAVITY_MODEL'].empty?
|
|
119
|
+
'ANTIGRAVITY_MODEL'
|
|
120
|
+
else
|
|
121
|
+
'default'
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Harness binary info
|
|
125
|
+
harness_path = config.harness_path
|
|
126
|
+
harness_stat = File.stat(harness_path) rescue nil
|
|
127
|
+
harness_arch = detect_arch(harness_path) if harness_stat
|
|
128
|
+
|
|
129
|
+
# rv detection
|
|
130
|
+
rv_version = detect_rv
|
|
131
|
+
|
|
132
|
+
# Gem versions — stdlib gems need special detection
|
|
133
|
+
gem_names = %w[websocket dotenv json logger]
|
|
134
|
+
gems = gem_names.to_h do |g|
|
|
135
|
+
ver = Gem.loaded_specs[g]&.version&.to_s
|
|
136
|
+
# Stdlib gems (json, logger) may not appear in loaded_specs
|
|
137
|
+
ver ||= begin
|
|
138
|
+
old_verbose = $VERBOSE
|
|
139
|
+
$VERBOSE = nil
|
|
140
|
+
require g
|
|
141
|
+
$VERBOSE = old_verbose
|
|
142
|
+
defined?(Gem) ? Gem.loaded_specs[g]&.version&.to_s : nil
|
|
143
|
+
rescue LoadError
|
|
144
|
+
nil
|
|
145
|
+
end
|
|
146
|
+
# Last resort: check if the constant exists (stdlib bundled)
|
|
147
|
+
ver ||= '(stdlib)' if %w[json logger].include?(g)
|
|
148
|
+
[g, ver]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
{
|
|
152
|
+
sdk_version: Antigravity::VERSION,
|
|
153
|
+
ruby_version: RUBY_VERSION,
|
|
154
|
+
ruby_platform: RUBY_PLATFORM,
|
|
155
|
+
bundler_version: Bundler::VERSION,
|
|
156
|
+
rv_version: rv_version,
|
|
157
|
+
api_key_present: api_key && !api_key.empty?,
|
|
158
|
+
api_key_prefix: api_key ? api_key[0..5] : '',
|
|
159
|
+
api_key_suffix: api_key ? api_key[-2..] : '',
|
|
160
|
+
api_key_source: api_key_source,
|
|
161
|
+
api_key_raw: api_key,
|
|
162
|
+
default_model: config.default_model,
|
|
163
|
+
model_source: model_source,
|
|
164
|
+
harness_path: harness_path,
|
|
165
|
+
harness_exists: !harness_stat.nil?,
|
|
166
|
+
harness_size: harness_stat&.size || 0,
|
|
167
|
+
harness_mtime: harness_stat&.mtime,
|
|
168
|
+
harness_arch: harness_arch,
|
|
169
|
+
timeout_llm: config.timeout_llm,
|
|
170
|
+
timeout_ws: config.timeout_ws,
|
|
171
|
+
timeout_handshake: config.timeout_handshake,
|
|
172
|
+
gems: gems,
|
|
173
|
+
}
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Quick health check — returns array of issue strings
|
|
177
|
+
def self.health_check(data = nil)
|
|
178
|
+
data ||= summary
|
|
179
|
+
issues = []
|
|
180
|
+
issues << 'GEMINI_API_KEY is not set' unless data[:api_key_present]
|
|
181
|
+
issues << "Harness binary not found at #{data[:harness_path]}" unless data[:harness_exists]
|
|
182
|
+
issues << 'websocket gem not loaded' unless data.dig(:gems, 'websocket')
|
|
183
|
+
issues
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
private
|
|
187
|
+
|
|
188
|
+
def self.section(title)
|
|
189
|
+
"\n#{C.bold(title)}"
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def self.field(label, value)
|
|
193
|
+
" #{C.cyan(label.to_s.ljust(12))} #{value}"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def self.detect_arch(path)
|
|
197
|
+
return nil unless File.exist?(path)
|
|
198
|
+
output = `file '#{path}' 2>/dev/null`.strip
|
|
199
|
+
case output
|
|
200
|
+
when /arm64/ then 'arm64 (Apple Silicon)'
|
|
201
|
+
when /x86_64/ then 'x86_64 (Intel)'
|
|
202
|
+
when /ELF.*64/ then 'linux-amd64'
|
|
203
|
+
else output.split(':').last&.strip&.slice(0, 40)
|
|
204
|
+
end
|
|
205
|
+
rescue
|
|
206
|
+
nil
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def self.detect_rv
|
|
210
|
+
`rv --version 2>/dev/null`.strip.then { |v| v.empty? ? nil : v }
|
|
211
|
+
rescue
|
|
212
|
+
nil
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def self.probe_models(api_key)
|
|
216
|
+
require 'net/http'
|
|
217
|
+
require 'json'
|
|
218
|
+
uri = URI("https://generativelanguage.googleapis.com/v1beta/models?key=#{api_key}")
|
|
219
|
+
resp = Net::HTTP.get_response(uri)
|
|
220
|
+
return nil unless resp.is_a?(Net::HTTPSuccess)
|
|
221
|
+
body = JSON.parse(resp.body)
|
|
222
|
+
models = body['models'] || []
|
|
223
|
+
names = models.map { |m| m['name'].to_s.sub('models/', '') }.sort
|
|
224
|
+
{ count: names.length, names: names }
|
|
225
|
+
rescue
|
|
226
|
+
nil
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
data/lib/antigravity.rb
CHANGED
|
@@ -29,6 +29,7 @@ require_relative "antigravity/connection/local_connection"
|
|
|
29
29
|
require_relative "antigravity/conversation"
|
|
30
30
|
require_relative "antigravity/colors"
|
|
31
31
|
require_relative "antigravity/lifecycle_logger"
|
|
32
|
+
require_relative "antigravity/diagnostics"
|
|
32
33
|
require_relative "antigravity/agent"
|
|
33
34
|
|
|
34
35
|
module Antigravity
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: antigravity-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Riccardo Carlesso
|
|
@@ -84,6 +84,7 @@ files:
|
|
|
84
84
|
- lib/antigravity/connection/local_connection.rb
|
|
85
85
|
- lib/antigravity/connection/websocket_client.rb
|
|
86
86
|
- lib/antigravity/conversation.rb
|
|
87
|
+
- lib/antigravity/diagnostics.rb
|
|
87
88
|
- lib/antigravity/emojis.rb
|
|
88
89
|
- lib/antigravity/errors.rb
|
|
89
90
|
- lib/antigravity/guards.rb
|