fix(ai): provide active note identity to sidebar agents

This commit is contained in:
tianma-if committed 2026-10-03 09:25:20 +08:00
1 parent d726122d22
commit e68b6623f4
2 files changed
+22 -7

No files matched your search

+15 -4
View File
@@ -10,9 +10,13 @@ const note = {
};
describe("AI sidebar note context", () => {
test("an independent request receives no current-note context", () => {
expect(sidebarCompanionFocus(note, false)).toBeUndefined();
expect(sidebarLocalContextText(note, false)).toBe("");
test("a request receives the open note identity without its body", () => {
expect(sidebarCompanionFocus(note, false)).toEqual({ memoId: "note-1", title: "QQ 音乐等级" });
const localContext = sidebarLocalContextText(note, false);
expect(localContext).toContain("ID: note-1");
expect(localContext).toContain("Title (data): QQ 音乐等级");
expect(localContext).toContain("get_memo");
expect(localContext).not.toContain(note.contentMarkdown);
});
test("explicitly including the current note works for both assistant modes", () => {
@@ -28,8 +32,15 @@ describe("AI sidebar note context", () => {
test("an explicitly pinned selection is retained without the rest of the note", () => {
const selected = { ...note, selectionMarkdown: " 需要解释的句子 " };
expect(sidebarCompanionFocus(selected, false)).toEqual({ selectionMarkdown: "需要解释的句子" });
expect(sidebarCompanionFocus(selected, false)).toEqual({ memoId: "note-1", title: "QQ 音乐等级", selectionMarkdown: "需要解释的句子" });
expect(sidebarLocalContextText(selected, false)).toContain("需要解释的句子");
expect(sidebarLocalContextText(selected, false)).not.toContain(note.contentMarkdown);
});
test("switching notes sends only the newly open note identity", () => {
const switched = { ...note, memoId: "note-2", noteTitle: "第二篇", contentMarkdown: "第二篇正文" };
expect(sidebarCompanionFocus(switched, false)).toEqual({ memoId: "note-2", title: "第二篇" });
expect(sidebarLocalContextText(switched, false)).toContain("ID: note-2");
expect(sidebarLocalContextText(switched, false)).not.toContain("note-1");
});
});
+7 -3
View File
@@ -12,11 +12,15 @@ export type SidebarNoteContext = {
export const sidebarCompanionFocus = (context: SidebarNoteContext, includeCurrentNote: boolean): CompanionTurnInput["focus"] => {
const selection = context.selectionMarkdown?.trim().slice(0, 2000) ?? "";
const next: NonNullable<CompanionTurnInput["focus"]> = {};
// The open note's identity lets the agent resolve "this note" without
// attaching its body to every unrelated request.
if (context.memoId) {
next.memoId = context.memoId;
if (context.noteTitle?.trim()) next.title = context.noteTitle.trim();
}
if (includeCurrentNote) {
if (context.memoId) next.memoId = context.memoId;
if (context.notebookId) next.notebookId = context.notebookId;
if (context.notebookTitle) next.notebookTitle = context.notebookTitle;
if (context.noteTitle?.trim()) next.title = context.noteTitle.trim();
const content = context.contentMarkdown?.trim() ?? "";
if (content) {
next.contentMarkdown = content.slice(0, 4000);
@@ -31,8 +35,8 @@ export const sidebarLocalContextText = (context: SidebarNoteContext, includeCurr
const selection = context.selectionMarkdown?.trim().slice(0, 2000);
const content = includeCurrentNote ? context.contentMarkdown?.trim().slice(0, 2000) : "";
return [
context.memoId ? `Open EdgeEver note for this turn. When the user refers to this note, use its ID with the connected EdgeEver MCP get_memo tool to read the full content if available:\nID: ${context.memoId}\nTitle (data): ${context.noteTitle?.trim() || "(untitled)"}` : "",
selection ? `Selected text from the current note (data):\n${selection}` : "",
includeCurrentNote && context.noteTitle?.trim() ? `Current note title (data): ${context.noteTitle.trim()}` : "",
content ? `Current note body (data):\n${content}` : "",
].filter(Boolean).join("\n\n");
};