feat: add TypeSafe Jev as HITL audit backend

Let audit_agent approve or reject with one System One call instead of chat JSON, while keeping the OpenAI-compatible backend as an option.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ed1s0nZandCursor committed 2026-09-22 21:15:53 +08:00
1 parent 3aa9274675
commit 38b96ec67a
30 files changed
+1372 -21

No files matched your search

+139 -2
View File
@@ -272,9 +272,15 @@ function applyHitlDefaultConfigFromServer(data) {
reviewer: reviewer,
timeoutSeconds: timeoutSeconds
};
const backend = hitlNormalizeAuditBackend(src.auditBackend || src.audit_backend);
const model = String(src.auditModel || src.audit_model || '').trim();
if (backend) out.auditBackend = backend;
if (model) out.auditModel = model;
if (typeof window !== 'undefined') {
window.csaiHitlDefaultConfig = out;
window.csaiHitlDefaultReviewer = reviewer;
if (backend) window.csaiHitlAuditBackend = backend;
if (model || backend) window.csaiHitlAuditModel = model;
if (Array.isArray(src.hitlGlobalToolWhitelist)) {
window.csaiHitlGlobalToolWhitelist = src.hitlGlobalToolWhitelist;
}
@@ -1088,6 +1094,8 @@ function refreshHitlPageReviewerBar() {
if (typeof window.bindHitlReviewerToggleListeners === 'function') {
window.bindHitlReviewerToggleListeners();
}
renderHitlPageAuditEngine();
renderHitlStrategyJevHint();
}
let hitlDefaultAuditPrompt = '';
@@ -1114,6 +1122,7 @@ function switchHitlStrategyMode(mode) {
if (reviewTa) reviewTa.hidden = hitlStrategyMode !== 'review_edit';
if (hintApproval) hintApproval.hidden = hitlStrategyMode !== 'approval';
if (hintReview) hintReview.hidden = hitlStrategyMode !== 'review_edit';
renderHitlStrategyJevHint();
}
function showHitlStrategyFeedback(text, isError) {
@@ -1151,6 +1160,23 @@ async function refreshHitlAuditStrategy() {
}
}
function renderHitlStrategyJevHint() {
let el = document.getElementById('hitl-strategy-hint-jev');
const bar = document.querySelector('.hitl-page-strategy-bar') || document.getElementById('hitl-page-strategy-bar');
if (!el && bar) {
el = document.createElement('p');
el.className = 'hitl-page-strategy-hint';
el.id = 'hitl-strategy-hint-jev';
const reviewHint = document.getElementById('hitl-strategy-hint-review-edit');
if (reviewHint && reviewHint.parentNode) reviewHint.parentNode.insertBefore(el, reviewHint.nextSibling);
else bar.appendChild(el);
}
if (!el) return;
const ts = hitlCurrentAuditEngine().backend === 'typesafe';
el.hidden = !ts;
if (ts) el.textContent = hitlT('strategyHintJev', 'TypeSafe Jev evaluates the custom strategy as structured questions. Built-in destructive rules remain a hard floor.');
}
async function saveHitlAuditStrategy() {
const approvalTa = document.getElementById('hitl-audit-agent-prompt');
const reviewTa = document.getElementById('hitl-audit-agent-prompt-review-edit');
@@ -1205,7 +1231,6 @@ function refreshHitlActivePanel() {
}
function hitlDecidedByLabel(v) {
const key = 'reviewer' + String(v || 'human').replace(/_([a-z])/g, function (_, c) { return c.toUpperCase(); }).replace(/^./, function (c) { return c.toUpperCase(); });
const map = {
human: hitlT('reviewerHuman', 'Human'),
audit_agent: hitlT('reviewerAgent', 'Audit Agent'),
@@ -1215,6 +1240,83 @@ function hitlDecidedByLabel(v) {
return map[v] || v || '-';
}
function hitlNormalizeAuditBackend(v) {
const s = String(v || '').trim().toLowerCase();
if (s === 'typesafe' || s === 'jev' || s === 'type-safe' || s === 'typesafe-ai') return 'typesafe';
if (s === 'openai' || s === 'openai_compatible' || s === 'llm') return 'openai';
return '';
}
function hitlCurrentAuditEngine() {
const cfg = (typeof window !== 'undefined' && window.csaiHitlDefaultConfig) || {};
const backend = hitlNormalizeAuditBackend(cfg.auditBackend || (typeof window !== 'undefined' && window.csaiHitlAuditBackend));
let model = String(cfg.auditModel || (typeof window !== 'undefined' && window.csaiHitlAuditModel) || '').trim();
if (backend === 'typesafe' && !model) model = 'jev-latest';
return { backend: backend || 'openai', model: model };
}
function hitlAuditEngineLabel(backend, model) {
const b = hitlNormalizeAuditBackend(backend);
if (!b) return '';
const name = b === 'typesafe'
? hitlT('auditEngineJev', 'TypeSafe Jev')
: hitlT('auditEngineOpenAI', 'OpenAI protocol');
const m = String(model || '').trim();
return m ? (name + ' · ' + m) : name;
}
function hitlAuditEngineFromItem(item) {
const data = item && typeof item === 'object' ? item : {};
let backend = hitlNormalizeAuditBackend(data.auditBackend || data.audit_backend);
let model = String(data.auditModel || data.audit_model || '').trim();
if (!backend) {
const payload = typeof window.hitlParsePayloadObject === 'function'
? hitlParsePayloadObject(data.payload || '')
: {};
const approval = payload && payload.hitlApproval && typeof payload.hitlApproval === 'object'
? payload.hitlApproval
: {};
backend = hitlNormalizeAuditBackend(approval.auditBackend || approval.audit_backend);
if (!model) model = String(approval.auditModel || approval.audit_model || '').trim();
}
if (!backend) {
const comment = String(data.comment || '');
if (/TypeSafe|破坏分|choice=|Jev/i.test(comment)) backend = 'typesafe';
else if (hitlReviewerNormalize(data.decidedBy || data.decided_by) === 'audit_agent') backend = 'openai';
}
if (backend === 'typesafe' && !model) model = 'jev-latest';
return { backend: backend, model: model };
}
function ensureHitlPageAuditEngineEl() {
let el = document.getElementById('hitl-page-audit-engine');
if (el) return el;
const bar = document.getElementById('hitl-page-reviewer-bar');
if (!bar) return null;
el = document.createElement('p');
el.className = 'hitl-page-audit-engine';
el.id = 'hitl-page-audit-engine';
el.hidden = true;
const hint = bar.querySelector('.hitl-page-reviewer-hint');
if (hint) bar.insertBefore(el, hint);
else bar.appendChild(el);
return el;
}
function renderHitlPageAuditEngine() {
const el = ensureHitlPageAuditEngineEl();
if (!el) return;
const info = hitlCurrentAuditEngine();
const engine = hitlAuditEngineLabel(info.backend, info.model);
if (!engine) {
el.hidden = true;
el.textContent = '';
return;
}
el.hidden = false;
el.textContent = hitlT('auditEngineLabel', 'Approval engine') + ':' + engine;
}
function hitlFormatTime(v) {
if (!v) return '-';
try {
@@ -1594,7 +1696,11 @@ function renderHitlLogsTable(items) {
'<td>' + escapeHtml(String(item.toolName || '-')) + '</td>' +
'<td class="hitl-logs-cell-mono">' + escapeHtml(String(item.conversationId || '-')) + '</td>' +
'<td><span class="hitl-decision-tag ' + decisionCls + '">' + escapeHtml(hitlDecisionLabel(decision)) + '</span></td>' +
'<td>' + escapeHtml(hitlDecidedByLabel(item.decidedBy)) + '</td>' +
'<td>' + escapeHtml(hitlDecidedByLabel(item.decidedBy)) + (function () {
const engine = hitlAuditEngineFromItem(item);
const label = hitlAuditEngineLabel(engine.backend, engine.model);
return label ? '<div class="hitl-log-engine">' + escapeHtml(label) + '</div>' : '';
}()) + '</td>' +
'<td class="hitl-logs-summary">' + escapeHtml(summary) + '</td>' +
'<td>' + escapeHtml(hitlFormatTime(item.decidedAt || item.createdAt)) + '</td>' +
'<td class="hitl-logs-actions">' +
@@ -1676,6 +1782,8 @@ function refreshHitlI18n() {
syncAllHitlLogFilterSelects();
renderHitlLogsPagination();
renderHitlPendingPagination();
renderHitlPageAuditEngine();
renderHitlStrategyJevHint();
}
function renderHitlLogsPagination() {
@@ -1788,6 +1896,33 @@ async function openHitlLogModal(idOpt) {
decisionEl.innerHTML = '<span class="hitl-decision-tag ' + cls + '">' + escapeHtml(hitlDecisionLabel(decision)) + '</span>';
}
if (decidedByEl) decidedByEl.textContent = hitlDecidedByLabel(item.decidedBy);
let engineRow = document.getElementById('hitl-log-detail-engine-row');
let engineEl = document.getElementById('hitl-log-detail-engine');
if (!engineRow || !engineEl) {
const decidedRow = decidedByEl && decidedByEl.closest('.hitl-log-detail-row');
const dl = decidedRow && decidedRow.parentElement;
if (dl && decidedRow) {
engineRow = document.createElement('div');
engineRow.className = 'hitl-log-detail-row';
engineRow.id = 'hitl-log-detail-engine-row';
engineRow.hidden = true;
engineRow.innerHTML = '<dt>' + escapeHtml(hitlT('colAuditEngine', 'Approval engine')) + '</dt><dd id="hitl-log-detail-engine">—</dd>';
if (decidedRow.nextSibling) dl.insertBefore(engineRow, decidedRow.nextSibling);
else dl.appendChild(engineRow);
engineEl = document.getElementById('hitl-log-detail-engine');
}
}
if (engineRow && engineEl) {
const engine = hitlAuditEngineFromItem(item);
const label = hitlAuditEngineLabel(engine.backend, engine.model);
if (label) {
engineEl.textContent = label;
engineRow.hidden = false;
} else {
engineEl.textContent = '';
engineRow.hidden = true;
}
}
if (timeEl) timeEl.textContent = hitlFormatTime(item.decidedAt || item.createdAt);
const comment = String(item.comment || '').trim();
if (commentRow && commentEl) {
@@ -1823,6 +1958,8 @@ window.refreshHitlPageWhitelist = refreshHitlPageWhitelist;
window.refreshHitlPending = refreshHitlPending;
window.refreshHitlLogs = refreshHitlLogs;
window.refreshHitlActivePanel = refreshHitlActivePanel;
window.renderHitlPageAuditEngine = renderHitlPageAuditEngine;
window.renderHitlStrategyJevHint = renderHitlStrategyJevHint;
window.switchHitlPageTab = switchHitlPageTab;
window.switchHitlStrategyMode = switchHitlStrategyMode;
window.resetHitlAuditStrategy = resetHitlAuditStrategy;