Skip to content

Commit 9f39c9f

Browse files
Antigravity Teamcopybara-github
authored andcommitted
No public description
PiperOrigin-RevId: 926283277 Change-Id: Ie6208176173b83e8a5d3593b2278e662396d078a
1 parent d1f831d commit 9f39c9f

3 files changed

Lines changed: 115 additions & 67 deletions

File tree

google/antigravity/connections/local/local_connection.py

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
from google.antigravity.hooks import hooks
4747
from google.antigravity.tools import tool_runner as t_runner
4848

49-
5049
_ANY_ADAPTER = pydantic.TypeAdapter(Any)
5150

5251

@@ -132,6 +131,7 @@ def mark_handled(self, request_type: str) -> bool:
132131
def _get_mcp_tool_name(server_name: str, tool_name: str) -> str:
133132
return f"{_MCP_TOOL_PREFIX}{server_name}_{tool_name}"
134133

134+
135135
_IDLE_SENTINEL = object()
136136
_CLOSE_SENTINEL = None
137137

@@ -601,6 +601,9 @@ async def receive_steps(self) -> AsyncIterator[LocalConnectionStep]:
601601

602602
step_obj = await self._step_queue.get()
603603

604+
if isinstance(step_obj, Exception):
605+
raise step_obj
606+
604607
if step_obj is _IDLE_SENTINEL:
605608
continue
606609
if step_obj is None:
@@ -858,9 +861,7 @@ async def _ws_reader_loop(self) -> None:
858861
and step_obj.source == types.StepSource.MODEL
859862
and step_obj.content
860863
):
861-
self._subagent_responses[step_obj.trajectory_id] = (
862-
step_obj.content
863-
)
864+
self._subagent_responses[step_obj.trajectory_id] = step_obj.content
864865

