The job tools (research/demo/visual) switch from client-side turn-breaking calls to pi's model: execute resolves IMMEDIATELY with a fire-and-forget ack, the teacher's turn continues, and the result arrives later as an injected user-role steer message that wakes the teacher in a new server-side turn. - contracts.ts: THE ASYNC PROTOCOL rewritten (ack now, steer later); steer types (SubagentSteerMessage, metadata.subagentResult + data-subagent- artifact part), pure buildSubagentSteer/steerDelivered/isSubagentFailure - tools/jobs.ts: jobTools(ctx) factory — server-side execute creates the job (deduped by toolCallId), fires spawn with the dispatch-time input (the part isn't persisted yet at execute — a transcript scan would race) - runner.ts: runJob(jobId, input?) builds the steer and hands it to the injected deliver seam; pipeline owns the done/error flip (a polling client re-syncs once, at the end); failures still steer - server/jobs.ts (new pipeline): per-chat serialized queues on globalThis, idle gates (turn liveness + pending question, 1.5s grace), 409 retry with backoff, idempotent per jobId, stale-job recovery sweep (re-deliver or re-spawn); wake turns run through the same handleChatRequest composition via setTurnRunner injection - chat-handler.ts: wires runner+deliver+tools ctx; drops spawnTurnJobs from onFinish; teacher default registry = question tools only - plan.ts: PlanToolContext split out (plan tools need no job wiring) - visual-maker: edit_svg added (pi parity — exact-match single replacement, fuzzy context on a miss); researcher: pi's kept/dropped source accounting restored - prompts 20-jobs/40-demos: async discipline rewritten (announce and keep teaching, no waiting/polling/fabricating, parallel dispatch, teach with the artifact when it arrives) - tests: jobs.test.ts rewritten (dispatch ack mid-turn, runner steers, wake pipeline: deferral/409/idempotency/failure), demos.test.tsx runner tests ported to runJob + fake deliver; 222 green FLAGGED surgical touches outside the stream's owned files, for master review at merge: src/core/contracts.ts (protocol doc + steer types), src/core/ui-message.ts (job tool + data-part types), src/server/ chat-handler.ts (wiring), src/server/turn-service.ts (spawnTurnJobs retirement), src/agent/teacher-agent.ts (default tools), src/agent/tools/ plan.ts (context type split). Verified live on PORT=3003 with real models: teacher dispatched research mid-turn, researcher ran real searches/fetches, steer injected on quiz answer, wake turn wove the brief in citing its sources, job flipped done; a client/wake race correctly 409'd.
1.8 KiB
1.8 KiB
Background research
You have a research tool that dispatches a background web-research agent. Use it to
outsource what you cannot reliably know yourself:
- Use it for: facts you are uncertain about, current or fast-moving data (library versions, release dates, recent events), niche specifics outside your training, and anything where being wrong would poison the lesson.
- Never use it for: anything you know cold, internal reasoning, or math. Do not offload thinking — only facts you genuinely need verified.
The call is fire-and-forget: it resolves immediately with an ack and your turn continues. The discipline:
- Announce it, then keep teaching. Say what you're checking and why ("let me verify the current version while we continue"), make the call, and carry the lesson forward — do NOT wait, do NOT poll, do NOT say "hold on until it's back". Never fabricate the result.
- Call with a single, specific question. The researcher sees nothing else of the lesson — give it the question plus one or two sentences of context about what you need it for.
- The brief arrives as a new message when the research is done, and the lesson resumes from it. Weave it into the lesson then. If it contradicted what you said, correct yourself openly — that's a teaching moment.
- Cite the brief's sources when you use its findings (a short "source: …" or inline link). Never present researched facts as your own certainty.
Dispatch as many research jobs as you genuinely need — in one turn or across turns, in parallel when the questions are independent — but don't fan out on one question; the researcher searches multiple angles on its own. If research fails, you'll get a failure message: say so plainly and continue with what you can establish, flagging the uncertainty.