@@ -44,6 +44,15 @@ def _run_harness(args):
4444 return runner .invoke (app , ["invoke" , "harness" , * args ])
4545
4646
47+ def _run_invoke (args ):
48+ """Run the harness subcommand pinned to the ``invoke`` transport.
49+
50+ ``--protocol`` now defaults to ``run_sse``; these tests exercise the
51+ ``/harness/invoke`` path, so they request it explicitly.
52+ """
53+ return _run_harness ([* args , "--protocol" , "invoke" ])
54+
55+
4756class _FakeResponse :
4857 def __init__ (self , payload , status_code = 200 ):
4958 self ._payload = payload
@@ -96,13 +105,13 @@ def test_build_harness_overrides_empty_when_unset():
96105
97106def test_unknown_harness_fails (tmp_path ):
98107 _write_registry (tmp_path , {"other" : {"url" : "https://x" , "key" : "k" }})
99- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
108+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
100109 assert result .exit_code == 1
101110 assert "not found in registry" in result .output
102111
103112
104113def test_no_registry_fails (tmp_path ):
105- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
114+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
106115 assert result .exit_code == 1
107116 assert "not found in registry" in result .output
108117
@@ -122,7 +131,7 @@ def test_harness_invoke_posts_correct_request(tmp_path, monkeypatch):
122131 "output" : "PINEAPPLE" ,
123132 })
124133
125- result = _run_harness (
134+ result = _run_invoke (
126135 [
127136 "first" ,
128137 "What should you reply?" ,
@@ -155,7 +164,7 @@ def test_harness_invoke_no_overrides_omits_harness_key(tmp_path, monkeypatch):
155164 captured = {}
156165 _patch_post (monkeypatch , captured )
157166
158- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
167+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
159168
160169 assert result .exit_code == 0 , result .output
161170 assert "harness" not in captured ["json" ]
@@ -176,7 +185,7 @@ def test_harness_error_field_is_surfaced(tmp_path, monkeypatch):
176185 },
177186 )
178187
179- result = _run_harness (
188+ result = _run_invoke (
180189 ["first" , "hi" , "--directory" , str (tmp_path ), "--tools" , "bogus" ]
181190 )
182191 assert result .exit_code == 1
@@ -189,7 +198,7 @@ def test_harness_invoke_http_error_fails(tmp_path, monkeypatch):
189198 captured = {}
190199 _patch_post (monkeypatch , captured , payload = {"detail" : "boom" }, status_code = 500 )
191200
192- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
201+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
193202 assert result .exit_code == 1
194203 assert "HTTP 500" in result .output
195204
@@ -199,7 +208,7 @@ def test_apikey_overrides_registry_key(tmp_path, monkeypatch):
199208 captured = {}
200209 _patch_post (monkeypatch , captured )
201210
202- result = _run_harness (
211+ result = _run_invoke (
203212 ["first" , "hi" , "--directory" , str (tmp_path ), "--apikey" , "jwt-token" ]
204213 )
205214 assert result .exit_code == 0 , result .output
@@ -282,7 +291,7 @@ def test_harness_invoke_uses_login_id_token_as_bearer(monkeypatch, tmp_path):
282291 _write_registry (tmp_path , {"first" : {"url" : "https://h.example.com" }}) # no static key
283292 captured = {}
284293 _patch_post (monkeypatch , captured )
285- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
294+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
286295 assert result .exit_code == 0 , result .output
287296 assert captured ["headers" ].get ("Authorization" ) == f"Bearer { tok } "
288297
@@ -292,7 +301,7 @@ def test_harness_invoke_apikey_overrides_login_id_token(monkeypatch, tmp_path):
292301 _write_registry (tmp_path , {"first" : {"url" : "https://h.example.com" }})
293302 captured = {}
294303 _patch_post (monkeypatch , captured )
295- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path ), "--apikey" , "explicit-key" ])
304+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path ), "--apikey" , "explicit-key" ])
296305 assert result .exit_code == 0 , result .output
297306 assert captured ["headers" ].get ("Authorization" ) == "Bearer explicit-key"
298307
@@ -317,7 +326,7 @@ def fake_post(url, json=None, headers=None, timeout=None):
317326 return _FakeResponse ({"output" : "ok" }, 401 if len (calls ) == 1 else 200 )
318327
319328 monkeypatch .setattr ("requests.post" , fake_post )
320- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
329+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
321330 assert result .exit_code == 0 , result .output
322331 assert calls == [f"Bearer { tok1 } " , f"Bearer { tok2 } " ] # one refresh + one retry
323332
@@ -334,7 +343,7 @@ def boom(self, rt):
334343 raise AuthError ("token endpoint rejected the request" )
335344
336345 monkeypatch .setattr (sess_mod .OAuthClient , "refresh" , boom )
337- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
346+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
338347 assert result .exit_code == 1
339348 assert "login" in result .output .lower ()
340349
@@ -346,7 +355,7 @@ def test_harness_invoke_keyauth_uses_key_even_when_logged_in(monkeypatch, tmp_pa
346355 _write_registry (tmp_path , {"first" : {"url" : "https://h.example.com" , "key" : "ak" , "runtime_id" : "r-1" }})
347356 captured = {}
348357 _patch_post (monkeypatch , captured )
349- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
358+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
350359 assert result .exit_code == 0 , result .output
351360 assert captured ["headers" ].get ("Authorization" ) == "Bearer ak"
352361
@@ -360,7 +369,7 @@ def test_harness_invoke_custom_jwt_entry_uses_login_id_token(monkeypatch, tmp_pa
360369 }})
361370 captured = {}
362371 _patch_post (monkeypatch , captured )
363- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
372+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
364373 assert result .exit_code == 0 , result .output
365374 assert captured ["headers" ].get ("Authorization" ) == f"Bearer { tok } "
366375
@@ -382,7 +391,7 @@ def fake_post(url, json=None, headers=None, timeout=None):
382391 return _FakeResponse ({"detail" : "denied" }, 401 )
383392
384393 monkeypatch .setattr ("requests.post" , fake_post )
385- result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
394+ result = _run_invoke (["first" , "hi" , "--directory" , str (tmp_path )])
386395 assert result .exit_code == 1
387396 assert len (calls ) == 2 # original + exactly one refresh-retry, no third
388397 assert "HTTP 401" in result .output
@@ -544,6 +553,36 @@ def test_user_id_from_token_helper():
544553 assert cli_invoke ._user_id_from_token ("" ) is None
545554
546555
556+ def test_default_protocol_is_run_sse_with_random_session (tmp_path , monkeypatch ):
557+ """No --protocol and no --session-id → run_sse with a freshly minted session."""
558+ _write_registry (tmp_path , {"first" : {"url" : "https://x" , "key" : "ak" }})
559+ calls = []
560+ sse = ['data: {"content":{"parts":[{"text":"OK"}]},"partial":true}' ]
561+
562+ class _SSEResp :
563+ status_code = 200
564+ text = ""
565+
566+ def iter_lines (self , decode_unicode = False ):
567+ return iter (sse )
568+
569+ def fake_post (url , json = None , headers = None , timeout = None , stream = False ):
570+ calls .append ({"url" : url , "json" : json })
571+ return _SSEResp () if url .endswith ("/run_sse" ) else _FakeResponse ({}, 200 )
572+
573+ monkeypatch .setattr ("requests.post" , fake_post )
574+
575+ result = _run_harness (["first" , "hi" , "--directory" , str (tmp_path )])
576+ assert result .exit_code == 0 , result .output
577+ # Default transport is run_sse (not /harness/invoke).
578+ run_call = next (c for c in calls if c ["url" ].endswith ("/run_sse" ))
579+ sid = run_call ["json" ]["session_id" ]
580+ assert sid .startswith ("s-" ) # random, not the invoke-path default
581+ # The session is created (idempotently) before the run, under that id.
582+ sess_call = next (c for c in calls if "/sessions/" in c ["url" ])
583+ assert sess_call ["url" ].endswith (f"/sessions/{ sid } " )
584+
585+
547586def test_harness_invalid_protocol_fails (tmp_path ):
548587 _write_registry (tmp_path , {"first" : {"url" : "https://x" , "key" : "ak" }})
549588 result = _run_harness (
0 commit comments