Merge pull request #33 from wagesj45/codex/suggest-ai-classification-status-spots
Add classification status indicators
This commit is contained in:
commit
2353f6db4d
3 changed files with 55 additions and 18 deletions
|
@ -21,6 +21,7 @@ message meets a specified criterion.
|
|||
- **Debug logging** – optional colorized logs help troubleshoot interactions with the AI service.
|
||||
- **Automatic rules** – create rules that tag or move new messages based on AI classification.
|
||||
- **Context menu** – apply AI rules to selected messages from the message list or display.
|
||||
- **Status icons** – toolbar icons indicate when messages are queued or being classified.
|
||||
- **Packaging script** – `build-xpi.ps1` builds an XPI ready for installation.
|
||||
|
||||
## Architecture Overview
|
||||
|
|
|
@ -13,6 +13,24 @@
|
|||
let logger;
|
||||
let AiClassifier;
|
||||
let aiRules = [];
|
||||
let queue = Promise.resolve();
|
||||
let queuedCount = 0;
|
||||
let processing = false;
|
||||
|
||||
function updateActionIcon() {
|
||||
let path = "resources/img/logo32.png";
|
||||
if (processing) {
|
||||
path = "resources/img/status-classifying.png";
|
||||
} else if (queuedCount > 0) {
|
||||
path = "resources/img/status-queued.png";
|
||||
}
|
||||
if (browser.browserAction) {
|
||||
browser.browserAction.setIcon({ path });
|
||||
}
|
||||
if (browser.messageDisplayAction) {
|
||||
browser.messageDisplayAction.setIcon({ path });
|
||||
}
|
||||
}
|
||||
|
||||
async function sha256Hex(str) {
|
||||
const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str));
|
||||
|
@ -21,7 +39,7 @@ async function sha256Hex(str) {
|
|||
|
||||
async function applyAiRules(idsInput) {
|
||||
const ids = Array.isArray(idsInput) ? idsInput : [idsInput];
|
||||
if (!ids.length) return;
|
||||
if (!ids.length) return queue;
|
||||
|
||||
if (!aiRules.length) {
|
||||
const { aiRules: stored } = await browser.storage.local.get("aiRules");
|
||||
|
@ -36,28 +54,40 @@ async function applyAiRules(idsInput) {
|
|||
|
||||
for (const msg of ids) {
|
||||
const id = msg?.id ?? msg;
|
||||
try {
|
||||
const full = await messenger.messages.getFull(id);
|
||||
const text = full?.parts?.[0]?.body || "";
|
||||
for (const rule of aiRules) {
|
||||
const cacheKey = await sha256Hex(`${id}|${rule.criterion}`);
|
||||
const matched = await AiClassifier.classifyText(text, rule.criterion, cacheKey);
|
||||
if (matched) {
|
||||
for (const act of (rule.actions || [])) {
|
||||
if (act.type === 'tag' && act.tagKey) {
|
||||
await messenger.messages.update(id, { tags: [act.tagKey] });
|
||||
} else if (act.type === 'move' && act.folder) {
|
||||
await messenger.messages.move([id], act.folder);
|
||||
} else if (act.type === 'junk') {
|
||||
await messenger.messages.update(id, { junk: !!act.junk });
|
||||
queuedCount++;
|
||||
updateActionIcon();
|
||||
queue = queue.then(async () => {
|
||||
processing = true;
|
||||
queuedCount--;
|
||||
updateActionIcon();
|
||||
try {
|
||||
const full = await messenger.messages.getFull(id);
|
||||
const text = full?.parts?.[0]?.body || "";
|
||||
for (const rule of aiRules) {
|
||||
const cacheKey = await sha256Hex(`${id}|${rule.criterion}`);
|
||||
const matched = await AiClassifier.classifyText(text, rule.criterion, cacheKey);
|
||||
if (matched) {
|
||||
for (const act of (rule.actions || [])) {
|
||||
if (act.type === 'tag' && act.tagKey) {
|
||||
await messenger.messages.update(id, { tags: [act.tagKey] });
|
||||
} else if (act.type === 'move' && act.folder) {
|
||||
await messenger.messages.move([id], act.folder);
|
||||
} else if (act.type === 'junk') {
|
||||
await messenger.messages.update(id, { junk: !!act.junk });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.aiLog("failed to apply AI rules", { level: 'error' }, e);
|
||||
} finally {
|
||||
processing = false;
|
||||
updateActionIcon();
|
||||
}
|
||||
} catch (e) {
|
||||
logger.aiLog("failed to apply AI rules", { level: 'error' }, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
"96": "resources/img/logo96.png",
|
||||
"128": "resources/img/logo128.png"
|
||||
},
|
||||
"browser_action": {
|
||||
"default_icon": "resources/img/logo32.png"
|
||||
},
|
||||
"message_display_action": {
|
||||
"default_icon": "resources/img/logo32.png"
|
||||
},
|
||||
"background": { "scripts": [ "background.js" ] },
|
||||
"options_ui": {
|
||||
"page": "options/options.html",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue