Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license

This commit is contained in:
2026-09-05 13:26:46 +03:00
commit 03634b1ca3
11340 changed files with 3442369 additions and 0 deletions
@@ -0,0 +1,79 @@
"""Regression tests for #93942 slice 1 — Bot Mode open chat pane never picks
up background deliveries.
Mechanism (traced on 85a55e2b30-era main, re-verified through 03b87d666d):
* Background DMs deliver via a separate ``hermes -p <profile> chat``
subprocess (``tools/bot_relay.py::local_delivery_command``) that writes the
turn straight to the session DB. No gateway stream event reaches the desktop.
* The gateway broadcasts ``sessions.changed`` on state.db mtime movement, and
the desktop's tick handler calls ``requestActiveTranscriptRefresh(true)`` —
but that refresh covers ONLY the MAIN pane's selection
(``activeStoredSessionId = selectedStoredSessionId``, wiring.tsx).
* Bot canonical chats open as workspace tiles (``workspaceMode: 'bots'``,
never the main selection), AND ``resolveActiveTranscriptSession()`` bails
when the session is absent from ``$sessions``/``$messagingSessions`` — which
bot chats always are (they carry the core ``hidden`` flag,
plugin.js "Bot Mode sessions are ALWAYS hidden").
Double exclusion ⇒ the sessions.changed refresh silently no-ops for exactly
the conversation the user is staring at.
Fix contract (slice 1): the sessions.changed tick must also reconcile the
transcripts of VISIBLE workspace tiles — signature-gated like the main pane,
keyed off each tile's stored↔runtime id pair — without touching messaging
polls, roster cadence, or the main-pane path.
"""
from __future__ import annotations
import re
from pathlib import Path
def _bg_sync_source() -> str:
return (
Path(__file__).resolve().parents[2]
/ "apps"
/ "desktop"
/ "src"
/ "app"
/ "contrib"
/ "hooks"
/ "use-background-sync.ts"
).read_text(encoding="utf-8")
def test_sessions_changed_tick_covers_workspace_tiles():
"""The $sessionsChangeTick listener must refresh tile transcripts too, not
only the main pane's active transcript."""
src = _bg_sync_source()
# Locate the tick listener block.
m = re.search(r"\$sessionsChangeTick\.listen\(", src)
assert m, "sessions.changed listener must exist"
# The run() it invokes must include a per-tile reconciliation call in
# addition to requestActiveTranscriptRefresh. Pre-fix, `run()` touches
# refreshSessions/refreshMessagingSessions/requestActiveTranscriptRefresh
# only — no tile path.
run_start = src.rfind("const run = () => {", 0, m.start())
body = src[run_start : src.find("}", m.start())]
assert re.search(r"[Tt]ile", body), (
"pre-fix state: sessions.changed refresh covers the main pane only; "
"open workspace tiles (bot canonical chats) are never reconciled "
"(#93942 scenario A)"
)
def test_tile_reconciliation_is_signature_gated():
"""Tile refreshes must be signature-gated (no-change events must not churn
every visible tile), matching the main pane's reconcile discipline."""
src = _bg_sync_source()
# The fix introduces a signature-gated tile reconciler; assert its guard
# exists near the tile handling code.
assert re.search(r"[Tt]ile[A-Za-z]*Signature|signature.*tile", src, re.IGNORECASE) or (
"signatureRef" in src and "[Tt]ile" in src
), "tile reconciliation must be signature-gated like the main pane path"
@@ -0,0 +1,117 @@
"""Regression tests for #93942 slice 2 — open chat pane never follows a runtime
rebuild after a mid-conversation model switch.
Mechanism (traced on 41447a6d70):
* A mid-conversation model/provider switch rebuilds the agent runtime. The
rebuilt runtime emits its ``session.info`` (and all later stream events)
under a NEW explicit ``session_id``; the old id is dead.
* The pane's identity is the pair ``(activeSessionIdRef, selectedStoredSessionIdRef)``.
After the rebuild, incoming events carry an explicit sid that no longer
equals ``activeSessionIdRef.current``, so ``isActiveEvent`` is False for every
subsequent event of the SAME conversation — view-scoped side effects stop,
and the pane keeps listening on a dead runtime until a full resume.
* Existing machinery covers compression rotation only:
``ensureSessionState`` fires the stored-id rotation signal when the SAME
runtime's stored id rotates — but a model-switch rebuild produces a NEW
runtime with a NEW stored id, which is invisible to that path.
Fix contract: when a ``session.info`` event's lineage
(``sessionMatchesStoredId`` on ``stored_session_id``) matches the currently
selected conversation but its runtime id differs from the active one, re-bind
the pane: adopt the new runtime id as the active session id (keeping the same
durable selection), so live events keep flowing to the view without a resume.
Guarded to only fire when the old runtime is dead (no busy/streaming state) so
an overlapping turn is never hijacked mid-flight.
Together with #94255 (slice 1), this closes #93942.
"""
from __future__ import annotations
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2] / "apps" / "desktop" / "src"
def _session_info_source() -> str:
return (
ROOT / "app" / "session" / "hooks" / "use-message-stream" / "gateway-event" / "session-info.ts"
).read_text(encoding="utf-8")
def test_session_info_rebinds_pane_to_rebuilt_runtime():
"""A session.info whose lineage matches the selected conversation but whose
runtime id differs from the active one must trigger the re-bind path."""
src = _session_info_source()
# The fix adds a lineage-checked re-bind call in handleSessionInfoEvent,
# distinct from the cwd-claim helper (#71254). Pre-fix there is exactly one
# sessionInfoDescribesSelectedSession use site (cwd claim); post-fix a
# second consumer exists for the re-bind.
uses = len(re.findall(r"sessionInfoDescribesSelectedSession\(", src))
assert uses >= 3, (
"pre-fix state: session.info lineage matching is used only for the cwd "
"claim; a rebuilt runtime (model switch) under a new session_id is "
"never adopted back into the open pane (#93942 scenario B)"
)
def test_rebind_is_guarded_against_live_turns():
"""The re-bind must not hijack a conversation while its OLD runtime is
still streaming/busy — only a dead runtime may be adopted over."""
src = _session_info_source()
# Locate the rebind helper's body precisely, then assert its guard inside.
fn = re.search(
r"function maybeRebindPaneToRebuiltRuntime\([^)]*\): boolean \{", src
)
assert fn, (
"pre-fix state: no maybeRebindPaneToRebuiltRuntime adoption path "
"exists; the rebuilt runtime is never adopted into the open pane"
)
body_start = fn.end()
next_fn = min(
(i for i in (src.find("\nfunction ", body_start), src.find("\nexport function ", body_start)) if i != -1),
default=-1,
)
assert next_fn != -1, "re-anchor needed: rebind helper is no longer followed by another function"
body = src[body_start:next_fn]
# The busy/awaiting/streaming guard must appear INSIDE the helper body —
# not merely somewhere in the file (fixes the precedence hazard the
# #94417 review flagged in the original draft of this assertion).
guard = re.search(r"oldState\?\.(busy|awaitingResponse|streamId)", body)
assert guard, (
"the re-bind helper must check the outgoing runtime's busy/streaming "
"state before switching; adopting over a live turn would split one "
"conversation across two panes"
)
def test_rebind_requires_stored_session_id_lineage():
"""The gateway always stamps stored_session_id on session.info (server.py:
'stored_session_id': session_key or ''), but an empty string must NOT be
adopted as lineage proof — only a real stored id may trigger the re-bind."""
src = _session_info_source()
fn = re.search(r"function maybeRebindPaneToRebuiltRuntime\([^)]*\): boolean \{", src)
assert fn, "rebind helper missing"
body_start = fn.end()
body = src[body_start : min(
(i for i in (src.find("\nfunction ", body_start), src.find("\nexport function ", body_start)) if i != -1),
default=-1,
)]
# The early return guards on the field being a non-empty usable string via
# the typeof check + downstream sessionInfoDescribesSelectedSession('' →
# null → wildcard refusal).
assert 'typeof payload?.stored_session_id !== "string"' in body or (
"typeof payload?.stored_session_id !== 'string'" in body
), "rebind must refuse events without a string stored_session_id"