SSkilltecabyclaudinhocode
Enviar skill
← Voltar para o catálogo

meme-library

Dados e Análise

A hierarchical, vision-tagged personal meme/sticker library. Use this skill to add new memes (single image or whole collections) and to retrieve a contextually-appropriate meme to send back. The library uses progressive disclosure — a lightweight root index decides which collection to drill into, then per-collection metadata holds the per-image semantics. Trigger when the user asks to ingest a mem

2estrelas
Ver no GitHub ↗Autor: yr-96Licença: MIT

Meme Library

A channel-agnostic library for managing and retrieving memes/stickers. This skill does not send anything — it stores, tags, indexes, and selects. Wire it into your own delivery skill (WeChat, Telegram, Slack, Discord, CLI, …) by consuming the path it returns.

Library Layout

$MEME_LIB_PATH/                  (default: ~/.meme-library/)
├── index.json                   # root index — ALWAYS read this first
├── <collection_a>/              # one folder per IP / character / theme
│   ├── meta.json               # per-image semantics for this collection
│   ├── img_001.jpg
│   └── ...
├── <collection_b>/
│   ├── meta.json
│   └── ...

Progressive disclosure principle: index.json is small and always loaded. Per-collection meta.json is loaded only when that collection is selected. This keeps context small as the library grows.

index.json schema

{
  "version": "1.0",
  "collections": {
    "<collection_id>": {
      "path": "<collection_id>/",
      "name": "Human-readable name",
      "count": 12,
      "vibe": "One-sentence summary of this collection's overall personality",
      "best_for": ["situation 1", "situation 2", "..."],
      "avoid_when": ["situation that this collection clashes with", "..."]
    }
  }
}

meta.json schema (per collection)

{
  "<filename.ext>": {
    "path": "<absolute path>",
    "description": "What is in the image, visually",
    "tags": ["tag1", "tag2", "..."],
    "occasion": "Free-text description of the situation this meme fits"
  }
}

See references/schema.md for the full spec.


Workflows

Workflow 1 — Add a single meme

Trigger: user shares one image and says "save this to <collection>" / "add to my memes".

  1. Run python scripts/add_meme.py --image <path> --collection <id> (creates the collection if missing).
  2. The script will: vision-analyze the image → propose a semantic filename → copy the file → update <collection>/meta.json.
  3. Confirm to user: filename, tags, occasion.
  4. After adding ≥3 new memes to a collection, run Workflow 5 to regenerate the collection's vibe/best_for/avoid_when, since the personality may have shifted. (add_meme.py deliberately does not refresh the fingerprint on every call — it would double the API cost per add.)

Workflow 2 — Add a whole new collection

Trigger: user shares a folder/zip of images and says "build a new sticker pack called X".

  1. Unzip if needed to a temp dir.
  2. Run python scripts/add_collection.py --source <dir> --collection <id> --name "<display name>".
  3. The script processes images one at a time (vision tools must NOT be called in parallel) → writes each into <collection>/meta.json → at the end, summarizes all descriptions into the collection's vibe/best_for/avoid_when and writes the entry to index.json.
  4. Confirm to user: count added, collection vibe.

Workflow 3 — Retrieve a meme that fits the current context

Trigger: an upstream agent/skill needs a meme for the current conversation.

Preferred flow (LLM-native, used when this skill is being driven by a language model):

  1. Read $MEME_LIB_PATH/index.json.
  2. Score each collection against the conversation context using vibe + best_for + avoid_when. Pick the top 1–2 collections (or zero if none fit — see "When to skip").
  3. Read meta.json for the selected collection(s).
  4. Pick the single meme whose occasion + tags best match the context. Strongly prefer specificity over generic catch-alls.
  5. Return the absolute path (and metadata) to the caller. Never invent or guess paths — only return paths that exist in the loaded JSON.

Fallback flow (programmatic, for non-LLM consumers):

python scripts/search.py --context "用户气死了" --top-k 1

Outputs JSON with the matched meme path and metadata, using keyword-overlap scoring across collections.

Workflow 4 — Maintenance

python scripts/health_check.py

Reports: orphan files (image present but no DB entry), missing files (DB entry but no image), index/meta count drift, and collections whose vibe summary is stale (no fingerprint at all, or count has drifted ≥3 since the last regeneration — see vibe_count in the index entry).

Workflow 5 — Regenerate a collection's vibe fingerprint

Trigger: health_check reports stale_vibe, the user says "the vibe of X is off", or you've added several new memes to a collection one at a time.

# Refresh one collection
python scripts/regen_vibe.py --collection <id>

# Refresh every collection that health_check considers stale
python scripts/regen_vibe.py --stale-only

# Nuke and rebuild every fingerprint in the library
python scripts/regen_vibe.py --all

The script reads every meme's description/tags/occasion in the target collection, calls the vision provider's summarise_collection once, writes the resulting vibe / best_for / avoid_when to index.json, and snapshots the current count into vibe_count so the next health check has an accurate baseline.


Behavior Rules (for the agent driving this skill)

These are the principles that make a library useful in practice, regardless of how the meme is eventually delivered:

  1. Don't be random. The library has rich occasion text — actually read it. Random selection produces tone-deaf sends.
  2. Specificity over breadth. A meme whose occasion is "对方迟迟不回消息时催促" beats a generic "震惊" meme when the user is being ghosted.
  3. Skip is a valid answer. If no meme scores a clear match, return nothing. Better to send no meme than a wrong one.
  4. One per turn. A retrieval call returns at most one meme.
  5. Don't repeat. If the caller passes a --exclude list of recently-sent paths, never return one in that list.
  6. Respect opt-out signals. If the upstream context mentions the user has asked to stop sending memes, return nothing and surface that to the caller.

When to skip

Return zero results when:

  • Topic is serious / technical / business-critical
  • The conversation tone is somber and no comforting collection exists in the library
  • All candidate memes score below a clear-match threshold
  • The user has opted out

Vision Provider

Configurable via env var MEME_VISION_PROVIDER:

ValueRequires
claude (default)ANTHROPIC_API_KEY
openaiOPENAI_API_KEY
geminiGEMINI_API_KEY

To plug in a custom provider, see scripts/lib/vision.py — implement the VisionProvider protocol.

Pitfalls

  • Never call vision tools in parallel. Most providers throttle or fail under burst load. Always loop sequentially.
  • All mutations must go through scripts/lib/store.py. The public helpers (ensure_collection, add_meme, remove_meme, update_collection_fingerprint) acquire a coarse-grained flock and write atomically via tempfile + os.replace — bypassing them risks half-written JSON or lost concurrent updates.
  • Filenames are semantic, not original. Always rename incoming images to <role>_<emotion>_<seq>.<ext> (or similar) on intake. IMG_2401.JPEG is useless to future-you. add_meme.py does this for you via the vision provider's filename_suggestion.
  • Vibe drifts. A collection's personality changes as it grows. Re-summarize after every ~3 additions or whenever the user manually requests it (see Workflow 5).
  • The path field in meta.json is recomputed on read. load_meta always rebuilds it from lib_root + collection + filename, so the library survives being moved across machines or relocated to a new $MEME_LIB_PATH. Don't rely on the on-disk value being current.
  • Use $MEME_LIB_PATH for portability. Don't hard-code paths in skills that consume meme-library; read the env var (default ~/.meme-library/).

Como adicionar

/plugin marketplace add yr-96/meme-library

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Comentários · Nenhum comentário

Entre para comentar. Entrar

  • Ainda não há comentários. Seja o primeiro.