[2/4] Add private Python goal operations (#27111)

## Why

The Python SDK must treat the runtime's initial goal turn and its
continuations as one logical operation. That requires a private
lifecycle engine before the public API can return the existing turn
handle and result types.

## What

- start goals by composing the existing clear/set goal RPCs
- enforce persisted, idle threads and a bounded startup handshake
- coalesce continuation notifications under a stable logical turn ID
- aggregate items, usage, timing, and terminal status
- support rollover-aware steering, interruption, cancellation, and
cleanup
- provide equivalent sync and async internals

This is the second PR in the stack and intentionally adds no public API.

## Test plan

- online CI, including the Python SDK suite
- behavioral coverage is added in the following two stack PRs
This commit is contained in:
Ahmed Ibrahim
2026-06-09 15:32:15 -07:00
committed by GitHub
Unverified
parent cc8325f181
commit 9316acf9b2
5 changed files with 597 additions and 23 deletions
+22 -7
View File
@@ -121,10 +121,20 @@ class MessageRouter:
def register_goal(self, thread_id: str) -> _GoalOperationState:
"""Register one thread-scoped logical goal operation before it starts."""
state = _GoalOperationState(thread_id=thread_id)
state.activate_turn_routing()
return self._register_goal(state)
def reserve_goal(self, thread_id: str) -> _GoalOperationState:
"""Reserve a thread route without accepting physical turns yet."""
return self._register_goal(_GoalOperationState(thread_id=thread_id))
def _register_goal(self, state: _GoalOperationState) -> _GoalOperationState:
with self._lock:
if thread_id in self._goal_operations:
raise RuntimeError(f"thread {thread_id!r} already has an active goal operation")
self._goal_operations[thread_id] = state
if state.thread_id in self._goal_operations:
raise RuntimeError(
f"thread {state.thread_id!r} already has an active goal operation"
)
self._goal_operations[state.thread_id] = state
return state
def unregister_goal(self, state: _GoalOperationState) -> None:
@@ -133,6 +143,11 @@ class MessageRouter:
if self._goal_operations.get(state.thread_id) is state:
self._goal_operations.pop(state.thread_id)
def has_goal(self, thread_id: str) -> bool:
"""Return whether a logical goal operation owns this thread route."""
with self._lock:
return thread_id in self._goal_operations
def route_response(self, msg: dict[str, JsonValue]) -> None:
"""Deliver a JSON-RPC response or error to its request waiter."""
@@ -181,10 +196,10 @@ class MessageRouter:
if goal_state is not None and (
turn_id is not None or notification.method.startswith("thread/goal/")
):
goal_state.observe(notification)
if goal_state.is_finished():
self.unregister_goal(goal_state)
return
if goal_state.observe(notification):
if goal_state.is_finished():
self.unregister_goal(goal_state)
return
if turn_id is None:
self._global_notifications.put(notification)
return