Class: Antigravity::Conversation

Inherits:
Object
  • Object
show all
Defined in:
lib/antigravity/conversation.rb

Overview

Manages a multi-turn conversation with the harness over WebSocket. Handles the event loop: send InputEvent, receive OutputEvents, dispatch tools.

Mirrors Python SDK's Conversation class:

- history, turn_count, conversation_id
- last_turn_usage, total_usage

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ws_client:, tool_runner: nil, hooks: nil) ⇒ Conversation

Returns a new instance of Conversation.



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/antigravity/conversation.rb', line 16

def initialize(ws_client:, tool_runner: nil, hooks: nil)
  @ws = ws_client
  @tool_runner = tool_runner || ToolRunner.new
  @hooks = hooks
  @conversation_id = nil
  @history = []
  @turn_count = 0
  @total_usage = empty_usage
  @last_turn_usage = nil
  @initialized = false
end

Instance Attribute Details

#conversation_idObject (readonly)

Returns the value of attribute conversation_id.



14
15
16
# File 'lib/antigravity/conversation.rb', line 14

def conversation_id
  @conversation_id
end

#historyObject (readonly)

Returns the value of attribute history.



14
15
16
# File 'lib/antigravity/conversation.rb', line 14

def history
  @history
end

#last_turn_usageObject (readonly)

Returns the value of attribute last_turn_usage.



14
15
16
# File 'lib/antigravity/conversation.rb', line 14

def last_turn_usage
  @last_turn_usage
end

#total_usageObject (readonly)

Returns the value of attribute total_usage.



14
15
16
# File 'lib/antigravity/conversation.rb', line 14

def total_usage
  @total_usage
end

#turn_countObject (readonly)

Returns the value of attribute turn_count.



14
15
16
# File 'lib/antigravity/conversation.rb', line 14

def turn_count
  @turn_count
end

Instance Method Details

#chat(prompt, timeout: Antigravity.config.timeout_llm, &block) ⇒ Message

Send a user message and collect the full response. Yields streaming chunks if a block is given.

Parameters:

  • prompt (String)

    user message

Returns:

  • (Message)

    the complete response

Raises:



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/antigravity/conversation.rb', line 56

def chat(prompt, timeout: Antigravity.config.timeout_llm, &block)
  raise ProtocolError, 'Session not initialized' unless @initialized

  @turn_count += 1
  @last_turn_usage = empty_usage

  # Send user input (protobuf InputEvent with user_input string field)
  input_event = {
    userInput: prompt
  }
  @ws.send_json(input_event)

  # Collect response
  collect_response(timeout: timeout, &block)
end

#initialize_session!(harness_config:) ⇒ Object

Initialize the conversation session with the harness. Sends InitializeConversationEvent (protobuf JSON format), receives response.

Raises:



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/antigravity/conversation.rb', line 30

def initialize_session!(harness_config:)
  # harness_config IS the InitializeConversationEvent JSON:
  # { config: { models: [...], workspaces: [...], ... } }
  @ws.send_json(harness_config)

  # Wait for InitializeConversationResponse
  msg = @ws.receive_json(timeout: 30)
  raise ProtocolError, 'No response to InitializeConversationEvent' unless msg

  if (init_resp = msg[:initializeConversationResponse])
    @conversation_id = init_resp[:cascadeId]
    @initialized = true
  else
    # Some harness versions may wrap differently
    @conversation_id = msg[:cascadeId] || msg.dig(:config, :cascadeId) || SecureRandom.uuid
    @initialized = true
  end

  self
end

#initialized?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/antigravity/conversation.rb', line 72

def initialized?
  @initialized
end

#session_summary(model: nil) ⇒ Object

Generate a session summary hash (mirrors Python's metadata)



77
78
79
80
81
82
83
84
85
86
# File 'lib/antigravity/conversation.rb', line 77

def session_summary(model: nil)
  {
    conversation_id: @conversation_id,
    turn_count: @turn_count,
    total_tokens: @total_usage[:total_token_count],
    prompt_tokens: @total_usage[:prompt_token_count],
    candidates_tokens: @total_usage[:candidates_token_count],
    model: model
  }
end