- gateway: separate config, models, state, audit, guardrail, embeddings, store, metrics, cleanup and routes; keep main.py as FastAPI bootstrap - extension: split client/config, six tools, config command and rules; preserve jiti entrypoint and registrations - Dockerfile copies the complete gateway module set - tests: update monkeypatch boundaries for modular config/state
51 lines
2.2 KiB
TypeScript
51 lines
2.2 KiB
TypeScript
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
import { Type } from "typebox";
|
|
import { gatewayRequest, loadConfig } from "../shared";
|
|
|
|
export function registerQmemMeta(pi: ExtensionAPI) {
|
|
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.",
|
|
promptGuidelines: ["qmem_meta: consultalo per censire i progetti esistenti e scegliere i filtri di ricerca (scope/kind/project_id)."],
|
|
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 },
|
|
};
|
|
},
|
|
});
|
|
|
|
}
|