subagent handling + 1m context resume

This commit is contained in:
Jonas H
2026-08-26 11:17:43 +02:00
parent a7d7940be3
commit c7eddf3bde
7 changed files with 2824 additions and 457 deletions

View File

@@ -7,7 +7,8 @@ lets us make Claude Code render its client-side tool UIs (AskUserQuestion,
ExitPlanMode, TodoWrite/Task*) on demand, so the pane's frame detector in
`src/term.rs` can be developed against what Ink actually draws.
Scenario is picked per turn from `CT_FAKE_SCENARIO` (ask | plan | todo | text).
Scenario is picked per turn from `CT_FAKE_SCENARIO`
(ask | plan | todo | taskupdate | agent | text).
Each incoming request is logged to `dev/fake_upstream.log` (declared tool names
+ the trailing user text) so we can see what CC sends.
"""
@@ -136,6 +137,19 @@ TASK_INPUTS = [
]
# Two parallel subagents with the *same* type and byte-identical prompts: the
# worst case for correlation (only Claude Code's `x-claude-code-agent-id` tells
# them apart), and what makes the subagent rows worth having.
AGENT_INPUTS = [
{"subagent_type": "Explore", "description": "find the retry helper",
"prompt": "Locate the retry helper and report back.", "run_in_background": False},
{"subagent_type": "Explore", "description": "find the retry helper",
"prompt": "Locate the retry helper and report back.", "run_in_background": False},
{"subagent_type": "oracle", "description": "review the lane design",
"prompt": "Review the lane design and report back.", "run_in_background": True},
]
class Handler(BaseHTTPRequestHandler):
protocol_version = "HTTP/1.1"
@@ -161,7 +175,12 @@ class Handler(BaseHTTPRequestHandler):
has_result = bool(blocks) and all(
b.get("type") == "tool_result" for b in blocks if isinstance(b, dict)
) and "toolu_fake" in json.dumps(blocks)
log(f"[{time.strftime('%H:%M:%S')}] {self.path} tools={tools} tail={tail}")
# `model` + `anthropic-beta` show how a `--model opus[1m]` pick reaches
# the wire (the 1M context window is a beta header, not a model id).
log(
f"[{time.strftime('%H:%M:%S')}] {self.path} model={body.get('model')} "
f"betas={self.headers.get('anthropic-beta', '')} tools={tools} tail={tail}"
)
if "count_tokens" in self.path:
out = json.dumps({"input_tokens": 100}).encode()
@@ -190,6 +209,12 @@ class Handler(BaseHTTPRequestHandler):
gen = stream_tools(
[("TaskCreate", t) for t in TASK_INPUTS], "Setting up the task list."
)
elif scenario == "agent":
# Spawn subagents. A real child then issues their requests itself,
# each carrying `x-claude-code-agent-id`.
gen = stream_tools(
[("Agent", a) for a in AGENT_INPUTS], "Delegating this."
)
elif scenario == "taskupdate":
gen = stream_tool("TaskUpdate", {"taskId": "1", "status": "in_progress"},
"Starting the first task.")