feat: discovery endpoint GET /v1/meta/overview + tool qmem_meta

- gateway v2.3.0: /v1/meta/overview (auth) con scope×kind, progetti, agenti, superseduti; scroll aggregato su soli campi metadata + cache TTL 60s invalidata su POST/DELETE/cleanup; audit action 'meta'
- estensione v1.3.0: tool qmem_meta (nessun parametro) che guida la ricerca settorializzata
- README/playbook (sez. 11.4)/AGENTS.md aggiornati
This commit is contained in:
enne2
2026-08-13 13:06:10 +02:00
parent f6d9c5872d
commit 4b1f13c118
5 changed files with 124 additions and 2 deletions
+46
View File
@@ -393,6 +393,52 @@ export default function qmemExtension(pi: ExtensionAPI) {
},
});
// =========================================================================
// TOOL: qmem_meta — discovery di scope, kind, progetti, agenti
// =========================================================================
pi.registerTool({
name: "qmem_meta",
label: "Qmem memory overview",
description:
"Restituisce la panoramica della memoria condivisa: scope con i relativi kind e conteggi, " +
"progetti, agenti e record superseduti. Usalo per decidere DOVE cercare (filtri " +
"scope/kind/project_id) prima di qmem_search su un dominio specifico, o per orientarti " +
"sui contenuti disponibili. Nessun parametro richiesto.",
parameters: Type.Object({}),
async execute(toolCallId, params, signal, onUpdate, ctx) {
const cfg = loadConfig();
if (!cfg.apiKey) {
return {
content: [{ type: "text", text: "Config mancante: esegui /qmem:config per impostare url e apiKey." }],
details: { error: "missing_config" },
};
}
onUpdate?.({ content: [{ type: "text", text: "qmem: lettura overview..." }] });
const { ok, status, data } = await gatewayRequest(cfg, "GET", "/v1/meta/overview", undefined, signal);
if (!ok) {
return {
content: [{ type: "text", text: `Errore ${status}: ${JSON.stringify(data)}` }],
details: { error: "gateway_error", status },
};
}
const lines: string[] = [];
lines.push(`Memoria condivisa: ${data.total} record (${data.superseded} superseduti${data.cached ? ", da cache" : ""})`);
lines.push("Scope:");
for (const s of data.scopes ?? []) {
const kinds = (s.kinds ?? []).map((k: any) => `${k.kind}=${k.count}`).join(", ");
lines.push(` ${s.scope} (${s.count}): ${kinds}`);
}
lines.push("Progetti:");
lines.push(` ${(data.projects ?? []).map((p: any) => `${p.project_id}(${p.count})`).join(", ") || "nessuno"}`);
lines.push("Agenti:");
lines.push(` ${(data.agents ?? []).map((a: any) => `${a.agent_id}(${a.count})`).join(", ") || "nessuno"}`);
return {
content: [{ type: "text", text: lines.join("\n") }],
details: { total: data.total, superseded: data.superseded },
};
},
});
// =========================================================================
// COMANDO: /qmem:config — menu interattivo + modalità CLI rapida
// =========================================================================