865866
# Dispatch post-tool-call or on-tool-error hooks for built-in tools
866867
# that were approved via ToolConfirmation. The harness executes them
@@ -945,16 +946,12 @@ async def _ws_reader_loop(self) -> None:
945946
self._active_subagent_ids.discard(tsu.trajectory_id)
946947
if self._hook_runner:
947948
op_ctx = hooks.OperationContext(self._get_turn_context())
948-
response = self._subagent_responses.pop(
949-
tsu.trajectory_id, ""
950-
)
949+
response = self._subagent_responses.pop(tsu.trajectory_id, "")
951950
result = types.ToolResult(
952951
name=types.BuiltinTools.START_SUBAGENT.value,
953952
result=response or tsu.trajectory_id,
954953
)
955-
await self._hook_runner.dispatch_post_tool_call(
956-
op_ctx, result
957-
)
954+
await self._hook_runner.dispatch_post_tool_call(op_ctx, result)
958955
else:
959956
# Parent trajectory went idle.
960957
self._parent_idle = True
@@ -965,6 +962,20 @@ async def _ws_reader_loop(self) -> None:
965962
if not self._is_idle.is_set():
966963
self._is_idle.set()
967964
await self._step_queue.put(_IDLE_SENTINEL)
965+
966+
if tsu.HasField("error"):
967+
if is_subagent:
968+
# Subagent failures are only logged. If an issue is serious
969+
# enough to be worth raising an exception then it should
970+
# affect the main trajectory too.
971+
logging.info(
972+
"Subagent trajectory failed with error: %s", tsu.error
973+
)
974+
else:
975+
await self._step_queue.put(
976+
types.AntigravityExecutionError(tsu.error)
977+
)
978+
968979
elif event.HasField("tool_call"):
969980
self._run_in_background(self._handle_tool_call(event.tool_call))
970981
except websockets.ConnectionClosed as e:
@@ -1061,13 +1072,12 @@ async def _handle_question_request(
10611072
logging.exception("_handle_question_request failed; sending error")
10621073
error_answer = localharness_pb2.UserQuestionAnswer(
10631074
multiple_choice_answer=localharness_pb2.MultipleChoiceAnswer(
1064-
freeform_response=(
1065-
f"SDK error processing question: {e!r}"
1066-
),
1075+
freeform_response=f"SDK error processing question: {e!r}",
10671076
),
10681077
)
10691078
await self._send_question_response(
1070-
step_update, [error_answer],
1079+
step_update,
1080+
[error_answer],
10711081
)
10721082

10731083
async def _send_question_response(
@@ -1170,9 +1180,7 @@ async def _handle_tool_confirmation_request(
11701180
# ToolConfirmation only has a bool field (no error/reason field), so
11711181
# rejecting is the only option. The harness transitions the step to
11721182
# STATE_ERROR, which the model does see.
1173-
logging.exception(
1174-
"_handle_tool_confirmation_request failed; rejecting"
1175-
)
1183+
logging.exception("_handle_tool_confirmation_request failed; rejecting")
11761184
await self._send_tool_confirmation(step_update, False)
11771185

11781186
async def _send_tool_confirmation(
@@ -1388,12 +1396,10 @@ def _get_default_binary_path_external() -> str:
13881396
if dist.files:
13891397
for f in dist.files:
13901398
normalized_path = str(f).replace("\\", "/")
1391-
if normalized_path.endswith(
1392-
(
1393-
"google/antigravity/bin/localharness",
1394-
"google/antigravity/bin/localharness.exe",
1395-
)
1396-
):
1399+
if normalized_path.endswith((
1400+
"google/antigravity/bin/localharness",
1401+
"google/antigravity/bin/localharness.exe",
1402+
)):
13971403
binary_path = os.path.abspath(str(f.locate()))
13981404
if os.path.exists(binary_path):
13991405
return binary_path
@@ -1750,7 +1756,7 @@ async def __aenter__(self) -> None:
17501756
f"Failed to connect to WebSocket at {ws_url} after"
17511757
f" {max_retries} attempts. Stderr: {stderr_output}"
17521758
) from e
1753-
await asyncio.sleep(0.1 * (2 ** attempt))
1759+
await asyncio.sleep(0.1 * (2**attempt))
17541760

17551761
assert ws is not None
17561762
try:

google/antigravity/connections/local/local_connection_test.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,47 @@ async def test_receive_steps_system_error_401(self):
137137
async for _ in harness.conn.receive_steps():
138138
pass
139139

140+
async def test_receive_steps_trajectory_error(self):
141+
harness = self._make_harness()
142+
143+
await harness.conn.send("Hello")
144+
init_data = await harness.wait_for_response()
145+
self.assertEqual(init_data.get("userInput"), "Hello")
146+
147+
# Set the cascade ID.
148+
event1 = localharness_pb2.OutputEvent(
149+
step_update=localharness_pb2.StepUpdate(
150+
cascade_id="my_cascade",
151+
trajectory_id="my_cascade",
152+
step_index=1,
153+
state=localharness_pb2.StepUpdate.STATE_ACTIVE,
154+
source=localharness_pb2.StepUpdate.SOURCE_MODEL,
155+
text="I'm working",
156+
)
157+
)
158+
await harness.send_event(event1)
159+
160+
# Send an error.
161+
event2 = localharness_pb2.OutputEvent(
162+
trajectory_state_update=localharness_pb2.TrajectoryStateUpdate(
163+
trajectory_id="my_cascade",
164+
state=localharness_pb2.TrajectoryStateUpdate.STATE_IDLE,
165+
error="Trajectory execution failed",
166+
)
167+
)
168+
await harness.send_event(event2)
169+
await harness.close_from_harness_side()
170+
171+
steps = []
172+
with self.assertRaisesRegex(
173+
types.AntigravityExecutionError, "Trajectory execution failed"
174+
):
175+
async for step in harness.conn.receive_steps():
176+
steps.append(step)
177+
178+
self.assertEqual(len(steps), 1)
179+
self.assertEqual(steps[0].content, "I'm working")
180+
140181
def test_local_connection_step_from_dict(self):
141182
"""Tests that LocalConnectionStep maps fields correctly."""
142183
step_dict = {

google/antigravity/connections/local/localharness_pb2.py

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,10 @@
193193
b' \x01(\x0b\x32\x30.antigravity.localharness.UserInput.SlashCommandH\x00\x42\x06\n\x04part"O\n\x10ToolConfirmation\x12\x15\n\rtrajectory_id\x18\x01'
194194
b' \x01(\t\x12\x12\n\nstep_index\x18\x02'
195195
b' \x01(\r\x12\x10\n\x08\x61\x63\x63\x65pted\x18\x03'
196-
b' \x01(\x08"\xb7\x01\n\x15TrajectoryStateUpdate\x12\x15\n\rtrajectory_id\x18\x02'
196+
b' \x01(\x08"\xc6\x01\n\x15TrajectoryStateUpdate\x12\x15\n\rtrajectory_id\x18\x02'
197197
b' \x01(\t\x12\x44\n\x05state\x18\x03'
198-
b' \x01(\x0e\x32\x35.antigravity.localharness.TrajectoryStateUpdate.State"A\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x11\n\rSTATE_RUNNING\x10\x01\x12\x0e\n\nSTATE_IDLE\x10\x02"9\n\x06Struct\x12/\n\x06\x66ields\x18\x01'
198+
b' \x01(\x0e\x32\x35.antigravity.localharness.TrajectoryStateUpdate.State\x12\r\n\x05\x65rror\x18\x04'
199+
b' \x01(\t"A\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x11\n\rSTATE_RUNNING\x10\x01\x12\x0e\n\nSTATE_IDLE\x10\x02"9\n\x06Struct\x12/\n\x06\x66ields\x18\x01'
199200
b' \x03(\x0b\x32\x1f.antigravity.localharness.Field"E\n\x05\x46ield\x12\x0c\n\x04name\x18\x01'
200201
b' \x01(\t\x12.\n\x05value\x18\x02'
201202
b' \x01(\x0b\x32\x1f.antigravity.localharness.Value"\xb7\x02\n\x05Value\x12\x39\n\nnull_value\x18\x01'
@@ -263,8 +264,8 @@
263264
_globals['_MCPSTDIOTRANSPORT_ENVENTRY']._serialized_options = b'8\001'
264265
_globals['_MCPHTTPTRANSPORT_HEADERSENTRY']._loaded_options = None
265266
_globals['_MCPHTTPTRANSPORT_HEADERSENTRY']._serialized_options = b'8\001'
266-
_globals['_NULLVALUE']._serialized_start = 10385
267-
_globals['_NULLVALUE']._serialized_end = 10412
267+
_globals['_NULLVALUE']._serialized_start = 10400
268+
_globals['_NULLVALUE']._serialized_end = 10427
268269
_globals['_INPUTCONFIG']._serialized_start = 49
269270
_globals['_INPUTCONFIG']._serialized_end = 195
270271
_globals['_INITIALIZECONVERSATIONEVENT']._serialized_start = 197
@@ -384,45 +385,45 @@
384385
_globals['_TOOLCONFIRMATION']._serialized_start = 7802
385386
_globals['_TOOLCONFIRMATION']._serialized_end = 7881
386387
_globals['_TRAJECTORYSTATEUPDATE']._serialized_start = 7884
387-
_globals['_TRAJECTORYSTATEUPDATE']._serialized_end = 8067
388-
_globals['_TRAJECTORYSTATEUPDATE_STATE']._serialized_start = 8002
389-
_globals['_TRAJECTORYSTATEUPDATE_STATE']._serialized_end = 8067
390-
_globals['_STRUCT']._serialized_start = 8069
391-
_globals['_STRUCT']._serialized_end = 8126
392-
_globals['_FIELD']._serialized_start = 8128
393-
_globals['_FIELD']._serialized_end = 8197
394-
_globals['_VALUE']._serialized_start = 8200
395-
_globals['_VALUE']._serialized_end = 8511
396-
_globals['_LISTVALUE']._serialized_start = 8513
397-
_globals['_LISTVALUE']._serialized_end = 8573
398-
_globals['_TOOLCALL']._serialized_start = 8575
399-
_globals['_TOOLCALL']._serialized_end = 8688
400-
_globals['_TOOLRESPONSE']._serialized_start = 8691
401-
_globals['_TOOLRESPONSE']._serialized_end = 8853
402-
_globals['_USERQUESTIONSRESPONSE']._serialized_start = 8856
403-
_globals['_USERQUESTIONSRESPONSE']._serialized_end = 9124
404-
_globals['_USERQUESTIONSRESPONSE_QUESTIONSRESPONSE']._serialized_start = 9032
405-
_globals['_USERQUESTIONSRESPONSE_QUESTIONSRESPONSE']._serialized_end = 9114
406-
_globals['_USERQUESTIONANSWER']._serialized_start = 9127
407-
_globals['_USERQUESTIONANSWER']._serialized_end = 9261
408-
_globals['_MULTIPLECHOICEANSWER']._serialized_start = 9263
409-
_globals['_MULTIPLECHOICEANSWER']._serialized_end = 9345
388+
_globals['_TRAJECTORYSTATEUPDATE']._serialized_end = 8082
389+
_globals['_TRAJECTORYSTATEUPDATE_STATE']._serialized_start = 8017
390+
_globals['_TRAJECTORYSTATEUPDATE_STATE']._serialized_end = 8082
391+
_globals['_STRUCT']._serialized_start = 8084
392+
_globals['_STRUCT']._serialized_end = 8141
393+
_globals['_FIELD']._serialized_start = 8143
394+
_globals['_FIELD']._serialized_end = 8212
395+
_globals['_VALUE']._serialized_start = 8215
396+
_globals['_VALUE']._serialized_end = 8526
397+
_globals['_LISTVALUE']._serialized_start = 8528
398+
_globals['_LISTVALUE']._serialized_end = 8588
399+
_globals['_TOOLCALL']._serialized_start = 8590
400+
_globals['_TOOLCALL']._serialized_end = 8703
401+
_globals['_TOOLRESPONSE']._serialized_start = 8706
402+
_globals['_TOOLRESPONSE']._serialized_end = 8868
403+
_globals['_USERQUESTIONSRESPONSE']._serialized_start = 8871
404+
_globals['_USERQUESTIONSRESPONSE']._serialized_end = 9139
405+
_globals['_USERQUESTIONSRESPONSE_QUESTIONSRESPONSE']._serialized_start = 9047
406+
_globals['_USERQUESTIONSRESPONSE_QUESTIONSRESPONSE']._serialized_end = 9129
407+
_globals['_USERQUESTIONANSWER']._serialized_start = 9142
408+
_globals['_USERQUESTIONANSWER']._serialized_end = 9276
409+
_globals['_MULTIPLECHOICEANSWER']._serialized_start = 9278
410+
_globals['_MULTIPLECHOICEANSWER']._serialized_end = 9360
410411
_globals['_MEDIA']._serialized_start = 7541
411412
_globals['_MEDIA']._serialized_end = 7602
412-
_globals['_USAGEMETADATA']._serialized_start = 9411
413-
_globals['_USAGEMETADATA']._serialized_end = 9579
414-
_globals['_MCPSERVERCONFIG']._serialized_start = 9582
415-
_globals['_MCPSERVERCONFIG']._serialized_end = 9982
416-
_globals['_MCPSERVERCONFIG_AUTHPROVIDERTYPE']._serialized_start = 9872
417-
_globals['_MCPSERVERCONFIG_AUTHPROVIDERTYPE']._serialized_end = 9969
418-
_globals['_MCPSTDIOTRANSPORT']._serialized_start = 9985
419-
_globals['_MCPSTDIOTRANSPORT']._serialized_end = 10146
420-
_globals['_MCPSTDIOTRANSPORT_ENVENTRY']._serialized_start = 10104
421-
_globals['_MCPSTDIOTRANSPORT_ENVENTRY']._serialized_end = 10146
422-
_globals['_MCPHTTPTRANSPORT']._serialized_start = 10149
423-
_globals['_MCPHTTPTRANSPORT']._serialized_end = 10302
424-
_globals['_MCPHTTPTRANSPORT_HEADERSENTRY']._serialized_start = 10256
425-
_globals['_MCPHTTPTRANSPORT_HEADERSENTRY']._serialized_end = 10302
426-
_globals['_ACTIONMCPTOOL']._serialized_start = 10304
427-
_globals['_ACTIONMCPTOOL']._serialized_end = 10383
413+
_globals['_USAGEMETADATA']._serialized_start = 9426
414+
_globals['_USAGEMETADATA']._serialized_end = 9594
415+
_globals['_MCPSERVERCONFIG']._serialized_start = 9597
416+
_globals['_MCPSERVERCONFIG']._serialized_end = 9997
417+
_globals['_MCPSERVERCONFIG_AUTHPROVIDERTYPE']._serialized_start = 9887
418+
_globals['_MCPSERVERCONFIG_AUTHPROVIDERTYPE']._serialized_end = 9984
419+
_globals['_MCPSTDIOTRANSPORT']._serialized_start = 10000
420+
_globals['_MCPSTDIOTRANSPORT']._serialized_end = 10161
421+
_globals['_MCPSTDIOTRANSPORT_ENVENTRY']._serialized_start = 10119
422+
_globals['_MCPSTDIOTRANSPORT_ENVENTRY']._serialized_end = 10161
423+
_globals['_MCPHTTPTRANSPORT']._serialized_start = 10164
424+
_globals['_MCPHTTPTRANSPORT']._serialized_end = 10317
425+
_globals['_MCPHTTPTRANSPORT_HEADERSENTRY']._serialized_start = 10271
426+
_globals['_MCPHTTPTRANSPORT_HEADERSENTRY']._serialized_end = 10317
427+
_globals['_ACTIONMCPTOOL']._serialized_start = 10319
428+
_globals['_ACTIONMCPTOOL']._serialized_end = 10398
428429
# @@protoc_insertion_point(module_scope)

0 commit comments

Comments
 (0)