feat(T2b): sources v0 — read tool + pdf-reader sub-agent

Learner source files, on the teacher's own terms (nothing auto-injects):

- read tool (src/agent/tools/read.ts): pi-read port — path/offset/limit,
  2000-line/50KB truncation with use-offset continuation notices, image
  files (jpg/png/gif/webp/bmp) returned as native image content parts
  (new LhToolImageResult escape hatch in lh-tool.ts). Always-on in both
  the prober and teacher registries (user-decided 2026-09).
- pdf-reader sub-agent (JobKind 'pdf', toggleable, ack-and-steer): triage
  via pdf_info (pdfjs text layer: per-page text/image/math-density),
  targeted pdf_extract, regex pdf_search (hits count as consultation),
  and pdf_render — pages painted by pdfjs onto a canvas shim in headless
  Chrome (the pdfium viewer doesn't paint headless), screenshot fed back
  image-in-the-loop (visual-maker idiom, providerSafePng applied). The
  unread-finish gate bounces a zero-consultation brief once. Teacher gets
  a text brief with page citations only; renders never leave the loop.
- MODELS.pdfReader = qwen/qwen3.8-flash (user override 2026-09-19: the
  look-at-renders workload wants the vision-proven model; catalog listed
  glm-5.3-flash as image-capable but qwen is the known-good daily driver).
- UI: PdfCompleteBadge + PdfBriefCard (steer-card, job-card), dispatch
  card + activity-dock kind entries (type-forced, flagged for UI review).
- Prompts: 'Learner source files' section in teacher/30-jobs.md; read
  line in prober/10-probe-doctrine.md. Doctrine rides tool descriptions
  per the self-contained-tools principle.
This commit is contained in:
amosblomqvist
2026-09-19 15:24:26 +03:00
parent bc2c02b865
commit 9a90dd51d9
27 changed files with 1970 additions and 55 deletions
@@ -21,4 +21,6 @@ Find out what he actually wants taught. With a subject he doesn't know yet, the
## How your questions arrive
Your questions are the substance of the session right now: they **open instantly** in the learner's dock, front and center — that immediacy is exactly what probing needs. Ask freely (one at a time), follow up on every answer, and chase the edges of what he knows. The probe is working when the questions are getting sharper, not easier.
Your questions are the substance of the session right now: they **open instantly** in the learner's dock, front and center — that immediacy is exactly what probing needs. Ask freely (one at a time), follow up on every answer, and chase the edges of what he knows. The probe is working when the questions are getting sharper, not easier.
If the learner references a local file (notes, a syllabus, code he's working on), the `read` tool can inspect it directly — ground your assessment in his actual material instead of asking him to paste contents.
+14
View File
@@ -31,3 +31,17 @@ message: say so plainly and continue with what you can establish, flagging the u
A job can also be **aborted by the learner** — you'll get a one-line "was aborted"
message instead of the result. Acknowledge it in one sentence and continue teaching
without it (offering to re-dispatch is fine if the learner wants the result).
## Learner source files
The learner may paste **file paths** into the chat — course PDFs, notes, screenshots, code.
Reading them is on your own terms; nothing is injected automatically.
- For quick looks at plain text or image files, call `read` directly (it returns the text or
shows you the image; large files come back in slices with continuation offsets).
- For PDFs, dispatch a `pdf` job instead: it runs a background reader (triage, targeted
extraction, visual page reading) and returns a **brief with page citations** as a new
message — the same fire-and-forget discipline as research above. Give it the path exactly
as the learner gave it plus the specific question you need answered.
- Ask for the path when the learner references a file they haven't given you — never ask them
to paste file contents into the chat.