Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
Prerequisites: Claude Code logged in with a claude.ai account, "env": {"CLAUDE_CODE_ARTIFACT": "1"} in ~/.claude/settings.json (see #14816), and a claude.ai artifact you own. Any artifact works; ask Claude to publish a one-line HTML page if you have none.
- In a T3 Claude thread, send:
Watch https://claude.ai/artifact/<id>. Claude callsArtifactCommentswithaction: "watch". The watch connects, and the result says auto-replies are not armed. - On the artifact page, leave a comment and use Send to Claude. The T3 thread does not wake.
- Confirm the turn origin. Find the thread's transcript (the newest
.jsonlunder~/.claude/projects/<project-dir>/) and run:Every message typed in the T3 composer showsjq -c 'select(.type=="user" and (.message.content|type)=="string") | {entrypoint, turnOrigin, text: .message.content[0:40]}' <transcript>.jsonl
"turnOrigin": "sdk". - Ask Claude to stop the watch (
on: false), then sendWatch https://claude.ai/artifact/<id>again. The watch is refused for the rest of the session. - Control: in a terminal, run
claudein the same project and send the sameWatchmessage. Auto-replies arm, and a comment sent to Claude gets a reply.
Expected behavior
The watch arms comment auto-replies, as it does in a terminal claude session. A comment sent to Claude wakes the thread, and Claude replies in the comment thread.
Actual behavior
The watch connects, but auto-replies never arm. The tool result says:
auto-replies arm only when the user asks for the watch in their own message, and no message from the user started this turn
A comment sent to Claude does not wake the thread.
Control: on the same machine, with the same settings and the same artifact, a terminal claude session armed auto-replies on a typed Watch <url>. The first comment sent to Claude got an auto-reply.
After one stop, every later watch request in that session is refused, including one I typed myself in the composer:
Not watching: watching this artifact was stopped earlier in this session, and this request did not come in a turn this session can verify the user started (a task notification, a wakeup, or a stop receipt started it — or a typed /command, whose origin is not recorded).
Likely cause
Claude Code records every user message T3 sends with turnOrigin: "sdk". Claude Code's artifact watch arms auto-replies only on a turn it can verify the user started, and an sdk turn does not qualify. The session transcript shows it for all three of my messages:
{"entrypoint": "sdk-ts", "turnOrigin": "sdk", "promptId": "<uuid>", "version": "2.1.309"} "Monitor https://claude.ai/artifact/..."
{"entrypoint": "sdk-ts", "turnOrigin": "sdk", "promptId": "<uuid>", "version": "2.1.309"} "help me fix this"
{"entrypoint": "sdk-ts", "turnOrigin": "sdk", "promptId": "<uuid>", "version": "2.1.309"} "Watch https://claude.ai/artifact/..."
The gate lives in Claude Code, not in T3. I don't know whether the Agent SDK lets a host mark a message as typed by the user. If it does, T3 should set that on composer messages. If it doesn't, this needs an upstream request to Anthropic, and a note in T3 that comment auto-replies don't work in T3 threads.
Related: #13978 (the same watcher shows in the Agents panel as a working agent) and #14816 (Artifact tool enabled by default in Claude threads).
Impact
Major degradation or frequent failure
Version or commit
T3 Code (Beta) 0.1.2
Environment
macOS 26.6.2, desktop app; Claude Code 2.1.309 (entrypoint sdk-ts), Opus 5.5, auto permission mode
Workaround
Don't stop a watch in a T3 thread: after a stop, the session can't restart it. Ask Claude to read the comments on demand instead of relying on auto-replies, or run the watch from a terminal claude session.
Activity
rolfilho commentedon Oct 23, 2026
Follow-up: an SDK host can mark a message as human-typed. anthropics/claude-code#102828 shows Claude Desktop messages recorded with
origin: {"kind":"human"},turnOrigin: "human",promptSource: "sdk". T3 composer messages in my transcript showorigin: null,turnOrigin: "sdk",promptSource: "sdk". So the likely fix is in T3: set the human origin on messages typed in the composer, and keepsdkfor automated sends (wakeups, scheduled tasks, orchestration messages).samwang0041-star commentedon Oct 31, 2026
The same
turnOrigin: "sdk"gate also suppresses Claude Code'sultracodekeyword opt-in in T3 threads, not just artifact auto-replies.Repro on T3 Code 0.1.6 (Beta) + Claude Code 2.1.316, with
enableWorkflows: trueand the defaultworkflowKeywordTriggerEnabled:ultracode(standalone or inside a sentence).workflow_keyword_requestattachment, so the model never gets the "opting this turn into multi-agent orchestration — use the Workflow tool" reminder. In my test the first message contained bothultrathinkandultracode: the transcript has anultrathink_effortattachment but noworkflow_keyword_request, and the user message hasturnOrigin: "sdk"/promptSource: "sdk".claudesession (human-typed prompt) emits theworkflow_keyword_requestreminder and the turn can enter the Workflow tool.ultrathinkstill works in T3 because its check does not requireisHumanTypedPrompt.In Claude Code 2.1.316 the keyword trigger is gated as (simplified):
isHumanTypedPromptis derived fromsessionChannelPersonTyped, separate from the visibleultracodesettings key. The xhigh/model-capability gate applies to the persistentultracodesetting and/effort ultracode, not to this keyword path, so this is only about the message provenance.Question for #24962: does stamping
origin: { kind: "human" }also makesessionChannelPersonTypedtrue, so the keyword trigger starts working? If yes, a regression like "a human-origin turn containingultracodeemitsworkflow_keyword_request, while scheduled/MCP turns do not" would lock it in. If not, T3 either needs to pass the session-channel person-typed flag (if the SDK exposes it) or detect the keyword in the adapter/composer itself.Practical impact: the missing Ultracode picker entry cannot be worked around by typing the keyword in a T3 thread today. A plain "use a workflow / fan out agents" request still counts as explicit opt-in for the Workflow tool, but the
ultracodekeyword does not.sipak commentedon Nov 8, 2026
We patched this in a fork and it works. On Claude Code 2.1.319 the CLI keeps only
origin {kind:"human"}from stdin and silently drops other kinds, so it's human or nothing. Our rule: stamp human exactly whencreatedBy === "user"andcreationSourceiswebormobile, on bothstartTurnandsteerTurninClaudeAdapterV2. Leavet3_thread_send, delegations, continuations, limit recovery and scheduled tasks unset. Typed prompts then recordturnOrigin: "human", and agent sends stay"sdk".