Versie 0.2.0

This commit is contained in:
Atreides Assets committed 2026-10-29 11:57:29 +01:00
commit e77d8fd373
495 files changed
+81026

No files matched your search

+89
View File
@@ -0,0 +1,89 @@
// Generated, do not edit. sha256:9505c124878c8b5af0571c1b4757d6fc332a4d6d342508d9c8ff717ce279c7db
import * as db from '../db.js';
import { CONFIG, ENUMS } from '../../shared/config.js';
import { assertEnum, nowIso } from './_shared.js';
import { emitChange } from './_events.js';
import { limitText } from '../ai/limits.js';
function uitRij(r) {
if (!r) return r;
let velden = null;
if (r.fieldsShared != null) {
try { velden = JSON.parse(r.fieldsShared); } catch { velden = []; }
if (!Array.isArray(velden)) velden = [];
}
return { ...r, fieldsShared: velden };
}
export async function logAiToolCall(entry) {
assertEnum('outcome', ENUMS.AI_CALL_OUTCOME, entry.outcome);
if (!entry.sessionId) throw new Error('An audit entry without a session cannot be traced.');
if (!entry.tool) throw new Error('An audit entry without a tool name cannot be traced.');
const momenten = entry.messages == null ? [] : [...entry.messages];
for (const m of momenten) assertEnum('kind', ENUMS.AI_MESSAGE_KIND, m?.kind);
const velden = entry.fieldsShared == null ? null : JSON.stringify([...entry.fieldsShared]);
db.run(`INSERT INTO AiToolCall
(sessionId, client, tool, arguments, fieldsShared, charactersOut, outcome, detail, occurredAt, serverVersion)
VALUES (?,?,?,?,?,?,?,?,?,?)`,
[entry.sessionId, entry.client ?? null, entry.tool,
entry.arguments != null ? JSON.stringify(entry.arguments) : null,
velden, entry.charactersOut ?? null, entry.outcome, entry.detail ?? null,
entry.occurredAt ?? nowIso(), entry.serverVersion ?? null]);
const id = db.lastId();
for (const m of momenten) {
const { text } = limitText(String(m.text ?? ''), CONFIG.AI.LIMITS.MAX_LOG_CHARS);
db.run(`INSERT INTO AiToolCallMessage (callId, kind, text, occurredAt) VALUES (?,?,?,?)`,
[id, m.kind, text, m.occurredAt ?? nowIso()]);
}
await db.persist();
emitChange('ai-activity-changed');
return id;
}
export function countAiToolCallsSince(sinds) {
const vanaf = Number.isInteger(sinds) && sinds >= 0 ? sinds : 0;
const r = db.one(`SELECT COUNT(*) AS n, MAX(id) AS laatste FROM AiToolCall WHERE id > ?`, [vanaf]);
const alles = db.one(`SELECT MAX(id) AS laatste FROM AiToolCall`);
return {
count: r ? r.n : 0,
newestId: (alles && alles.laatste != null) ? alles.laatste : 0,
};
}
export function aiToolCallMessages(callId) {
const n = Number(callId);
if (!Number.isInteger(n) || n <= 0) return [];
return db.all(`SELECT id, callId, kind, text, occurredAt FROM AiToolCallMessage
WHERE callId = ? ORDER BY id`, [n]);
}
export function aiSessions(uren = 24) {
const grens = new Date(Date.now() - Math.max(1, Number(uren) || 24) * 3600_000).toISOString();
return db.all(
`SELECT sessionId, client, serverVersion,
COUNT(*) AS calls, MIN(occurredAt) AS firstAt, MAX(occurredAt) AS lastAt
FROM AiToolCall
WHERE occurredAt >= ?
GROUP BY sessionId, client, serverVersion
ORDER BY lastAt DESC`, [grens])
.map(r => ({ ...r, zonderVersie: r.serverVersion == null }));
}
export function listAiToolCalls(limit = CONFIG.AI.AUDIT_PAGE_SIZE) {
const n = Math.min(Math.max(Number(limit) || CONFIG.AI.AUDIT_PAGE_SIZE, 1), 1000);
return db.all(`SELECT * FROM AiToolCall ORDER BY occurredAt DESC, id DESC LIMIT ?`, [n]).map(uitRij);
}
export function countAiToolCalls() {
const totaal = db.one(`SELECT COUNT(*) AS n FROM AiToolCall`);
const perUitkomst = db.all(`SELECT outcome, COUNT(*) AS n FROM AiToolCall GROUP BY outcome`);
const uitkomsten = {};
for (const k of ENUMS.AI_CALL_OUTCOME) uitkomsten[k] = 0;
for (const r of perUitkomst) uitkomsten[r.outcome] = r.n;
return { total: totaal ? totaal.n : 0, byOutcome: uitkomsten };
}
export function lastAiToolCallAt() {
const r = db.one(`SELECT occurredAt FROM AiToolCall ORDER BY occurredAt DESC, id DESC LIMIT 1`);
return r ? r.occurredAt : null;
}