| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
fix(orchestration): restore agent attribution in director summary (#554) * fix(orchestration): use metadata-based human/agent discrimination in director Closes #511 The original approach used AGENT_PREFIX_RE on converted message content to distinguish human turns from agent turns. This was unreliable: message-converter.ts applies a [senderName]: prefix to ALL role:'user' messages unconditionally, so extractLastHumanMessage() matched every human message as an agent turn and always returned null — the Open Student Question section never fired. Fix per reviewer feedback (use real structured metadata, not display text): - extractLastHumanMessage() now takes StatelessChatRequest['messages'] (pre-conversion) and uses msg.metadata.originalRole === 'user' as the source-of-truth discriminator. Text is extracted from msg.parts directly — no content parsing. - summarizeConversation() uses msg.role for human/agent discrimination. In the director path, convertMessagesToOpenAI() is called without currentAgentId, so peer agent messages remain role:'assistant' and role:'user' reliably identifies human turns. The [senderName]: prefix is stripped from summary output cosmetically only. - buildDirectorPrompt() 10th param changed from OpenAIMessage[] to StatelessChatRequest['messages']; director-graph.ts passes state.messages (already in scope at line 164, no extra computation). - Tests updated to use director-path message shapes: humanMsg() carries [You]: prefix, agentMsg() uses role:'assistant'. extractLastHumanMessage tests use originalRole metadata. * refactor(orchestration): move attribution fix to prompt layer; add eval fixtures Replaces procedural extractLastHumanMessage + buildOpenStudentQuestionSection wiring with three declarative rules in director/system.md — labels are authoritative, END is blocked by an unresolved student question, and a brief acknowledgment does not constitute resolution. Removes: extractLastHumanMessage, buildOpenStudentQuestionSection, {{openStudentQuestionSection}} placeholder, originalMessages 10th param. Keeps: summarizeConversation role-based discrimination (still the core fix). Adds eval/orchestration/ (runner.ts, judge.ts, reporter.ts, types.ts, scenarios/premature-end.json) following the outline-language eval pattern, with a deterministic premature-END scenario as the must-have regression guard. * chore(orchestration): remove eval fixtures and stale tests per review Per wyuc's review on PR #554: the eval/orchestration fixtures pass on main before the fix, so they don't discriminate — pull them out so the PR lands as a clean prompt-layer change. Track eval as a follow-up. - Remove eval/orchestration/ (judge, runner, reporter, types, scenario) - Remove eval:orchestration npm script from package.json - Delete 3 stale tests from tests/prompts/templates.test.ts that called buildDirectorPrompt with a 10th param removed in the refactor - Fix prettier formatting in conversation-summary.test.ts and templates.test.ts (was masking the TS break in CI) All checks pass: prettier clean, 333 unit tests green, 0 lint errors, tsc --noEmit clean. --------- Co-authored-by: 杨慎 <117187635+cosarah@users.noreply.github.com> | 3 个月前 | |
fix: render whiteboard math via KaTeX instead of raw LaTeX text (#938) * fix: render whiteboard math via KaTeX instead of raw LaTeX text * fix: recognize single-command LaTeX with a braced argument The fallback missed valid single-command expressions (\vec{v}, \hat{x}, \overline{x}) whose command is not in COMMON_LATEX_COMMAND, because commands.length < 2 returned null and they rendered as raw text. Now a single command counts as math when it carries a braced argument, while path-like prose (C:\temp) still has no braced argument and stays text. Add regression tests for both cases. * fix: exclude Windows drive paths before the common-LaTeX-command check COMMON_LATEX_COMMAND.test() ran before any path-like check, so C:\alpha, C:\theta and C:\pi were classified as LaTeX and rendered through KaTeX. Return early for text starting with a drive letter, and add C:\alpha to the Windows-path regression cases so a path whose segment matches COMMON_LATEX_COMMAND is covered. --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: wyuc <wang-yc24@mails.tsinghua.edu.cn> | 1 个月前 | |
refactor(whiteboard): file-based prompts + geometry conflict detection (#485) * feat(prompts): declare whiteboard role prompt IDs + whiteboard-reference snippet * feat(prompts): add whiteboard role template skeletons + reference snippet stub * refactor(orchestration): move buildWhiteboardGuidelines to role-specific markdown templates * docs(prompts): whiteboard guidelines now in markdown templates * feat(prompts): whiteboard-reference canvas + JSON output sections * feat(prompts): whiteboard-reference action schemas for text/shape/line * feat(prompts): whiteboard-reference action schemas for latex/chart/table * feat(prompts): whiteboard-reference action schemas for code/delete/clear/close * feat(prompts): whiteboard-reference LaTeX JSON escape section * feat(prompts): whiteboard-reference bounds + overlap section * feat(prompts): whiteboard-reference font + latex height tables * feat(prompts): whiteboard-reference pre-output checklist * feat(prompts): expand teacher whiteboard template * feat(prompts): expand assistant whiteboard template * feat(prompts): expand student whiteboard template * test(prompts): assert whiteboard-reference sections reach every role prompt * tune(prompts): cap teacher element budget at 4/turn, encourage wb_clear on crowded board * tune(prompts): simplify teacher template — single conservative rule + state-awareness emphasis * tune(prompts): add LaTeX-height × text-fontSize pairing table for visual weight consistency * feat(orchestration): preserve image parts from UIMessage to AI SDK ModelMessage * feat(eval): attach prior-turn whiteboard screenshot as user message image part Gated behind EVAL_ATTACH_PRIOR_SCREENSHOT=1 env. When on, captures a screenshot after every turn (not just checkpoints) and attaches it as a file part with mediaType:'image/png' on the next user message. Teacher prompt gets a new 'Prior-state image' section telling the agent to treat it as direct visual feedback. * fix(orchestration): strip data: prefix before passing image to AI SDK Vercel AI SDK's streamText/generateText treats ImagePart.image as a URL to fetch when it's a string. data: URLs fail the http/https scheme check and throw AI_DownloadError. Strip the data URL prefix and pass raw base64 with mediaType separately — AI SDK treats base64 strings as data content. * refactor(whiteboard): add conflict summarizer, drop prior-screenshot feature Eval across flash (image-on vs off × repeat-3) and pro (same) showed the prior-screenshot image-input feature gives ~0 net benefit: +0.4 overall on flash and −0.6 on pro. The image feedback loop's theoretical upside (agent self-correcting from visual) didn't materialize — weak models couldn't act on the image and strong models "found things to fix" and over-corrected. Meanwhile programmatic geometry detection on the raw JSON cleanly lifted overlap from 6.3 → 8.1 on flash. So: remove the image-input plumbing, keep a programmatic equivalent. ## Removed (reverts 0e07e9e, b5675bc, image half of 097ec2f) - lib/orchestration/ai-sdk-adapter.ts: revert multimodal content passthrough - lib/orchestration/summarizers/message-converter.ts: revert image part extraction; user content is back to string-only - lib/orchestration/summarizers/conversation-summary.ts: revert multimodal content flattening - lib/orchestration/director-graph.ts: revert HumanMessage multimodal cast - tests/orchestration/message-converter.test.ts: deleted (was purely image-conversion tests) - eval/whiteboard-layout/runner.ts: drop image attach, vision gate, per-turn screenshot capture; revert to checkpoint-only capture - Role templates (wb-teacher / wb-assistant / wb-student): strip "Prior-state image" sections ## Added - lib/orchestration/summarizers/whiteboard-conflicts.ts: pure geometry detector. Computes bbox IoU, line segment vs bbox intersection, and canvas edge clipping on the current whiteboard state. Renders a text block for inclusion in the system prompt. - lib/orchestration/summarizers/state-context.ts: wires the conflict block in after the whiteboard element listing. - Role templates: replace image-reading guidance with concise "Layout conflicts" sections pointing at the computed list, with a strong anti-action anchor so agents don't self-trigger wb_clear when the list is empty. ## Eval instrumentation (orthogonal) - EVAL_ENABLE_THINKING=1 opt-in to enable model thinking per-request. app/api/chat/route.ts reads body.thinking; runner.ts forwards it. Default chat path stays on enabled:false for latency. - Per-turn wall-clock timing: eval/whiteboard-layout/{runner,reporter, types}.ts capture and report mean/p50/p95/total turn latency. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(whiteboard): address code-review feedback W1: drop stale "prior-state image" reference from conflict-block prose (lib/orchestration/summarizers/whiteboard-conflicts.ts) — the image feature was removed; the text now says "real visible problem on the current board". W3: type `thinking` on StatelessChatRequest instead of reading it through a cast. `app/api/chat/route.ts` now accesses `body.thinking` directly; frontend callers can discover the field via TS completion. W4: unify canvas height constant to 563 (matching the actual rendered pixel count from capture.ts). The geometry detector's CANVAS_HEIGHT, the snippet's Dimensions / coordinate system / layout-guide text, and examples all now agree. N6: add tests/orchestration/whiteboard-conflicts.test.ts — 17 cases covering empty input, bbox overlap threshold (30%, 50%, 100%, plus 10% sub-threshold), line-crosses-bbox (through, endpoint-inside, path-above), canvas clipping on all 4 edges, exact-edge placement (not reported), malformed elements (skipped not crashed), and output format. All 43 tests pass; tsc --noEmit clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(eval): finish canvas-height 563 unification Second-pass code review caught one residual 562.5 in app/eval/whiteboard/page.tsx that the first cleanup (commit 7a006bb) missed. The 0.5px disagreement was harmless in practice (Playwright captures rounded to 563), but inconsistent with the geometry detector and the prompt snippet now agreeing on 563. All 43 tests pass; tsc clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: prettier format whiteboard-conflicts.test + eval/runner CI's `pnpm check` (prettier --check) caught two unformatted files: - eval/whiteboard-layout/runner.ts - tests/orchestration/whiteboard-conflicts.test.ts Auto-fixed via `pnpm prettier --write`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: 杨慎 <117187635+cosarah@users.noreply.github.com> | 4 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 3 个月前 | ||
| 1 个月前 | ||
| 4 个月前 |