Class: Antigravity::Agent
Instance Attribute Summary collapse
-
#api_key ⇒ Object
Returns the value of attribute api_key.
-
#born_at ⇒ Object
readonly
Returns the value of attribute born_at.
-
#client ⇒ Object
readonly
Returns the value of attribute client.
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
-
#conversation ⇒ Object
readonly
Returns the value of attribute conversation.
-
#hooks ⇒ Object
readonly
Returns the value of attribute hooks.
-
#logger_guard ⇒ Object
readonly
Returns the value of attribute logger_guard.
-
#model ⇒ Object
Returns the value of attribute model.
-
#policies ⇒ Object
readonly
Returns the value of attribute policies.
-
#policy ⇒ Object
readonly
Returns the value of attribute policy.
-
#sidecars ⇒ Object
readonly
Returns the value of attribute sidecars.
-
#skills ⇒ Object
readonly
Returns the value of attribute skills.
-
#system_instruction ⇒ Object
Returns the value of attribute system_instruction.
-
#tools ⇒ Object
readonly
Returns the value of attribute tools.
-
#workspace ⇒ Object
Returns the value of attribute workspace.
Class Method Summary collapse
-
.list_skills(path_or_url) ⇒ Array<String>
List discovered skills in a container path (without loading them).
-
.open(**kwargs, &block) ⇒ Object
Block form: opens connection, yields agent, auto-closes.
Instance Method Summary collapse
-
#add_inline_skill(name:, description:, instructions:) ⇒ Skill
Create and add an inline skill (no file needed).
-
#add_skill(path_or_url, skill_name: nil) ⇒ Skill
(also: #load_skill)
Add a single skill by path or GitHub URL.
-
#add_skills(paths_or_urls) ⇒ Array<Skill>
Add one or more skills by path or GitHub URL.
- #after_response(&block) ⇒ Object
- #after_tool_call(&block) ⇒ Object (also: #on_tool_call)
- #attach_logger(log_target = nil, level: :info, silent_notice: false) ⇒ Object
- #attach_sidecar(sidecar) ⇒ Object
- #before_prompt(&block) ⇒ Object
- #before_tool_call(&block) ⇒ Object
- #close! ⇒ Object
-
#connect! ⇒ Object
--- Connection Lifecycle ---.
- #connected? ⇒ Boolean
-
#conversation_id ⇒ Object
--- Metadata Accessors (mirrors Python SDK) ---.
- #emit_sidecar_event(event_type, payload = {}) ⇒ Object
- #enforce(policy) ⇒ Object
-
#initialize(model: nil, system_instruction: nil, tools: [], skills: [], policies: [], policy: nil, workspace: nil, auto_logger: true, log_file: nil) {|_self| ... } ⇒ Agent
constructor
A new instance of Agent.
-
#prompt(message, timeout: Antigravity.config.timeout_llm, &block) ⇒ Object
(also: #ask)
--- Chat ---.
-
#register_tool(tool_or_name = nil, description: "", &block) ⇒ Object
--- Tool Registration ---.
- #session_summary ⇒ Object
- #turn_count ⇒ Object
-
#uptime ⇒ Object
Seconds since agent was created.
-
#uptime_human ⇒ Object
Human-readable uptime: "1m 23.4s", "7.3s".
Methods inherited from Base
Methods included from Emojifiable
Constructor Details
#initialize(model: nil, system_instruction: nil, tools: [], skills: [], policies: [], policy: nil, workspace: nil, auto_logger: true, log_file: nil) {|_self| ... } ⇒ Agent
Returns a new instance of Agent.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/antigravity/agent.rb', line 10 def initialize(model: nil, system_instruction: nil, tools: [], skills: [], policies: [], policy: nil, workspace: nil, auto_logger: true, log_file: nil, &block) @model = model || Antigravity.config.default_model @api_key = Antigravity.config.api_key @system_instruction = system_instruction @workspace = resolve_workspace(workspace) @tools = tools.dup @skills = [] @policies = [] @sidecars = [] @hooks = Hooks.new @client = Client.new @logger_guard = nil @connection = nil @conversation = nil @connected = false @born_at = Time.now # Register pre-provided tools into the tool runner @tool_runner = ToolRunner.new @tools.each { |t| @tool_runner.register(t) } # Load skills provided at construction (local paths or GitHub URLs) add_skills(skills) unless Array(skills).empty? # Resolve policy: sugar (symbol → preset, Policy object → use directly) if policy resolved = policy.is_a?(Symbol) ? Policy.preset(policy) : policy enforce(resolved) end # Load policies policies.each { |p| enforce(p) } # Automagic Logger attachment unless disabled via ENV["ANTIGRAVITY_LOGGER"]=false or auto_logger: false if auto_logger && logger_enabled? attach_logger(log_file) end yield(self) if block_given? end |
Instance Attribute Details
#api_key ⇒ Object
Returns the value of attribute api_key.
6 7 8 |
# File 'lib/antigravity/agent.rb', line 6 def api_key @api_key end |
#born_at ⇒ Object (readonly)
Returns the value of attribute born_at.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def born_at @born_at end |
#client ⇒ Object (readonly)
Returns the value of attribute client.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def client @client end |
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def connection @connection end |
#conversation ⇒ Object (readonly)
Returns the value of attribute conversation.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def conversation @conversation end |
#hooks ⇒ Object (readonly)
Returns the value of attribute hooks.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def hooks @hooks end |
#logger_guard ⇒ Object (readonly)
Returns the value of attribute logger_guard.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def logger_guard @logger_guard end |
#model ⇒ Object
Returns the value of attribute model.
6 7 8 |
# File 'lib/antigravity/agent.rb', line 6 def model @model end |
#policies ⇒ Object (readonly)
Returns the value of attribute policies.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def policies @policies end |
#policy ⇒ Object (readonly)
Returns the value of attribute policy.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def policy @policy end |
#sidecars ⇒ Object (readonly)
Returns the value of attribute sidecars.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def sidecars @sidecars end |
#skills ⇒ Object (readonly)
Returns the value of attribute skills.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def skills @skills end |
#system_instruction ⇒ Object
Returns the value of attribute system_instruction.
6 7 8 |
# File 'lib/antigravity/agent.rb', line 6 def system_instruction @system_instruction end |
#tools ⇒ Object (readonly)
Returns the value of attribute tools.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def tools @tools end |
#workspace ⇒ Object
Returns the value of attribute workspace.
7 8 9 |
# File 'lib/antigravity/agent.rb', line 7 def workspace @workspace end |
Class Method Details
.list_skills(path_or_url) ⇒ Array<String>
List discovered skills in a container path (without loading them).
261 262 263 |
# File 'lib/antigravity/agent.rb', line 261 def self.list_skills(path_or_url) SkillResolver.resolve(path_or_url) end |
.open(**kwargs, &block) ⇒ Object
Block form: opens connection, yields agent, auto-closes.
62 63 64 65 66 67 68 69 70 |
# File 'lib/antigravity/agent.rb', line 62 def self.open(**kwargs, &block) agent = new(**kwargs) agent.connect! begin block.call(agent) ensure agent.close! end end |
Instance Method Details
#add_inline_skill(name:, description:, instructions:) ⇒ Skill
Create and add an inline skill (no file needed).
252 253 254 255 256 |
# File 'lib/antigravity/agent.rb', line 252 def add_inline_skill(name:, description:, instructions:) skill = Skill.inline(name: name, description: description, instructions: instructions) @skills << skill unless @skills.any? { |s| s.name == skill.name } skill end |
#add_skill(path_or_url, skill_name: nil) ⇒ Skill Also known as: load_skill
Add a single skill by path or GitHub URL. Raises if the path resolves to multiple skills (use add_skills instead).
224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/antigravity/agent.rb', line 224 def add_skill(path_or_url, skill_name: nil) target = skill_name ? "#{path_or_url.to_s.chomp('/')}/#{skill_name}" : path_or_url.to_s paths = SkillResolver.resolve(target) if paths.size > 1 raise ArgumentError, "add_skill resolved to #{paths.size} skills. Use add_skills instead, " \ "or specify skill_name: to pick one." end raise ArgumentError, "No skill found at #{target}" if paths.empty? load_single_skill(paths.first) end |
#add_skills(paths_or_urls) ⇒ Array<Skill>
Add one or more skills by path or GitHub URL. Accepts a single string or an array. Each entry is resolved (may expand to multiple).
241 242 243 244 245 |
# File 'lib/antigravity/agent.rb', line 241 def add_skills(paths_or_urls) Array(paths_or_urls).flat_map do |p| SkillResolver.resolve(p).map { |skill_path| load_single_skill(skill_path) } end end |
#after_response(&block) ⇒ Object
272 273 274 |
# File 'lib/antigravity/agent.rb', line 272 def after_response(&block) hooks.after_response(&block) end |
#after_tool_call(&block) ⇒ Object Also known as: on_tool_call
280 281 282 |
# File 'lib/antigravity/agent.rb', line 280 def after_tool_call(&block) hooks.after_tool_call(&block) end |
#attach_logger(log_target = nil, level: :info, silent_notice: false) ⇒ Object
213 214 215 216 217 |
# File 'lib/antigravity/agent.rb', line 213 def attach_logger(log_target = nil, level: :info, silent_notice: false) @logger_guard = Guards::AgentLogger.new(log_target, level: level, silent_notice: silent_notice) @logger_guard.attach_to(self) @logger_guard end |
#attach_sidecar(sidecar) ⇒ Object
208 209 210 211 |
# File 'lib/antigravity/agent.rb', line 208 def attach_sidecar(sidecar) @sidecars << sidecar sidecar end |
#before_prompt(&block) ⇒ Object
268 269 270 |
# File 'lib/antigravity/agent.rb', line 268 def before_prompt(&block) hooks.before_prompt(&block) end |
#before_tool_call(&block) ⇒ Object
276 277 278 |
# File 'lib/antigravity/agent.rb', line 276 def before_tool_call(&block) hooks.before_tool_call(&block) end |
#close! ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/antigravity/agent.rb', line 126 def close! # Emit session_end hook before teardown if @connected hooks.emit(:session_end, { turn_count: turn_count, conversation_id: conversation_id, }) end @connected = false @connection&.disconnect! @connection = nil @conversation = nil end |
#connect! ⇒ Object
--- Connection Lifecycle ---
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/antigravity/agent.rb', line 78 def connect! return self if @connected # Auto-attach lifecycle logger if enabled via env if lifecycle_logger_enabled? && !@lifecycle_attached LifecycleLogger.attach!(self, verbose: ENV['ANTIGRAVITY_LIFECYCLE_VERBOSE'] == '1') @lifecycle_attached = true end @connection = Connection::LocalConnection.new @connection.connect! @conversation = Conversation.new( ws_client: @connection.ws_client, tool_runner: @tool_runner, hooks: @hooks ) harness_config = build_harness_config # Emit indexing hooks — workspace indexing happens during session init index_t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) if @workspace hooks.emit(:indexing_start, { workspace: @workspace }) if @workspace @conversation.initialize_session!(harness_config: harness_config) @connected = true if @workspace index_elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - index_t0 hooks.emit(:indexing_done, { workspace: @workspace, elapsed: index_elapsed.round(2) }) end # Emit session_start hook hooks.emit(:session_start, { model: @model, conversation_id: conversation_id, workspace: @workspace, skills_count: @skills.length, tools_count: @tools.length, }) self end |
#connected? ⇒ Boolean
122 123 124 |
# File 'lib/antigravity/agent.rb', line 122 def connected? @connected && @connection&.connected? end |
#conversation_id ⇒ Object
--- Metadata Accessors (mirrors Python SDK) ---
164 165 166 |
# File 'lib/antigravity/agent.rb', line 164 def conversation_id @conversation&.conversation_id end |
#emit_sidecar_event(event_type, payload = {}) ⇒ Object
285 286 287 |
# File 'lib/antigravity/agent.rb', line 285 def emit_sidecar_event(event_type, payload = {}) @sidecars.each { |sidecar| sidecar.emit(event_type, payload) } end |
#enforce(policy) ⇒ Object
52 53 54 55 56 57 |
# File 'lib/antigravity/agent.rb', line 52 def enforce(policy) @policies << policy before_tool_call do |tool_name, args| policy.evaluate(tool_name, args) end end |
#prompt(message, timeout: Antigravity.config.timeout_llm, &block) ⇒ Object Also known as: ask
--- Chat ---
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/antigravity/agent.rb', line 143 def prompt(, timeout: Antigravity.config.timeout_llm, &block) connect! unless @connected emit_sidecar_event(:prompt_started, prompt: ) hooks.run_pre_prompt() if @connected && @conversation response = @conversation.chat(, timeout: timeout, &block) else # Legacy mock-client path (unit tests, pre-connection) response = client.send_turn(self, , &block) end hooks.run_post_response(response) emit_sidecar_event(:turn_completed, response: response.content, model: model) response end |
#register_tool(tool_or_name = nil, description: "", &block) ⇒ Object
--- Tool Registration ---
195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/antigravity/agent.rb', line 195 def register_tool(tool_or_name = nil, description: "", &block) if block_given? && tool_or_name tool = Tool::Dynamic.new(tool_or_name, description: description, &block) elsif tool_or_name.respond_to?(:to_json_schema) tool = tool_or_name else raise ArgumentError, "Invalid tool definition" end @tools << tool @tool_runner.register(tool) if @tool_runner tool end |
#session_summary ⇒ Object
172 173 174 175 176 |
# File 'lib/antigravity/agent.rb', line 172 def session_summary return {} unless @conversation @conversation.session_summary(model: @model) end |
#turn_count ⇒ Object
168 169 170 |
# File 'lib/antigravity/agent.rb', line 168 def turn_count @conversation&.turn_count || 0 end |
#uptime ⇒ Object
Seconds since agent was created
179 180 181 |
# File 'lib/antigravity/agent.rb', line 179 def uptime Time.now - @born_at end |
#uptime_human ⇒ Object
Human-readable uptime: "1m 23.4s", "7.3s"
184 185 186 187 188 189 190 191 |
# File 'lib/antigravity/agent.rb', line 184 def uptime_human secs = uptime if secs >= 60 "#{(secs / 60).to_i}m #{(secs % 60).round(1)}s" else "#{secs.round(1)}s" end end |