feat(recorder): aggiunti tool di registrazione e analisi attivita BiDi (JSONL)
This commit is contained in:
@@ -720,6 +720,159 @@ export default function (pi: ExtensionAPI) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Registrazione e analisi attività di navigazione (Activity Recorder JSONL)
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
pi.registerTool({
|
||||||
|
name: "browser_record_start",
|
||||||
|
label: "Browser Record Start",
|
||||||
|
description:
|
||||||
|
"Avvia o riconfigura la registrazione continua degli eventi e delle attività di navigazione " +
|
||||||
|
"(URL, domini, navigazioni, caricamento DOM, errori e log di console) su un file JSONL.",
|
||||||
|
parameters: Type.Object({
|
||||||
|
path: Type.Optional(
|
||||||
|
Type.String({
|
||||||
|
description:
|
||||||
|
"Percorso assoluto del file JSONL (default: ~/.local/state/pi-firefox-bidi/activity.jsonl)",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
events: Type.Optional(
|
||||||
|
Type.Array(Type.String(), {
|
||||||
|
description: "Lista di eventi BiDi da registrare (opzionale)",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
async execute(_id, params) {
|
||||||
|
await ensureBridge();
|
||||||
|
const r = await bridge("/recorder/start", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(params),
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Registrazione attività attiva su file: ${r.file}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
details: r,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
pi.registerTool({
|
||||||
|
name: "browser_record_stop",
|
||||||
|
label: "Browser Record Stop",
|
||||||
|
description: "Sospende la registrazione delle attività di navigazione su file.",
|
||||||
|
parameters: Type.Object({}),
|
||||||
|
async execute() {
|
||||||
|
await ensureBridge();
|
||||||
|
const r = await bridge("/recorder/stop", { method: "POST" });
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Registrazione attività sospesa. Eventi totali registrati: ${r.totalEvents} (${r.file})`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
details: r,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
pi.registerTool({
|
||||||
|
name: "browser_record_status",
|
||||||
|
label: "Browser Record Status",
|
||||||
|
description: "Mostra lo stato del registratore attività, il percorso del file JSONL e il numero di eventi.",
|
||||||
|
parameters: Type.Object({}),
|
||||||
|
async execute() {
|
||||||
|
await ensureBridge();
|
||||||
|
const r = await bridge("/recorder/status");
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: JSON.stringify(r, null, 2) }],
|
||||||
|
details: r,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
pi.registerTool({
|
||||||
|
name: "browser_record_get",
|
||||||
|
label: "Browser Record Get",
|
||||||
|
description:
|
||||||
|
"Recupera le attività di navigazione registrate dal file JSONL per analisi (formato compatto o JSON grezzo).",
|
||||||
|
parameters: Type.Object({
|
||||||
|
limit: Type.Optional(
|
||||||
|
Type.Number({ description: "Numero massimo di eventi recenti da recuperare (default 30)", default: 30 }),
|
||||||
|
),
|
||||||
|
format: Type.Optional(
|
||||||
|
Type.Enum(
|
||||||
|
{ summary: "summary", json: "json" },
|
||||||
|
{ description: "Formato: 'summary' (timeline compatta) o 'json' (oggetti completi)", default: "summary" },
|
||||||
|
),
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
async execute(_id, params) {
|
||||||
|
await ensureBridge();
|
||||||
|
const r = await bridge("/recorder/get", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({ limit: params.limit ?? 30 }),
|
||||||
|
});
|
||||||
|
const records: any[] = r.records ?? [];
|
||||||
|
if (params.format === "json") {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: JSON.stringify(r, null, 2) }],
|
||||||
|
details: r,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (records.length === 0) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Nessuna attività registrata nel log (${r.file}).` }],
|
||||||
|
details: r,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const lines = records.map((rec) => {
|
||||||
|
const timeStr = rec.timestamp ? rec.timestamp.split("T")[1]?.slice(0, 8) : "--:--:--";
|
||||||
|
if (rec.event === "navigation_started") {
|
||||||
|
return `[${timeStr}] 🌐 Navigazione: ${rec.url} (dominio: ${rec.domain ?? "-"})`;
|
||||||
|
} else if (rec.event === "page_loaded") {
|
||||||
|
return `[${timeStr}] ⏱ Caricato: ${rec.url ?? ""} in ${rec.durationMs ?? "?"}ms`;
|
||||||
|
} else if (rec.event === "dom_ready") {
|
||||||
|
return `[${timeStr}] 📄 DOM Ready: ${rec.url ?? ""}`;
|
||||||
|
} else if (rec.event === "console_log") {
|
||||||
|
return `[${timeStr}] 💬 [Console ${rec.level ?? "log"}]: ${rec.text ?? ""}`;
|
||||||
|
}
|
||||||
|
return `[${timeStr}] ⚡ ${rec.event}: ${rec.url ?? JSON.stringify(rec)}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Ultime ${records.length} attività registrate (${r.file}):\n\n` + lines.join("\n"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
details: r,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
pi.registerTool({
|
||||||
|
name: "browser_record_clear",
|
||||||
|
label: "Browser Record Clear",
|
||||||
|
description: "Svuota il file di log delle attività e azzera il contatore.",
|
||||||
|
parameters: Type.Object({}),
|
||||||
|
async execute() {
|
||||||
|
await ensureBridge();
|
||||||
|
const r = await bridge("/recorder/clear", { method: "POST" });
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: "Log attività svuotato con successo." }],
|
||||||
|
details: r,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Notifica asincrona (agy/bridge → pi): webhook locale
|
// Notifica asincrona (agy/bridge → pi): webhook locale
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user