Files
antigravity-skills-reference/docs/integrations/jetski-cortex.md
sickn33 bdcfbb9625 feat(hugging-face): Add official ecosystem skills
Import the official Hugging Face ecosystem skills and sync the\nexisting local coverage with upstream metadata and assets.\n\nRegenerate the canonical catalog, plugin mirrors, docs, and release\nnotes after the maintainer merge batch so main stays in sync.\n\nFixes #417
2026-03-29 18:31:46 +02:00

8.5 KiB
Raw Blame History

title, description
title description
Jetski/Cortex + Gemini Integration Guide Come usare antigravity-awesome-skills con Jetski/Cortex evitando loverflow di contesto con 1.340+ skill.

Jetski/Cortex + Gemini: integrazione sicura con 1.340+ 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.340 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:

{
  "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/.

4.1. Tipi di base

type SkillMeta = {
  id: string;
  path: string;
  name: string;
  description?: string;
  category?: string;
  risk?: string;
};

4.2. Bootstrap: caricare il manifest

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

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

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:

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 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:

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.

  • 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.