Merge pull request #108 from wagesj45/codex/add-diff-view-to-debug-tab

Add debug diff view
This commit is contained in:
Jordan Wages 2025-07-19 19:33:13 -05:00 committed by GitHub
commit 45125f634d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 27 additions and 2 deletions

View file

@ -33,6 +33,7 @@ let userTheme = 'auto';
let currentTheme = 'light'; let currentTheme = 'light';
let detectSystemTheme; let detectSystemTheme;
let errorPending = false; let errorPending = false;
let showDebugTab = false;
const ERROR_NOTIFICATION_ID = 'sortana-error'; const ERROR_NOTIFICATION_ID = 'sortana-error';
function normalizeRules(rules) { function normalizeRules(rules) {
@ -262,12 +263,16 @@ async function processMessage(id) {
try { try {
const full = await messenger.messages.getFull(id); const full = await messenger.messages.getFull(id);
let text = buildEmailText(full); let text = buildEmailText(full);
const originalText = text;
if (tokenReduction && maxTokens > 0) { if (tokenReduction && maxTokens > 0) {
const limit = Math.floor(maxTokens * 0.9); const limit = Math.floor(maxTokens * 0.9);
if (text.length > limit) { if (text.length > limit) {
text = text.slice(0, limit); text = text.slice(0, limit);
} }
} }
if (showDebugTab) {
await storage.local.set({ lastFullText: originalText, lastPromptText: text });
}
let hdr; let hdr;
let currentTags = []; let currentTags = [];
let alreadyRead = false; let alreadyRead = false;
@ -425,7 +430,7 @@ async function clearCacheForMessages(idsInput) {
} }
try { try {
const store = await storage.local.get(["endpoint", "templateName", "customTemplate", "customSystemPrompt", "aiParams", "debugLogging", "htmlToMarkdown", "stripUrlParams", "altTextImages", "collapseWhitespace", "tokenReduction", "aiRules", "theme", "errorPending"]); const store = await storage.local.get(["endpoint", "templateName", "customTemplate", "customSystemPrompt", "aiParams", "debugLogging", "htmlToMarkdown", "stripUrlParams", "altTextImages", "collapseWhitespace", "tokenReduction", "aiRules", "theme", "errorPending", "showDebugTab"]);
logger.setDebug(store.debugLogging); logger.setDebug(store.debugLogging);
await AiClassifier.setConfig(store); await AiClassifier.setConfig(store);
userTheme = store.theme || 'auto'; userTheme = store.theme || 'auto';
@ -440,6 +445,7 @@ async function clearCacheForMessages(idsInput) {
maxTokens = parseInt(store.aiParams.max_tokens) || maxTokens; maxTokens = parseInt(store.aiParams.max_tokens) || maxTokens;
} }
errorPending = store.errorPending === true; errorPending = store.errorPending === true;
showDebugTab = store.showDebugTab === true;
const savedStats = await storage.local.get('classifyStats'); const savedStats = await storage.local.get('classifyStats');
if (savedStats.classifyStats && typeof savedStats.classifyStats === 'object') { if (savedStats.classifyStats && typeof savedStats.classifyStats === 'object') {
Object.assign(timingStats, savedStats.classifyStats); Object.assign(timingStats, savedStats.classifyStats);
@ -494,6 +500,9 @@ async function clearCacheForMessages(idsInput) {
tokenReduction = changes.tokenReduction.newValue === true; tokenReduction = changes.tokenReduction.newValue === true;
logger.aiLog("tokenReduction updated from storage change", { debug: true }, tokenReduction); logger.aiLog("tokenReduction updated from storage change", { debug: true }, tokenReduction);
} }
if (changes.showDebugTab) {
showDebugTab = changes.showDebugTab.newValue === true;
}
if (changes.errorPending) { if (changes.errorPending) {
errorPending = changes.errorPending.newValue === true; errorPending = changes.errorPending.newValue === true;
updateActionIcon(); updateActionIcon();

View file

@ -31,6 +31,10 @@
.tag { .tag {
--bulma-tag-h: 318; --bulma-tag-h: 318;
} }
#diff-display {
white-space: pre-wrap;
font-family: monospace;
}
</style> </style>
</head> </head>
<body> <body>
@ -286,9 +290,11 @@
<span>Debug</span> <span>Debug</span>
</h2> </h2>
<pre id="payload-display"></pre> <pre id="payload-display"></pre>
<div id="diff-display" class="mt-4"></div>
</div> </div>
</div> </div>
</section> </section>
<script src="../resources/js/diff_match_patch_uncompressed.js"></script>
<script src="options.js"></script> <script src="options.js"></script>
</body> </body>
</html> </html>

View file

@ -21,7 +21,9 @@ document.addEventListener('DOMContentLoaded', async () => {
'aiCache', 'aiCache',
'theme', 'theme',
'showDebugTab', 'showDebugTab',
'lastPayload' 'lastPayload',
'lastFullText',
'lastPromptText'
]); ]);
const tabButtons = document.querySelectorAll('#main-tabs li'); const tabButtons = document.querySelectorAll('#main-tabs li');
const tabs = document.querySelectorAll('.tab-content'); const tabs = document.querySelectorAll('.tab-content');
@ -67,9 +69,17 @@ document.addEventListener('DOMContentLoaded', async () => {
await applyTheme(themeSelect.value); await applyTheme(themeSelect.value);
const payloadDisplay = document.getElementById('payload-display'); const payloadDisplay = document.getElementById('payload-display');
const diffDisplay = document.getElementById('diff-display');
if (defaults.lastPayload) { if (defaults.lastPayload) {
payloadDisplay.textContent = JSON.stringify(defaults.lastPayload, null, 2); payloadDisplay.textContent = JSON.stringify(defaults.lastPayload, null, 2);
} }
if (defaults.lastFullText && defaults.lastPromptText && diff_match_patch) {
const dmp = new diff_match_patch();
dmp.Diff_EditCost = 4;
const diffs = dmp.diff_main(defaults.lastFullText, defaults.lastPromptText);
dmp.diff_cleanupEfficiency(diffs);
diffDisplay.innerHTML = dmp.diff_prettyHtml(diffs);
}
themeSelect.addEventListener('change', async () => { themeSelect.addEventListener('change', async () => {
markDirty(); markDirty();
await applyTheme(themeSelect.value); await applyTheme(themeSelect.value);