I post-trained Qwen3.6-35B-A3B into a text interaction model. It follows writing as a timestamped stream and chooses one action at a time, including doing nothing.
Interaction models let people work with AI more like we work with each other. They continuously take in audio, video, and text, then think, respond, and act in real time.
Thinking Machines argues that interactivity should scale with intelligence, not arrive later as interface polish. This project asks what that idea looks like in text.
The model sees an unfinished document. It can mark text, start a lookup, use or discard a result, reply, or manage a reminder.
I wanted it to feel like a person following along. It should notice a missing fact, remember an instruction, mark matching words, or set a reminder.
The actions came quickly. The harder problem was teaching the model when to act, wait, or do nothing.
Demos
Holding a lookup until it belongs
I write about the 2022 World Cup final, admit that I cannot remember the score, and keep typing. The model starts a background lookup while the draft continues to change.
When the result returns, the model keeps it private. It waits until the draft reaches the unfinished thought, then adds “Argentina 3, France 3 (4-2 on penalties).”
The timing is the point. I never stop writing to ask for the score, and the result does not appear in an unrelated sentence just because the lookup finished.
Marking filler words
I ask the model to watch for filler words, then continue drafting. As each “um” appears, it underlines the exact span and adds a small note to the action rail.
Managing a recurring reminder
I set a recurring “breathe” reminder, then return to brainstorming. The model schedules it while the runtime keeps time.
Each timer fire becomes a small nudge. The reminder persists while the document changes, but never takes over the page or asks me to stop writing.
Applying knowledge to exact spans
I ask the model to notice every animal, then begin a new story. “Tiger” and “monkey” are marked independently as they appear, without a full response.
The base model already knows what an animal is. Training teaches it to carry that instruction across a live stream and apply its knowledge to exact spans in text it has never seen.
Doing Nothing
The least visually impressive film is probably the most important. I type, pause, revise a sentence, and continue writing while the model repeatedly chooses idle.
Exactly half of the 2,000 interaction decisions are idle examples, kept at full weight. Downweighting them makes the model restless and gives it reasons to intervene when nothing needs its attention.
For a system that watches continuously, the absence of unnecessary behavior is part of the capability. A model that always finds something to say is much less pleasant to keep open while I write.
One Decision at a Time
The model receives a serialized history of user, runtime, tool, and timer events. It predicts exactly one action for the current moment.
A simplified lookup moment looks like this:
<event dt=650ms>
source=user
activity=active
text="writing about the 2022 final and
I can't remember the score"
</event>
<event dt=500ms>
source=tool
status=succeeded
result="Argentina 3, France 3.
Argentina won 4-2 on penalties."
</event>
<PREDICT_ONE_ACTION>
Typing enters the stream as complete document snapshots. The latest snapshot is always the source of truth.
Tool results and timer events use the same ordered stream. The model stays grounded in what happened instead of relying on a hidden summary that may disagree with the visible document.
The action space has nine verbs:
idle: nothing should happenmark: point at textdelegate: start a lookupintegrate: use a returned resultskip: discard a stale resultrespond: send a conventional assistant replyschedule: create a remindercancel: stop a remindernudge: deliver a reminder
Keeping these actions separate matters. A highlight should not behave like a chat message. A lookup should not claim attention. A reminder should not be rewritten every time it fires.
Thinking Machines trains from scratch around time-aligned micro-turns, continuous input and output, explicit silence, and asynchronous work.
This project borrows those ideas at a smaller scale, with one important difference. My model stays turn-based underneath.
A browser sampler, event queue, scheduler, and serialized inference loop approximate the continuous exchange that the Thinking Machines model learns natively.
Following a Document, Not a Conversation
A conversation is a list of turns. A document is not. The user may type half a sentence, pause, revise it, move the cursor, or keep typing while a decision is running.
The browser samples the document when typing starts, while typing continues, and after typing pauses. These snapshots act like text micro-turns and preserve when text appeared and changed.
Decisions run serially. Newer snapshots replace older unprocessed snapshots, but tool and timer events are never dropped. The user can keep writing while the model thinks.
Positions use the same UTF-16 offsets as browser selection APIs. This matters because emoji occupy different numbers of code points and browser text units.
A mark is valid only if its offsets still point to the exact text the model claims to have marked.
Near the context limit, the runtime builds a deterministic checkpoint from stored state. It includes the latest document, active reminders, unfinished lookups, live instructions, and handled events.
The checkpoint is not a model-written summary. That makes the boundary reproducible and stops a pending result from vanishing just because the session became long.
Background Work Without Losing the Thread
The lookup path mirrors the interaction and background split in the Thinking Machines post. Here, the background component is a narrow lookup tool rather than a second general model.
When the model delegates, the lookup receives a grounded query tied to the text that caused it. The user keeps writing. The result returns with its original request attached.
The model sees both the fact and the newer draft. It can integrate the result, keep waiting, or discard it if the document has moved on.
A result does not force itself into the interface just because the job finished.
Reminders follow the same shape. The model schedules, the runtime keeps time, and a stale fire from a canceled timer can be rejected.
Thinking Machines gives its model a direct sense of elapsed time. I use a scheduler, so time becomes an event the model reasons about instead of something it measures internally.
Building the Training Data
The dataset contains 2,000 interaction decisions. Each asks what the model should do at one moment rather than asking it to write a complete response.
The non-idle half covers marking, lookup, integration, stale-result skipping, replies, reminders, cancellation, timer firing, and state carried across long contexts.
I mixed them with about 1,000 ordinary assistant examples to preserve general language ability.
The browser sampler that built the training streams is the same sampler used by the interface. This is the text equivalent of trainer and sampler alignment.
Artificial chunks do not behave like real typing. Real writing contains bursts, long pauses, revisions, and unfinished phrases that disappear before they become instructions.
The data includes close pairs that differ in one detail. A direct instruction should activate, while the same words inside a quotation may not.
A fresh lookup result may help, while that result after a topic change should be skipped. An active timer should nudge, while a queued fire from a canceled timer should be discarded.
These pairs teach the difference between recognizing a possible action and deciding that it belongs now.
Everything was mechanically validated, then reviewed by me. An action can be perfectly valid and still feel wrong while someone is writing.
Behavior Without Bookkeeping
The first version asked the model to choose a behavior and emit all of the bookkeeping needed to execute it.
That mixed objective hurt learning.
The final policy no longer emits event IDs, timer IDs, or text offsets. It predicts a compact semantic intent, such as “mark the next um.”
Training the Model
The model is Qwen3.6-35B-A3B with thinking disabled. I trained LoRA adapters through Tinker.
The first run used a larger adapter and an aggressive learning rate. It learned some interaction mechanics but degraded general language behavior and produced repetitive outputs.
Those checkpoints were not safe to promote. I kept the failed run as evidence instead of quietly replacing it.
Smaller experiments isolated the data, output format, learning rate, adapter size, and supervision. The largest improvement came from simplifying the intent format.
The shipped adapter is rank 16 at step 63. It preserved ordinary language ability much better while learning the interaction grammar well enough to carry the films.
The objective used raw token-level weights to emphasize the decision-bearing part of each output without disturbing the balance between interaction and replay data.
I chose the checkpoint on development data. The sealed test remained closed until that choice was complete.
The Preference Problem
Supervised training taught the model how to produce actions, not which action to prefer. A retrieved fact can be correct and grounded but still be unwanted after the user changes topics.
I generated preference pairs that compare valid but intrusive actions with quieter alternatives. They covered stale integration, needless marks, duplicate lookups, ambiguous cancellation, unwanted replies, and correct idleness.
Why Preference Training Instead of On-Policy Distillation
The teacher was much better at comparing complete actions than generating the right one from scratch. It produced the correct action in 121 of 144 probes, or 84.0%.
When shown two complete alternatives, it chose the better one in 716 of 720 comparisons, or 99.4%.
The on-policy distillation recipe I considered samples trajectories from the student and uses per-token reverse KL to move the student toward the teacher’s distribution.
That is attractive when the teacher’s normal policy is the behavior you want to copy.
Here, I had only shown that the teacher’s comparative judgment was reliable. I had not shown that its normal policy assigned enough probability to restrained actions such as idle or skip.
Distillation could therefore reproduce the same unwanted replies or stale integrations more efficiently.
The output format also made complete actions a natural unit of judgment. Each prediction was short, with one early choice usually selecting the action.
The remaining tokens identified an instruction, result, timer, or target.
I therefore used a DAgger-like loop to collect states where the student failed, then compared complete valid actions.
DPO directly raises the preferred completion and lowers the rejected one.
After 20 preference updates, the resulting checkpoints lost more in mechanics and safety than they gained in restraint, so I kept the supervised checkpoint.
This does not rule out DPO or on-policy distillation. It means this preference run did not produce a net improvement.
Before revisiting distillation, I would inspect the teacher’s token probabilities on the exact failure states.
If it consistently favors idle over an intrusive action, its distribution becomes a useful training signal. If it does not, distillation would only optimize the wrong behavior more efficiently.
A Thin Execution Layer
The model chooses a semantic intent. The runtime resolves its references and enforces objective constraints.
A mark must point to text that still exists. An integration must cite a completed lookup. A nudge must follow a real timer fire. Replies and integrations are blocked while the user is typing.
An intent that cannot resolve against the current session state has no effect.
If a newer snapshot arrives during inference, the proposal is checked again against the new state.
The runtime never decides whether an animal is worth marking. That is policy, so it stays with the model.
Rejected attempts remain in the audit trail. The clean interface shows executed actions. A technical view exposes raw output, intent resolution, checks, and timing.
Both views project the same session record. That helped separate model errors from runtime bugs during filming.
Several failed takes exposed runtime problems in mark projection, blocked-action resumption, and the browser’s first segment. Small fixes at shared boundaries solved them without retraining.
Inference
The browser sends full snapshots over a WebSocket. The server commits each snapshot to the session stream and asks the model for one action.
Inference is serialized per session, but newer typing accumulates while a decision runs. The interface does not freeze.
The serialized format is deterministic. Unchanged history produces unchanged bytes, so the engine can reuse the prompt prefix instead of processing the entire session again.
This provides one benefit of persistent streaming sessions without requiring a full-duplex model architecture.
The Final Evaluation
After choosing the checkpoint, I opened a sealed set of 400 interaction decisions exactly once. There were no retries, resampling, tuning, or training afterward.
| Measure | Result |
|---|---|
| Strict, resolvable intent | 334 / 400 (83.5%) |
| Passed mechanical checks | 348 / 400 (87%) |
| Timer lifecycle | 68 / 70 |
| Restraint, correctly quiet | 154 / 220 (70%) |
| Long-context rollover | 72 / 106 |
| Potentially unsafe if unprotected | 27 outputs |
Timer behavior was strongest. Restraint was weakest. Long-context behavior was uneven.
The raw failures mattered more than the percentages. The model replied when silence was required, used stale information, canceled the wrong reminder, or marked when it should have waited.
Twenty-seven outputs could have caused an unsafe or unwanted action without runtime protection. I do not consider this checkpoint ready for autonomous execution.
The five films are controlled demonstrations of behaviors the model can perform. They are not evidence that every similar prompt will work.
A convincing minute-long interaction and a dependable general system are different achievements. This project produced the first while measuring the distance to the second.
Limitations and Future Work
Restraint
The model still sometimes replies, marks, or uses a result when waiting would be better. More runtime rules would hide those mistakes without teaching better judgment.
The next training step is a smaller, better-balanced preference set built from observed errors. Each pair should compare a tempting action with the quieter action that fits the moment.
Long Sessions
The runtime carries state across the context boundary correctly. The evaluation showed that the model does not always use that state correctly.
Responsiveness
The interface accepts typing during inference, but the model still processes one decision at a time. A model trained on persistent, time-aligned streams would close that gap.
Background Agents
Although this project focused on the interaction model, agentic intelligence is also an important part of the system.
A next step is adding asynchronous background agents for deeper reasoning, broader tool use, and longer tasks, while the interaction model stays present and brings their work forward only when it becomes useful.
What I Learned
The base model did not need to learn what a tiger was, what a filler word was, or how to read a football score.
Post-training had to teach a different capability: when that knowledge should become an action inside someone else’s unfinished work.
That separated three problems I had initially treated as one. An action can be mechanically valid, factually correct, and still inappropriate.
The runtime can guarantee the first. It cannot learn the third on the model’s behalf.
For an interaction model, timing is not interface polish. It is part of the prediction.
Silence is not missing output. It is one of the outputs, and often the right one.
Citation
Please cite this work as:
Rajat Tiwari, "Teaching Models Interaction", therajattiwari.com, Sep 2026. https://www.therajattiwari.com/writings/teaching-models-interaction/
Or use the BibTeX citation:
@misc{tiwari2026teachingmodelsinteraction,
author = {Rajat Tiwari},
title = {Teaching Models Interaction},
year = {2026},
howpublished = {therajattiwari.com},
note = {https://www.therajattiwari.com/writings/teaching-models-interaction/},
}