feat(prompt): regola vincolante identificazione macchina nei record qmem (hostname auto-rilevato, layout modulare) + bump v1.8.0

This commit is contained in:
enne2
2026-08-24 22:55:51 +02:00
parent 4776b4b496
commit 5a5081e5d9
7 changed files with 46 additions and 5 deletions
+2 -2
View File
@@ -47,10 +47,10 @@ Config salvata in `~/.config/pi-qmem/config.json` (0600):
## Regole comportamentali (autocontenute)
Le regole vincolanti (obbligo `project_id`, punteggi, correzione/supersede, discovery) sono **distribuite con l'estensione**, senza toccare AGENTS.md:
Le regole vincolanti (obbligo `project_id`, punteggi, correzione/supersede, discovery, **identificazione macchina nei record locali**) sono **distribuite con l'estensione**, senza toccare AGENTS.md:
- **`promptGuidelines`** sui 4 tool (bullets nel `Guidelines` del system prompt, solo quando i tool sono attivi)
- **`before_agent_start`** → blocco "Regole pi-qmem" iniettato nel system prompt a ogni turno (solo se i tool qmem sono attivi)
- **`before_agent_start`** → blocco "Regole pi-qmem" iniettato nel system prompt a ogni turno (solo se i tool qmem sono attivi); include la sezione **Identificazione macchina** con `MACCHINA CORRENTE` rilevata dinamicamente dall'estensione (`os.hostname()` + `/etc/os-release`)
- **Skill `qmem`** (`skills/qmem/SKILL.md`, standard agentskills.io) → procedura completa on-demand, caricabile con `/skill:qmem`
- Manifest: `pi.skills` nel package.json
+11
View File
@@ -1,4 +1,5 @@
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { MACHINE } from "./shared";
export function registerQmemRules(pi: ExtensionAPI) {
const QMEM_RULES = `
@@ -19,6 +20,16 @@ QUANDO un tool fallisce o un'operazione si blocca:
2. se trovata una soluzione documentata → applicala e cita l'ID del record
3. se assente → troubleshooting normale, poi qmem_store della soluzione trovata
### Identificazione macchina nei record (vincolante)
- MACCHINA CORRENTE (rilevata automaticamente dall'estensione): ${MACHINE}
MUST:
- MUST: in qmem_store/qmem_correct che descrivono percorsi, porte, servizi, configurazioni, comandi o risultati LOCALI, includere nel testo il prefisso 'MACCHINA: <hostname> (<OS>, <GPU/hardware rilevanti>)' (es. 'MACCHINA: frigate (Fedora Linux 44, Tesla V100-16GB)').
- MUST: per dettagli strettamente legati a una singola macchina usare il project 'host-<hostname>' (es. host-frigate); se si usa un project funzionale (es. llama-cpp), marcare comunque l'hostname nel testo.
- Verifica SEMPRE l'identità della macchina con 'hostname'/'hostnamectl' PRIMA di salvare (mai dedurla da indizi indiretti).
MUST NOT:
- MUST NOT salvare record locali senza hostname se rischiano di essere applicati su altre macchine.
- Per procedure replicabili altrove: dichiara la macchina di origine e le differenze note (GPU, driver, path).
### Gestione Gerarchica e Navigazione ad Albero
- Per domini complessi/vasti: crea nodi specialistici (level=L2_SUBTOPIC, topic=MACRO/SUB, parent_id=...) e collegali a un nodo indice (level=L1_ROOT, topic=MACRO/ROOT, links=[...]).
- Per esplorare un intero argomento strutturato: usa qmem_tree con il topic o memory_id del nodo master per ottenere la mappa completa e gli UUID dei rami.
+18
View File
@@ -65,6 +65,24 @@ export function saveConfig(cfg: MemoryConfig) {
}
}
// ---------------------------------------------------------------------------
// Identità della macchina: rilevata dinamicamente e iniettata nelle regole.
// Ogni installazione si auto-descrive (hostname + OS + arch) senza configurazione.
// ---------------------------------------------------------------------------
export function detectMachine(): string {
const hostname = os.hostname();
let osName = "OS sconosciuto";
try {
const m = fs.readFileSync("/etc/os-release", "utf8").match(/^PRETTY_NAME="?([^"\n]+)"?/m);
if (m) osName = m[1];
} catch {
/* os-release non leggibile: resta il default */
}
return `${hostname} (${osName}, ${os.arch()})`;
}
export const MACHINE = detectMachine();
export async function gatewayRequest(
cfg: MemoryConfig,
method: string,
+2 -1
View File
@@ -1,6 +1,6 @@
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
import { gatewayRequest, loadConfig } from "../shared";
import { gatewayRequest, loadConfig, MACHINE } from "../shared";
export function registerQmemCorrect(pi: ExtensionAPI) {
pi.registerTool({
@@ -17,6 +17,7 @@ export function registerQmemCorrect(pi: ExtensionAPI) {
promptGuidelines: [
"qmem_correct: correggi solo con evidenza verificata (fonte autorevole, conferma utente, esito di azione) — mai per semplice dubbio o opinione.",
"qmem_correct: il vecchio record resta in archivio marcato superseded — mai eliminare (tranne duplicati esatti).",
`qmem_correct: se il record corretto riguarda una macchina, dichiara nel testo la MACCHINA di riferimento (prefisso 'MACCHINA: <hostname> (<OS>, <GPU>)'). Macchina corrente (rilevata dall'estensione): ${MACHINE}.`,
],
parameters: Type.Object({
memory_id: Type.Optional(Type.String({ description: "UUID del record attivo da supersedere (dalla risposta di qmem_search)." })),
+2 -1
View File
@@ -1,6 +1,6 @@
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
import { gatewayRequest, loadConfig } from "../shared";
import { gatewayRequest, loadConfig, MACHINE } from "../shared";
export function registerQmemStore(pi: ExtensionAPI) {
pi.registerTool({
@@ -16,6 +16,7 @@ export function registerQmemStore(pi: ExtensionAPI) {
promptGuidelines: [
"qmem_store: project_id è OBBLIGATORIO — consulta qmem_meta per riusare l'id esistente (fallback pi-qmem per conoscenza trasversale, mai vuoto).",
"qmem_store: salva record compatti e ad alto segnale, mai transcript grezzi.",
`qmem_store: per record macchina-specifici (percorsi, porte, servizi, config locali) includi nel testo il prefisso 'MACCHINA: <hostname> (<OS>, <GPU>)' e usa project host-<hostname> per dettagli strettamente locali. Macchina corrente (rilevata dall'estensione): ${MACHINE}.`,
],
parameters: Type.Object({
text: Type.String({ description: "Il contenuto del record di memoria (compatto, ad alto segnale)." }),
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "pi-qmem",
"version": "1.7.1",
"version": "1.8.0",
"description": "Memoria centralizzata e condivisa per agenti AI: salva e cerca record semantici (Qdrant + BGE-M3) via Memory Gateway.",
"keywords": ["pi-package", "memory", "agent", "qdrant", "rag"],
"license": "MIT",
+10
View File
@@ -51,6 +51,16 @@ Ogni memoria salvata DEVE avere un `project_id` idoneo (kebab-case, nome del pro
Record senza project_id sono invisibili alla ricerca settorializzata e al censimento di `qmem_meta`.
## Identificazione macchina nei record (vincolante)
Percorsi, porte, servizi, configurazioni, comandi o risultati LOCALI devono sempre indicare la macchina di riferimento:
1. Verifica l'identità con `hostname`/`hostnamectl` (mai dedurla da indizi indiretti).
2. Includi nel testo il prefisso `MACCHINA: <hostname> (<OS>, <GPU/hardware rilevanti>)` — es. `MACCHINA: frigate (Fedora Linux 44, Tesla V100-16GB)`.
3. Dettagli strettamente locali → project `host-<hostname>` (es. `host-frigate`); con project funzionale (es. `llama-cpp`) marca comunque l'hostname nel testo.
4. Procedure replicabili altrove: dichiara la macchina di origine e le differenze note (GPU, driver, path).
5. L'estensione rileva automaticamente la macchina corrente (`os.hostname()` + `/etc/os-release`) e la inietta nelle regole: è il riferimento per la sessione, ma verifica comunque prima di salvare.
## Correzione di memorie false (supersede)
Correggere è obbligatorio quando l'evidenza è verificata: contraddizione con fonte autorevole, conferma diretta dell'utente, esito di un'azione che smentisce il record.