Skip to content

feat(invoke harness): add run_sse protocol alongside invoke#81

Open
yaozheng-fang wants to merge 7 commits into
mainfrom
feat/invoke-harness-run-sse
Open

feat(invoke harness): add run_sse protocol alongside invoke#81
yaozheng-fang wants to merge 7 commits into
mainfrom
feat/invoke-harness-run-sse

Conversation

@yaozheng-fang

@yaozheng-fang yaozheng-fang commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

What

Adds a second transport to agentkit invoke harness: --protocol run_sse, which streams from the deployed harness over ADK's /run_sse endpoint (alongside the existing default --protocol invokePOST /harness/invoke).

Rebased onto main (which now carries the #84 JWT data-plane auth), so the net change here is just the run_sse path.

Changes

  • --protocol invoke|run_sse (default invoke). Unknown value → fast-fail.
  • run_sse path (_harness_run_sse):
    • app_name fixed to "harness" (CLI-side constant; decoupled from the deployed HARNESS_NAME).
    • Creates the ADK session, then POST /run_sse, streaming partial deltas (skips the final aggregate and thought parts so the answer isn't double-printed).
    • Overrides (--system-prompt / --model-name / --tools / --skills / --runtime) are sent as the harness field so the runtime streams a spawned (overridden) agent; without them it streams the base agent. --max-llm-calls is invoke-only and ignored here (with a notice).
  • user_id from JWT sub: when the bearer token is an OIDC id_token (custom_jwt harness), decode its sub claim and use it as the run's user_id so sessions tie to the authenticated identity; opaque key_auth tokens fall back to a random u-<uuid>.
  • Shared auth: the auth-type-aware token resolution from feat(auth): use the login id_token as the harness-invoke Bearer (JWT … #84 (--apikey > login id_token for custom_jwt > static key for key_auth, with 401 force-refresh retry) now applies to both transports — so run_sse against a custom_jwt harness needs no explicit -ak.

Tests

tests/toolkit/cli/test_cli_invoke_harness.py — run_sse streaming, override forwarding, invalid-protocol fast-fail, and user_id-from-sub (plus the _user_id_from_token helper). Full file: 22 passed; ruff clean.

Verified end-to-end

Against a deployed custom_jwt harness with the local agentkit login id_token:

  • --protocol run_sse with an override → streamed the overridden answer, user_id = the token's sub, no -ak needed.

yaozheng-fang and others added 3 commits June 18, 2026 22:28
Add --protocol {invoke|run_sse} to 'agentkit invoke harness'. run_sse calls the deployed harness's ADK /run_sse endpoint: fixed app_name 'harness', a random CLI-generated user_id (temporary), and the caller's session_id; it creates the session then streams the answer (skipping model thought parts and the final aggregate). The existing /harness/invoke path is unchanged and remains the default.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The harness /run_sse now honors once-time overrides (spawned agent), so the CLI's run_sse mode sends --system-prompt/--model-name/--tools/--skills/--runtime as the 'harness' field. Only --max-llm-calls remains invoke-only. Base (no-override) run_sse is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The run_sse path used a random u-<uuid> user_id. When the bearer token is an
OIDC id_token (custom_jwt harness), decode its sub claim and use it as user_id
so sessions tie to the authenticated identity; fall back to random for opaque
key_auth tokens.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yaozheng-fang yaozheng-fang force-pushed the feat/invoke-harness-run-sse branch from e10fa9e to ad9f7e8 Compare June 18, 2026 14:43
yaozheng-fang and others added 4 commits June 18, 2026 22:55
run_sse is now the default transport for `agentkit invoke harness`; pass
--protocol invoke for the /harness/invoke path. When --session-id is unset the
run_sse path mints a random s-<id> (creating it is idempotent). Existing
invoke-path tests pin --protocol invoke via a _run_invoke helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update the invoke harness section: run_sse is now the default transport,
run_sse user_id comes from the JWT sub (or random), --session-id is minted
randomly when unset (idempotent create), and auth auto-loads the agentkit
login id_token for custom_jwt harnesses (no -ak needed) for both transports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… reasoning

- invoke now mints a random s-<id> session when --session-id is unset, matching
  run_sse (session handling is identical across transports).
- run_sse renders the model's reasoning (thought parts) dim/grey under a
  '🤔 思考中…' header so the wait isn't blank, then the answer under '📝 Response:'.
- docs updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the 🤔/📝 emoji headers. The wait + reasoning phase now shows a 'thinking'
loading spinner (model thought parts stay hidden); once the answer arrives the
spinner stops and the reply streams after a blank line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant