feat(ai-chat): сообщать агенту о правках пользователя между ходами (per-turn diff) #281
Open
agent_coder
wants to merge 3 commits from
feat/274-ai-chat-page-diff into develop
pull from: feat/274-ai-chat-page-diff
merge into: vvzvlad:develop
vvzvlad:main
vvzvlad:fix/283-slash-layout
vvzvlad:image-inline-row
vvzvlad:feat/276-ai-chat-dock
vvzvlad:feat/270-stress-accent
vvzvlad:fix/269-table-menu-refocus
vvzvlad:feat/275-codeblock-buttons
vvzvlad:feat/273-temp-note-delete
vvzvlad:develop
vvzvlad:feat/268-comment-hover
vvzvlad:docs/dev-stand-guide
vvzvlad:feat/266-scroll-position
vvzvlad:fix/260-collab-docname-slugid
vvzvlad:test/244-phase2-tail
vvzvlad:fix/262-reindex-progress-realtime
vvzvlad:fix/258-changelog-compare-links
vvzvlad:feature/offline-sync
vvzvlad:feat/git-sync
vvzvlad:feat/184-autonomous-agent-runs
vvzvlad:fix/244-dataloss-bugs
vvzvlad:feat/246-spoiler
vvzvlad:feat/221-image-captions
vvzvlad:test/244-part-b
vvzvlad:feat/251-intentional-clear
vvzvlad:fix/embeddings-reindex-progress
vvzvlad:refactor/193-tool-spec-registry
vvzvlad:fix/255-ws-redis-adapter-leak
vvzvlad:fix/252-e2e-open-handles
vvzvlad:feat/229-catalog-yaml
vvzvlad:feat/243-blob-sandbox
vvzvlad:feat/228-inline-footnotes
vvzvlad:fix/qa-ui-bugs-216-218
vvzvlad:feature/agent-roles-catalog
vvzvlad:fix/share-alias-rename
vvzvlad:fix/ai-chat-empty-render
vvzvlad:feat/191-chat-doc-binding
vvzvlad:feat/201-temporary-notes
vvzvlad:feat/198-interrupt-agent
vvzvlad:feat/ai-chat-full-history
vvzvlad:feat/199-ai-generate-title
vvzvlad:feat/205-share-aliases
vvzvlad:batch/issues-189-187-170
vvzvlad:feat/170-mcp-test-button
vvzvlad:feat/189-context-badge
vvzvlad:feat/198-interrupt-agent-send-now
vvzvlad:fix/issues-190-159
vvzvlad:fix/ai-chat-new-chat-during-stream
vvzvlad:fix/ai-chat-stream-perf
vvzvlad:batch/issues-2026-06-25
vvzvlad:feat/ai-chat-persistent-history
vvzvlad:fix/ai-chat-copy-chat-wysiwyg
vvzvlad:fix/ai-stream-reset-resilience
vvzvlad:fix/ai-stream-undici-timeout
vvzvlad:fix/footnote-review-1227-followup
vvzvlad:fix/ai-chat-token-counter-realtime
vvzvlad:docs/manual-qa-test-plan
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2f3d5d3783 |
docs: fix escapeAttr comment count (three, not four) (#274 review)
The regex strips three attribute-breaking chars (" < >); the JSDoc said four.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
6e681a9c66 |
fix(#274): escape page_changed injection surface, drop dead content_hash (review F1-F5)
F1: escape the collaborative page title before interpolating into
<page_changed page="..."> (and the pre-existing openedPage attr) — strip
<>" and collapse whitespace, so a crafted title can't break out of the
attribute into the system prompt (cross-user injection).
F2: neutralize <page_changed>/</page_changed> occurrences inside the diff body
so a crafted line can't close the block early.
F3: remove the dead content_hash column (written every turn, never read) —
migration, repo, service hashing + crypto import, db.d.ts, spec asserts.
F4: test the best-effort catch branches (detectPageChange / snapshotOpenPage
swallow errors and don't break the turn).
F5: soften the overstated 'diff cannot smuggle instructions' comment to
defense-in-depth framing referencing the F1/F2 mitigations + safety sandwich.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
8c5b57ebfa |
feat(ai-chat): notify the agent of user page edits between turns (closes #274)
The agent rebuilds context from DB each turn and didn't know the user manually edited the open page since its last response, so it could overwrite those edits. Add a per-turn ephemeral <page_changed> note in the system prompt (twin of INTERRUPT_NOTE, self-clearing) carrying a unified Markdown diff of what changed since the END of the agent's previous turn. - New ai_chat_page_snapshots table (migration + hand-declared db.d.ts/entity types) storing the page Markdown per (chat,page) at each turn's end. - Pure computePageChange util (whitespace-normalized unified diff via the existing jsdiff dep, 6KB cap + getPage hint). - Turn start: if the open page's updatedAt moved past the snapshot, diff current vs snapshot; non-empty -> PAGE_CHANGED_NOTE in the safety sandwich. - Turn end: upsert the snapshot on EVERY terminal path (onFinish/onError/onAbort, once) so the agent's own edits are excluded by construction even on aborted turns. All best-effort (never breaks/latency-regresses a turn); fast path when updatedAt is unchanged. Server-only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |