mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-15 03:12:21 +02:00
feat(notes): attach selected Notes/Todos as Agent context (#6495)
* feat: add Notes and Todos as agent chat context - Send selected Note/Todo IDs from the Notes UI - Load selected notes with owner scoping in chat routes - Format note content and checklist items for the model - Inject selected notes as untrusted chat context - Add a selected-context indicator beside Shell Access - Keep selected context associated with the active chat session * Improved selected notes context handling and discouragin redundant note lookup and permission requests * Fix selected notes UI when switching chats * fix(notes): harden selected context lifecycle and validation --------- Co-authored-by: Alexandre Teixeira <111787685+alteixeira20@users.noreply.github.com>
This commit is contained in:
co-authored by
Alexandre Teixeira
parent
a8c147b238
commit
8feb50e894
@@ -65,6 +65,8 @@ import { invalidateSettings } from './appConfig.js';
|
||||
let _contextHeaderAnchorEl = null;
|
||||
let _contextHeaderPopupCleanup = null;
|
||||
let _pendingToolApproval = null;
|
||||
const _selectedNoteIdsBySession = new Map();
|
||||
let _pendingSelectedNoteIds = [];
|
||||
let _lastPrivateBrowserUrl = '';
|
||||
function _isPrivateBrowserTool(tool) {
|
||||
const name = String(tool || '').toLowerCase();
|
||||
@@ -240,6 +242,46 @@ import { invalidateSettings } from './appConfig.js';
|
||||
_submitToolApprovalWhenIdle(_pendingToolApproval.approval_id);
|
||||
});
|
||||
|
||||
window.addEventListener('odysseus:notes-context-selected', (event) => {
|
||||
const noteIds = event.detail?.noteIds;
|
||||
if (!Array.isArray(noteIds) || noteIds.length === 0) return;
|
||||
|
||||
const sessionId = sessionModule.getCurrentSessionId?.();
|
||||
if (!sessionId && !sessionModule.hasPendingChat?.()) {
|
||||
console.warn('Cannot attach Notes context: no active or pending chat');
|
||||
return;
|
||||
}
|
||||
|
||||
if (sessionId) {
|
||||
_selectedNoteIdsBySession.set(sessionId, [...noteIds]);
|
||||
} else {
|
||||
_pendingSelectedNoteIds = [...noteIds];
|
||||
}
|
||||
if (event.detail) event.detail.accepted = true;
|
||||
_renderSelectedNotesIndicator(noteIds);
|
||||
});
|
||||
|
||||
window.addEventListener('odysseus:session-changed', (event) => {
|
||||
const sessionId = event.detail?.sessionId;
|
||||
if (sessionId && event.detail?.materialized && _pendingSelectedNoteIds.length) {
|
||||
_selectedNoteIdsBySession.set(sessionId, _pendingSelectedNoteIds);
|
||||
}
|
||||
_pendingSelectedNoteIds = [];
|
||||
_renderSelectedNotesIndicator(
|
||||
sessionId ? (_selectedNoteIdsBySession.get(sessionId) || []) : []
|
||||
);
|
||||
});
|
||||
|
||||
document.getElementById('selected-notes-context-btn')?.addEventListener('click', () => {
|
||||
const sessionId = sessionModule.getCurrentSessionId?.();
|
||||
if (sessionId) {
|
||||
_selectedNoteIdsBySession.delete(sessionId);
|
||||
} else {
|
||||
_pendingSelectedNoteIds = [];
|
||||
}
|
||||
_renderSelectedNotesIndicator([]);
|
||||
});
|
||||
|
||||
function _fmtContextNumber(n) {
|
||||
const v = Number(n || 0);
|
||||
return v ? v.toLocaleString() : '?';
|
||||
@@ -290,6 +332,26 @@ import { invalidateSettings } from './appConfig.js';
|
||||
return Math.max(50, Math.min(95, Math.round(n)));
|
||||
}
|
||||
|
||||
function _renderSelectedNotesIndicator(noteIds){
|
||||
const button = document.getElementById('selected-notes-context-btn');
|
||||
const count = document.getElementById('selected-notes-context-count');
|
||||
|
||||
if (!button || !count) return;
|
||||
|
||||
const total = Array.isArray(noteIds) ? noteIds.length : 0;
|
||||
if(!total){
|
||||
button.style.display = 'none';
|
||||
count.textContent = '';
|
||||
return;
|
||||
}
|
||||
count.textContent = `${total} note${total === 1 ? '' : 's'} selected`;
|
||||
button.style.display = '';
|
||||
button.title = `${total} selected Note/Todo${total === 1 ? '' : 's'} — click to clear`;
|
||||
button.setAttribute(
|
||||
'aria-label',
|
||||
`Clear ${total} selected Note/Todo${total === 1 ? '' : 's'} context`
|
||||
);
|
||||
}
|
||||
function _liveSessionModule() {
|
||||
return (window.sessionModule && window.sessionModule.getCurrentSessionId)
|
||||
? window.sessionModule
|
||||
@@ -2497,6 +2559,12 @@ import { invalidateSettings } from './appConfig.js';
|
||||
const fd = new FormData();
|
||||
fd.append('message', approvalForSend ? '' : _finalMsgWithInject);
|
||||
fd.append('session', streamSessionId);
|
||||
|
||||
const selectedNoteIds = _selectedNoteIdsBySession.get(streamSessionId) || [];
|
||||
if(selectedNoteIds.length){
|
||||
fd.append('selected_note_ids', JSON.stringify(selectedNoteIds))
|
||||
}
|
||||
|
||||
if (approvalForSend) {
|
||||
fd.append('tool_approval_id', approvalForSend.approval_id);
|
||||
fd.append('tool_approval_decision', approvalForSend.decision);
|
||||
|
||||
Reference in New Issue
Block a user