Begin adding AI memory
This commit is contained in:
@@ -39,6 +39,113 @@
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div class="column is-12">
|
||||
<article class="box">
|
||||
<h2 class="title is-6">Diagnostics Quick Checks</h2>
|
||||
<p class="is-size-7 has-text-grey" style="margin-bottom: 0.65rem;">
|
||||
Run projection shadow, event ledger smoke, and trace diagnostics from one place.
|
||||
</p>
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-12-tablet is-3-desktop">
|
||||
<form id="projection-shadow-form">
|
||||
<label class="label is-size-7">Projection Shadow</label>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input is-small" name="session_lookup" placeholder="name | id | service | identifier" list="diagnostics-session-options" required>
|
||||
<input type="hidden" name="session_id">
|
||||
</div>
|
||||
<p class="help is-size-7" title="Use this when a thread looks wrong in Compose and you need to compare DB messages vs event projection.">Pick a session to compare message table vs event projection.</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input is-small" name="detail_limit" value="25" type="number" min="0" max="200">
|
||||
</div>
|
||||
</div>
|
||||
<button class="button is-small is-link is-light" type="submit">Run Shadow</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="column is-12-tablet is-3-desktop">
|
||||
<form id="event-ledger-smoke-form">
|
||||
<label class="label is-size-7">Event Ledger Smoke</label>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input is-small" name="minutes" value="120" type="number" min="1" max="10080">
|
||||
</div>
|
||||
<p class="help is-size-7" title="Use this to check that recent traffic is actually writing canonical events.">Checks whether recent actions were written to `ConversationEvent`.</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input is-small" name="service" placeholder="service" list="diagnostics-service-options">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input is-small" name="require_types" placeholder="message_created,reaction_added" list="diagnostics-event-type-options">
|
||||
</div>
|
||||
<p class="help is-size-7" title="If set, response includes missing required event types so you can quickly spot dual-write gaps.">Optional required event types (comma-separated).</p>
|
||||
</div>
|
||||
<button class="button is-small is-link is-light" type="submit">Run Smoke</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="column is-12-tablet is-3-desktop">
|
||||
<form id="trace-diagnostics-form">
|
||||
<label class="label is-size-7">Trace Diagnostics</label>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input is-small" name="trace_id" placeholder="select recent trace id or paste one" list="diagnostics-trace-options" required>
|
||||
</div>
|
||||
<p class="help is-size-7" title="Use this to reconstruct ingress -> persistence -> fanout path and jump to projection-shadow for linked sessions.">Use a trace id from the dropdown (recent traces), Event Ledger Smoke `sample[].trace_id`, or UR logs.</p>
|
||||
</div>
|
||||
<button class="button is-small is-link is-light" type="submit">Lookup Trace</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="column is-12-tablet is-3-desktop">
|
||||
<form id="memory-search-form">
|
||||
<label class="label is-size-7">Memory Search</label>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input is-small" name="q" placeholder="search memory text" required>
|
||||
</div>
|
||||
<p class="help is-size-7" title="Use this for fast retrieval over AI memory/wiki text; backend can be django or manticore.">Query memory index and inspect top matches.</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input is-small" name="statuses" placeholder="active" value="active">
|
||||
</div>
|
||||
</div>
|
||||
<button class="button is-small is-link is-light" type="submit">Query Memory</button>
|
||||
<button class="button is-small is-light" type="button" id="memory-search-status">Backend Status</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<datalist id="diagnostics-session-options">
|
||||
{% for row in diagnostics_options.sessions %}
|
||||
<option value="{{ row.label }}" data-session-id="{{ row.id }}"></option>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
<datalist id="diagnostics-trace-options">
|
||||
{% for trace_id in diagnostics_options.trace_ids %}
|
||||
<option value="{{ trace_id }}"></option>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
<datalist id="diagnostics-service-options">
|
||||
{% for service in diagnostics_options.services %}
|
||||
<option value="{{ service }}"></option>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
<datalist id="diagnostics-event-type-options">
|
||||
{% for event_type in diagnostics_options.event_types %}
|
||||
<option value="{{ event_type }}"></option>
|
||||
{% endfor %}
|
||||
</datalist>
|
||||
<div class="buttons are-small" style="margin-bottom: 0.5rem;">
|
||||
<button id="diagnostics-select-all" type="button" class="button is-light">Select All</button>
|
||||
<button id="diagnostics-copy" type="button" class="button is-light">Copy</button>
|
||||
</div>
|
||||
<pre id="diagnostics-output" class="is-size-7" style="max-height: 20rem; overflow:auto; background:#f7f7f7; padding:0.75rem; border-radius:8px;"></pre>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div class="column is-12">
|
||||
<article class="box">
|
||||
<h2 class="title is-6">Purge OSINT Setup Categories</h2>
|
||||
@@ -72,5 +179,144 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
<script>
|
||||
(function () {
|
||||
const out = document.getElementById("diagnostics-output");
|
||||
const shadowForm = document.getElementById("projection-shadow-form");
|
||||
const smokeForm = document.getElementById("event-ledger-smoke-form");
|
||||
const traceForm = document.getElementById("trace-diagnostics-form");
|
||||
const memoryForm = document.getElementById("memory-search-form");
|
||||
const memoryStatusBtn = document.getElementById("memory-search-status");
|
||||
const selectAllBtn = document.getElementById("diagnostics-select-all");
|
||||
const copyBtn = document.getElementById("diagnostics-copy");
|
||||
const sessionOptionMap = new Map();
|
||||
const sessionDatalist = document.getElementById("diagnostics-session-options");
|
||||
if (sessionDatalist) {
|
||||
sessionDatalist.querySelectorAll("option").forEach(function (opt) {
|
||||
const key = (opt.value || "").trim();
|
||||
const sessionId = (opt.dataset.sessionId || "").trim();
|
||||
if (key && sessionId) {
|
||||
sessionOptionMap.set(key, sessionId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function write(text) {
|
||||
if (out) {
|
||||
out.textContent = text;
|
||||
}
|
||||
}
|
||||
|
||||
function outputText() {
|
||||
return out ? (out.textContent || "") : "";
|
||||
}
|
||||
|
||||
function selectOutputText() {
|
||||
if (!out) return;
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(out);
|
||||
const selection = window.getSelection();
|
||||
if (!selection) return;
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
|
||||
async function copyOutputText() {
|
||||
const text = outputText();
|
||||
if (!text) return;
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
write(text + "\n\n[Copied]");
|
||||
return;
|
||||
} catch (err) {
|
||||
const area = document.createElement("textarea");
|
||||
area.value = text;
|
||||
area.style.position = "fixed";
|
||||
area.style.opacity = "0";
|
||||
document.body.appendChild(area);
|
||||
area.focus();
|
||||
area.select();
|
||||
try {
|
||||
document.execCommand("copy");
|
||||
write(text + "\n\n[Copied]");
|
||||
} finally {
|
||||
document.body.removeChild(area);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function runGet(url, params) {
|
||||
const query = new URLSearchParams(params);
|
||||
const response = await fetch(`${url}?${query.toString()}`, { headers: { "Accept": "application/json" } });
|
||||
const payload = await response.json();
|
||||
return { status: response.status, payload };
|
||||
}
|
||||
|
||||
shadowForm.addEventListener("submit", async function (ev) {
|
||||
ev.preventDefault();
|
||||
write("Running projection shadow...");
|
||||
const form = new FormData(shadowForm);
|
||||
const sessionLookup = (form.get("session_lookup") || "").toString().trim();
|
||||
const sessionId = sessionOptionMap.get(sessionLookup) || sessionLookup;
|
||||
const result = await runGet("{% url 'system_projection_shadow' %}", {
|
||||
session_id: sessionId,
|
||||
detail_limit: (form.get("detail_limit") || "25").toString().trim(),
|
||||
});
|
||||
write(JSON.stringify(result, null, 2));
|
||||
});
|
||||
|
||||
smokeForm.addEventListener("submit", async function (ev) {
|
||||
ev.preventDefault();
|
||||
write("Running event ledger smoke...");
|
||||
const form = new FormData(smokeForm);
|
||||
const result = await runGet("{% url 'system_event_ledger_smoke' %}", {
|
||||
minutes: (form.get("minutes") || "120").toString().trim(),
|
||||
service: (form.get("service") || "").toString().trim(),
|
||||
require_types: (form.get("require_types") || "").toString().trim(),
|
||||
});
|
||||
write(JSON.stringify(result, null, 2));
|
||||
});
|
||||
|
||||
traceForm.addEventListener("submit", async function (ev) {
|
||||
ev.preventDefault();
|
||||
write("Running trace diagnostics...");
|
||||
const form = new FormData(traceForm);
|
||||
const result = await runGet("{% url 'system_trace_diagnostics' %}", {
|
||||
trace_id: (form.get("trace_id") || "").toString().trim(),
|
||||
});
|
||||
write(JSON.stringify(result, null, 2));
|
||||
});
|
||||
|
||||
memoryForm.addEventListener("submit", async function (ev) {
|
||||
ev.preventDefault();
|
||||
write("Running memory search...");
|
||||
const form = new FormData(memoryForm);
|
||||
const result = await runGet("{% url 'system_memory_search_query' %}", {
|
||||
q: (form.get("q") || "").toString().trim(),
|
||||
statuses: (form.get("statuses") || "active").toString().trim(),
|
||||
limit: "20",
|
||||
});
|
||||
write(JSON.stringify(result, null, 2));
|
||||
});
|
||||
|
||||
if (memoryStatusBtn) {
|
||||
memoryStatusBtn.addEventListener("click", async function () {
|
||||
write("Checking memory search backend...");
|
||||
const result = await runGet("{% url 'system_memory_search_status' %}", {});
|
||||
write(JSON.stringify(result, null, 2));
|
||||
});
|
||||
}
|
||||
|
||||
if (selectAllBtn) {
|
||||
selectAllBtn.addEventListener("click", function () {
|
||||
selectOutputText();
|
||||
});
|
||||
}
|
||||
if (copyBtn) {
|
||||
copyBtn.addEventListener("click", function () {
|
||||
copyOutputText();
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user