Squash of the 54 commits on victor-kyriazakos:feat/user-channel-warning-suppression (PR #112302, head f45c640e55) so the contributor's authorship survives a rebase-merge; the commits interleave with a cron delivery-ledger rework that the salvage removes in follow-up commits, so per-commit cherry-picks were not practical. Adds display.suppress_warning_notifications (global + per-platform, default false): one resolver (gateway/warning_notifications.py), BasePlatformAdapter.emit_warning / emit_media_warning / warning_text, a notification_category classification carried through wakes, queues and persistence, and render/present boundaries for CLI/TUI.
48 lines
2.6 KiB
Python
48 lines
2.6 KiB
Python
"""Salt R11-B1: synchronous child failure echo above the CLI spinner is an automatic diagnostic presentation
|
|
and honors display.suppress_warning_notifications under the parent's turn snapshot; the child result and the
|
|
relayed subagent.complete event are never gated."""
|
|
import json
|
|
import pytest
|
|
|
|
|
|
def configure(home, setting, monkeypatch):
|
|
home.mkdir(exist_ok=True)
|
|
monkeypatch.setenv('HERMES_HOME', str(home))
|
|
(home/'config.yaml').write_text(json.dumps({'display': {} if setting is None else {'suppress_warning_notifications':setting}}))
|
|
|
|
|
|
|
|
def test_sync_failure_real_run_to_spinner_three_modes(tmp_path, monkeypatch):
|
|
from tools.delegate_tool import _run_single_child
|
|
from tools.delegate_tool_progress import _build_child_progress_callback
|
|
from agent.notification_presentation import notification_policy_snapshot
|
|
from tests.tools.test_delegate_output_schema import _StubChild, _StubParent
|
|
rows=[]
|
|
for setting in (None,False,True):
|
|
configure(tmp_path/f'sync-{setting}',setting,monkeypatch)
|
|
import io
|
|
from contextlib import redirect_stdout
|
|
from agent.display import KawaiiSpinner
|
|
from agent.notification_presentation import notification_config_snapshot
|
|
buffer=io.StringIO();events=[]
|
|
parent=_StubParent();parent.session_id='parent'
|
|
with redirect_stdout(buffer):parent._delegate_spinner=KawaiiSpinner('delegating')
|
|
parent.tool_progress_callback=lambda *a,**kw:events.append({'args':a,'kwargs':kw})
|
|
child=_StubChild([])
|
|
def fail(**kwargs):raise RuntimeError('SYNC_REAL_CHILD_CRASH')
|
|
child.run_conversation=fail
|
|
child.tool_progress_callback=_build_child_progress_callback(0,'actual failing child',parent)
|
|
config=notification_config_snapshot()
|
|
assert config['display'].get('suppress_warning_notifications') is setting
|
|
with notification_policy_snapshot(parent,'cli',config):
|
|
result=_run_single_child(0,'actual failing child',child,parent)
|
|
assert result['status'] in ('error','failed') and 'SYNC_REAL_CHILD_CRASH' in str(result)
|
|
rows.append({'setting':setting,'lines':buffer.getvalue().splitlines(),'events':events,'result':result})
|
|
# absent/false: legacy echo present; true: echo suppressed. Result and relayed event untouched in all modes.
|
|
assert any('SYNC_REAL_CHILD_CRASH' in s for s in rows[0]['lines']), rows[0]
|
|
assert any('SYNC_REAL_CHILD_CRASH' in s for s in rows[1]['lines']), rows[1]
|
|
assert not any('SYNC_REAL_CHILD_CRASH' in s for s in rows[2]['lines']), rows[2]
|
|
for row in rows:
|
|
assert any(e['args'][0] == 'subagent.complete' for e in row['events']), row['events']
|
|
|