Files
antigravity-skills-reference/docs/integrations/jetski-cortex.md
2026-03-21 11:00:03 +00:00

273 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Jetski/Cortex + Gemini Integration Guide
description: "Come usare antigravity-awesome-skills con Jetski/Cortex evitando loverflow di contesto con 1.306+ skill."
---
# Jetski/Cortex + Gemini: integrazione sicura con 1.306+ skill
Questa guida mostra come integrare il repository `antigravity-awesome-skills` con un agente basato su **Jetski/Cortex + Gemini** (o framework simili) **senza superare il context window** del modello.
Lerrore tipico visto in Jetski/Cortex è:
> `TrajectoryChatConverter: could not convert a single message before hitting truncation`
Il problema non è nelle skill, ma **nel modo in cui vengono caricate**.
---
## 1. Antipattern da evitare
Non bisogna mai:
- leggere **tutte** le directory `skills/*/SKILL.md` allavvio;
- concatenare il contenuto di tutte le `SKILL.md` in un singolo system prompt;
- reiniettare lintera libreria per **ogni** richiesta.
Con oltre 1.306 skill, questo approccio riempie il context window prima ancora di aggiungere i messaggi dellutente, causando lerrore di truncation.
---
## 2. Pattern raccomandato
Principi chiave:
- **Manifest leggero**: usare `data/skills_index.json` per sapere *quali* skill esistono, senza caricare i testi completi.
- **Lazy loading**: leggere `SKILL.md` **solo** per le skill effettivamente invocate in una conversazione (es. quando compare `@skill-id`).
- **Limiti espliciti**: imporre un massimo di skill/tokens caricati per turno, con fallback chiari.
- **Path safety**: verificare che i path del manifest restino dentro `SKILLS_ROOT` prima di leggere `SKILL.md`.
Il flusso consigliato è:
1. **Bootstrap**: allavvio dellagente leggere `data/skills_index.json` e costruire una mappa `id -> meta`.
2. **Parsing dei messaggi**: prima di chiamare il modello, estrarre tutti i riferimenti `@skill-id` dai messaggi utente/sistema.
3. **Risoluzione**: mappare gli id trovati in oggetti `SkillMeta` usando la mappa di bootstrap.
4. **Lazy load**: leggere i file `SKILL.md` solo per questi id (fino a un massimo configurabile).
5. **Prompt building**: costruire i system messages del modello includendo solo le definizioni delle skill selezionate.
---
## 3. Struttura di `skills_index.json`
Il file `data/skills_index.json` è un array di oggetti, ad esempio:
```json
{
"id": "brainstorming",
"path": "skills/brainstorming",
"category": "planning",
"name": "brainstorming",
"description": "Use before any creative or constructive work.",
"risk": "safe",
"source": "official",
"date_added": "2026-02-27"
}
```
Campi chiave:
- **`id`**: identificatore usato nelle menzioni `@id` (es. `@brainstorming`).
- **`path`**: directory che contiene la `SKILL.md` (es. `skills/brainstorming/`).
Per ottenere il percorso alla definizione della skill:
- `fullPath = path.join(SKILLS_ROOT, meta.path, "SKILL.md")`.
> Nota: `SKILLS_ROOT` è la directory radice dove avete installato il repository (es. `~/.agent/skills`).
---
## 4. Pseudocodice di integrazione (TypeScript)
> Esempio completo in: [`docs/integrations/jetski-gemini-loader/`](../../docs/integrations/jetski-gemini-loader/).
### 4.1. Tipi di base
```ts
type SkillMeta = {
id: string;
path: string;
name: string;
description?: string;
category?: string;
risk?: string;
};
```
### 4.2. Bootstrap: caricare il manifest
```ts
function loadSkillIndex(indexPath: string): Map<string, SkillMeta> {
const raw = fs.readFileSync(indexPath, "utf8");
const arr = JSON.parse(raw) as SkillMeta[];
const map = new Map<string, SkillMeta>();
for (const meta of arr) {
map.set(meta.id, meta);
}
return map;
}
```
### 4.3. Parsing dei messaggi per trovare `@skill-id`
```ts
const SKILL_ID_REGEX = /@([a-zA-Z0-9-_./]+)/g;
function resolveSkillsFromMessages(
messages: { role: string; content: string }[],
index: Map<string, SkillMeta>,
maxSkills: number
): SkillMeta[] {
const found = new Set<string>();
for (const msg of messages) {
let match: RegExpExecArray | null;
while ((match = SKILL_ID_REGEX.exec(msg.content)) !== null) {
const id = match[1];
if (index.has(id)) {
found.add(id);
}
}
}
const metas: SkillMeta[] = [];
for (const id of found) {
const meta = index.get(id);
if (meta) metas.push(meta);
if (metas.length >= maxSkills) break;
}
return metas;
}
```
### 4.4. Lazy loading dei file `SKILL.md`
```ts
async function loadSkillBodies(
skillsRoot: string,
metas: SkillMeta[]
): Promise<string[]> {
const bodies: string[] = [];
for (const meta of metas) {
const fullPath = path.join(skillsRoot, meta.path, "SKILL.md");
const text = await fs.promises.readFile(fullPath, "utf8");
bodies.push(text);
}
return bodies;
}
```
### 4.5. Costruzione del prompt Jetski/Cortex
Pseudocodice per la fase di preprocessing, prima del `TrajectoryChatConverter`:
```ts
async function buildModelMessages(
baseSystemMessages: { role: "system"; content: string }[],
trajectory: { role: "user" | "assistant" | "system"; content: string }[],
skillIndex: Map<string, SkillMeta>,
skillsRoot: string,
maxSkillsPerTurn: number,
overflowBehavior: "truncate" | "error" = "truncate"
): Promise<{ role: string; content: string }[]> {
const referencedSkills = resolveSkillsFromMessages(
trajectory,
skillIndex,
Number.MAX_SAFE_INTEGER
);
if (
overflowBehavior === "error" &&
referencedSkills.length > maxSkillsPerTurn
) {
throw new Error(
`Too many skills requested in a single turn. Reduce @skill-id usage to ${maxSkillsPerTurn} or fewer.`
);
}
const selectedMetas = resolveSkillsFromMessages(
trajectory,
skillIndex,
maxSkillsPerTurn
);
const skillBodies = await loadSkillBodies(skillsRoot, selectedMetas);
const skillMessages = skillBodies.map((body) => ({
role: "system" as const,
content: body,
}));
return [...baseSystemMessages, ...skillMessages, ...trajectory];
}
```
> Suggerimento: aggiungete una stima dei token per troncare o riassumere i `SKILL.md` se il context window si avvicina al limite.
> Il reference loader di questo repo supporta anche un fallback esplicito: `overflowBehavior: "error"`.
---
## 5. Gestione degli overflow di contesto
Per evitare errori difficili da capire per lutente, impostate:
- una **soglia di sicurezza** (es. 7080% del context window);
- un **limite massimo di skill per turno** (es. 510).
Strategie quando si supera la soglia:
- ridurre il numero di skill incluse (es. in base a recenza o priorità); oppure
- restituire un errore chiaro allutente, ad esempio:
> "Sono state richieste troppe skill in un singolo turno. Riduci il numero di `@skill-id` nel messaggio o dividili in più passaggi."
---
## 6. Scenari di test raccomandati
- **Scenario 1 Messaggio semplice ("hi")**
- Nessun `@skill-id` → nessuna `SKILL.md` caricata → il prompt rimane piccolo → nessun errore.
- **Scenario 2 Poche skill**
- Messaggio con 12 `@skill-id` → solo le relative `SKILL.md` vengono caricate → nessun overflow.
- **Scenario 3 Molte skill**
- Messaggio con molte `@skill-id` → si attiva il limite `maxSkillsPerTurn` o il controllo di token → nessun overflow silenzioso.
---
## 7. Sottoinsiemi di skill e bundle
Per ulteriore controllo:
- spostate le skill non necessarie in `skills/.disabled/` per escluderle in certi ambienti;
- usate i **bundle** descritti in [`docs/users/bundles.md`](../users/bundles.md) per caricare solo gruppi tematici.
## 8. Recovery su Windows se siete gia in crash loop
Se lhost continua a riaprire la stessa trajectory corrotta dopo un errore di truncation:
- rimuovete la skill o il pacchetto problematico;
- cancellate Local Storage / Session Storage / IndexedDB usati da Antigravity;
- svuotate `%TEMP%`;
- riavviate con un loader lazy e limiti espliciti.
Guida completa:
- [`docs/users/windows-truncation-recovery.md`](../users/windows-truncation-recovery.md)
Per evitare che il problema si ripresenti:
- mantenete `overflowBehavior: "error"` quando preferite un fallimento esplicito;
- continuate a validare che i path risolti restino dentro `skillsRoot`.
---
## 9. Riepilogo
- Non concatenate mai tutte le `SKILL.md` in un singolo prompt.
- Usate `data/skills_index.json` come manifest leggero.
- Caricate le skill **ondemand** in base a `@skill-id`.
- Impostate limiti chiari (max skill per turno, soglia di token).
Seguendo questo pattern, Jetski/Cortex + Gemini può usare lintera libreria di `antigravity-awesome-skills` in modo sicuro, scalabile e compatibile con il context window dei modelli moderni.