Felo SuperAgent Skill

SkillMedia

Generates product photos, logos, and branding images through an ongoing AI chat.

Available today. Use it from your connected AI after setup.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use the Felo SuperAgent Skill skill

About this skill

Felo SuperAgent API: AI conversation with real-time SSE streaming on a persistent LiveDoc canvas. Use when users want SuperAgent chat, continuous conversation, logo/branding design, or e-commerce product images. CRITICAL: When user provides ANY image/product description (e.g. '生成一張...產品照片', '我的提示詞為:

What this skill tells your AI

The instructions your AI receives, as published by duotify/githubclawtoolkit in skills/felo-superAgent/SKILL.md and read by ahel’s review.

Constraints (MUST READ FIRST)

These rules are mandatory. Violating any of them will produce incorrect behavior.

  1. NEVER treat image/product descriptions as prompt-writing or prompt-optimization tasks. If the user's message contains a visual description — regardless of phrasing such as "我的提示詞為", "my prompt is", "生成一張", "generate a photo of", "create a product image" — you MUST call the felo-superAgent API immediately to generate the actual image. Do NOT:

    • Rewrite, refine, or "improve" the description as a text output
    • Suggest keywords or aspect ratios as your final response
    • Write a better prompt to result.md instead of calling the API
    • Describe what you would do instead of doing it

    The ONLY correct response to an image/product generation request is to execute the skill (run run_superagent.mjs with --skill-id ecommerce-product-image or logo-and-branding) and output the resulting image URLs. If you find yourself writing text about the image instead of calling the API, stop and call the API.

  2. ALWAYS use --json flag. The script MUST run in JSON mode (--json). In Claude Code's Bash tool, stdout is always captured — it never streams directly to the user. JSON mode returns the full answer in a structured response that Claude can then output as text. State IDs are extracted from the JSON response fields thread_short_id and live_doc_short_id.

  3. ALWAYS output the answer and all tool results. After the script finishes: (a) print data.answer verbatim as your response text — do NOT summarize or paraphrase; (b) render every entry in data.image_urls as a Markdown inline image ![title](url) immediately after the answer — NEVER skip image URLs; (c) list any entries in data.discoveries, data.documents, data.ppts, data.htmls.

  4. --live-doc-id is optional for the first call. run_superagent.mjs works without --live-doc-id — the API will auto-assign a LiveDoc and return its live_doc_short_id in the JSON response. On the FIRST call in a session (no live_doc_id known yet), you MAY omit --live-doc-id. After the first call, always reuse the returned live_doc_short_id (see Constraint #4 and Step 2).

  5. Reuse live_doc_id from ANY source. If you already have a live_doc_id from any previous operation in this session — whether from a prior SuperAgent call's JSON response (data.live_doc_short_id), user-provided input, or any other skill — use it directly. Do NOT try to fetch LiveDoc list via felo-livedoc (it may not be installed). Only omit --live-doc-id when you truly have no ID from any source. (Note: live_doc_id corresponds to the API field live_doc_short_id and the [state] output key live_doc_short_id.)

  6. One LiveDoc per session. All conversations within a session MUST use the same --live-doc-id. Do NOT create a new LiveDoc unless the user explicitly asks to "open a new canvas" / "start a new LiveDoc" / "create a new workspace".

  7. Default behavior is follow-up, not new conversation. After the first question, every subsequent user message is a follow-up. You MUST pass --thread-id from the previous response. Only omit --thread-id (to start a new thread on the same LiveDoc) when:

    • The user explicitly says "new topic" / "change subject" / "start over"
    • The user's intent requires a specific --skill-id (e.g., tweet writing, logo design, product image) and the current thread was not created with that skill — because --skill-id only takes effect in new conversations
  8. Always persist state. After every call, extract thread_short_id and live_doc_id from the stderr [state] line (where live_doc_id is output as live_doc_short_id). Use them in the next call. Losing these IDs breaks conversation continuity.

  9. Skill ID selection (New Conversations Only). When creating a new conversation (no --thread-id), analyze the user's intent and determine if it matches one of the supported skill IDs:

    Available skill IDs:

    • twitter-writer — For composing, drafting, or posting tweets/X posts
    • logo-and-branding — For creating logos, brand designs, or visual identity
    • ecommerce-product-image — For generating product images for e-commerce use

    Selection logic:

    • If the user explicitly requests a specific skill-id, use their specified value
    • If the user's intent clearly matches one of the above, pass --skill-id with that value
    • If none of the above match, do NOT pass --skill-id (general conversation mode)
    • --skill-id is only effective when creating a new conversation. It is ignored in follow-up mode (--thread-id).
  10. Brand style selection for skill-based new conversations. When starting a NEW conversation that uses a skill ID (twitter-writer, logo-and-branding, ecommerce-product-image), you MUST fetch the style library and let the user choose a style BEFORE calling run_superagent.mjs. The chosen style is passed via --ext '{"brand_style_requirement":"<style_string>"}'. See Step 4.5 for the full procedure.

    • The style string is the exact text block output by run_style_library.mjs for that entry. Fields vary by category:
      • TWITTER: Style name + Style labels (language-aware) + Style DNA + Cover file ID (omitted if null)
      • IMAGE: Style name + Style labels + Style DNA or Cover file ID depending on what is present
    • Use the category that matches the skill: TWITTER for twitter-writer, IMAGE for logo-and-branding and ecommerce-product-image.
    • Always pass --accept-language to run_style_library.mjs so labels are returned in the user's language.
    • If the user has already specified a style (by name or by pasting the style block), skip the fetch and use their choice directly.
    • If the style library returns no entries, proceed without --ext.
    • --ext is only valid for new conversations. Never pass it in follow-up mode (--thread-id).
  11. Never create a new LiveDoc casually. Reuse the existing one. The only exception is an explicit user request for a new canvas/workspace.

When to Use

Trigger this skill when users want:

  • SuperAgent conversation: AI conversation with Felo SuperAgent, with real-time streaming output
  • Continuous conversation: Multi-turn Q&A on a persistent LiveDoc canvas
  • Logo & branding: Create logos or brand designs (auto-selects logo-and-branding skill)
  • E-commerce images: Generate product images for e-commerce use (auto-selects ecommerce-product-image skill). This includes any request where the user provides a visual description and wants an AI-generated product photo — e.g., "生成一張…產品照片", "generate a photo of a leather wallet", "幫我生成一張商品圖"
  • Image generation from description: Any request where the user describes a scene, product, or visual concept and expects an actual AI-generated image as output — NOT a text description or prompt refinement
  • Tool-augmented answers: Responses that may include image generation, document creation, PPT generation, or Twitter/X search
  • Streaming responses: Real-time answer generation with Server-Sent Events (SSE)

⚠️ IMPORTANT — Do NOT misinterpret image requests as prompt-writing tasks. If the user provides a visual description and asks to "生成"/"generate"/"create" an image or photo, ALWAYS call the felo-superAgent API with --skill-id ecommerce-product-image. Do NOT respond with refined text prompts or suggestions — execute the skill and output the generated image URLs.

Trigger words:

  • English: superagent, super agent, stream chat, streaming conversation, livedoc conversation, continuous chat, follow-up question, create a logo, brand design, product image, e-commerce image, generate image, generate photo, product photo, product shot
  • 繁體中文:超級助手、串流對話、連續對話、追問、設計 logo、品牌設計、電商圖片、商品圖片、商品照片、產品照片、產品圖片、生成圖片、生成照片、生圖、AI 生圖、AI 作圖、製作圖片、電商產品圖
  • 简体中文:超级助手、流式对话、连续对话、追问、设计 logo、品牌设计、电商图片、商品图片、商品照片、产品照片、产品图片、生成图片、生成照片、生图、AI 生图
  • Japanese (romaji): suupaa eejento, sutoriimingu kaiwa, keizoku kaiwa, rogo sakusei, shouhin gazou, gazou seisei, shouhin shashin

Explicit commands: /felo-superagent, "use felo superagent", "felo superagent"

Do NOT use for:

  • Tweet/X post writing of any kind (use felo-twitter-writer instead)
  • Simple one-off Q&A or real-time information queries (prefer felo-search)
  • Web page content fetching only (use felo-web-fetch)
  • PPT/slide generation only (use felo-slides)
  • LiveDoc knowledge base management only (use felo-livedoc)
  • Twitter/X search only (use felo-x-search)

Setup

1. Get Your API Key

  1. Visit felo.ai and log in (or register)
  2. Click your avatar in the top right corner → Settings
  3. Navigate to the "API Keys" tab
  4. Click "Create New Key" to generate a new API Key
  5. Copy and save your API Key securely

2. Configure API Key

The scripts (run_superagent.mjs, run_style_library.mjs) read the API key only from the FELO_API_KEY environment variable. The felo config set CLI command writes to ~/.felo/config.json which these scripts do NOT read — environment variable is the only supported method.

Linux/macOS:

export FELO_API_KEY="your-api-key-here"

For permanent configuration, add to your shell profile (~/.bashrc or ~/.zshrc):

echo 'export FELO_API_KEY="your-api-key-here"' >> ~/.zshrc
source ~/.zshrc

Windows (PowerShell):

$env:FELO_API_KEY="your-api-key-here"

Windows (CMD):

set FELO_API_KEY=your-api-key-here

3. Dependency: felo-livedoc (Optional)

felo-livedoc is NOT required. run_superagent.mjs can be called without --live-doc-id on the first call — the API auto-assigns a LiveDoc and returns its ID in the response for reuse.

How to Execute

When this skill is triggered, follow these steps strictly in order. Execute all commands using the Bash tool.

Step 1: Check API Key

if [ -z "$FELO_API_KEY" ]; then
  echo "ERROR: FELO_API_KEY not set"
  exit 1
fi

If not set, stop and show the user the setup instructions above.

Step 2: Obtain live_doc_id

(Note: live_doc_id corresponds to the API field live_doc_short_id.)

2a. If you already have a live_doc_id from ANY source in this session: Skip to Step 3. Reuse the same ID. Sources include: a previous SuperAgent call's JSON response (data.live_doc_short_id), user-provided input, or any other skill that returned a LiveDoc ID.

2b. If no live_doc_id is available — proceed to Step 3 WITHOUT --live-doc-id. The API will auto-assign a LiveDoc. After the call completes, capture data.live_doc_short_id from the JSON response and reuse it in all subsequent calls.

2c. If the user explicitly requests a new canvas/workspace: Simply omit --live-doc-id in the next call. A new LiveDoc will be created automatically.

Step 3: Determine Conversation Mode

Decide whether this is a new conversation or a follow-up:

ConditionModeWhat to pass
First question in session (no thread_short_id yet)New conversation--live-doc-id if known, omit if not
User asks a follow-up / continues the topic (DEFAULT)Follow-up--thread-id AND --live-doc-id
User explicitly says "new topic" / "change subject"New conversation--live-doc-id only (same LiveDoc)
User's intent requires a --skill-id not matching current threadNew conversation--live-doc-id + --skill-id (same LiveDoc)
User explicitly says "new canvas" / "new LiveDoc"New conversationOmit --live-doc-id (API creates new one)

IMPORTANT: The default for any user message after the first one is ALWAYS follow-up. Only treat it as a new conversation if the user explicitly requests it.

Step 4: Determine Skill ID (New Conversations Only)

If this is a new conversation (no --thread-id), analyze the user's intent:

Available skill IDs:

  • twitter-writer — For composing, drafting, or posting tweets/X posts
  • logo-and-branding — For creating logos, brand designs, or visual identity
  • ecommerce-product-image — For generating product images for e-commerce use

How to decide:

  1. If the user explicitly specifies a skill-id, use that value
  2. Otherwise, analyze the user's request and determine if it matches one of the above
  3. If none match, do NOT pass --skill-id

If this is a follow-up (--thread-id is set), skip this step entirely. --skill-id is ignored in follow-up mode.

Step 4.5: Fetch and Select Brand Style (New Skill Conversations Only)

When to run this step: Only when this is a NEW conversation AND a skill ID was determined in Step 4 (twitter-writer, logo-and-branding, or ecommerce-product-image). Skip entirely for follow-up conversations or general (no skill) conversations.

Category mapping:

Skill IDStyle category
twitter-writerTWITTER
logo-and-brandingIMAGE
ecommerce-product-imageIMAGE

4.5a. If the user has already specified a style (by name, or by pasting a style block), use it directly — skip to 4.5d.

4.5b. Fetch the style list:

Use the category that matches the skill:

Skill ID--category
twitter-writerTWITTER
logo-and-brandingIMAGE
ecommerce-product-imageIMAGE

Pass --accept-language matching the user's language (same value used for SuperAgent).

# For twitter-writer
node .agents/skills/felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en

# For logo-and-branding or ecommerce-product-image
node .agents/skills/felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en

The output lists styles in this format, one block per style separated by a blank line:

Style name: darioamodei
Style labels: Thoughtful long-form essays
Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
...(full content)

Style name: Casual & Witty
Style labels: humor, relatable
Style DNA: ...(full content)
Cover file ID: file_abc123

Notes:

  • Style labels is omitted if no labels exist for this entry.
  • Style DNA is the full text of content.styleDna (TWITTER type). Do NOT truncate it.
  • Cover file ID is omitted if the value is null/empty.

User-created styles appear first, followed by recommended styles.

4.5c. Present the styles to the user and ask them to choose:

Show the list (style names only is sufficient) and ask which one to use. Wait for the user's selection before proceeding.

Example prompt to user:

Here are the available Twitter writing styles. Which one would you like to use?

  1. Casual & Witty (your style)
  2. Professional Thought Leader (recommended)
  3. No style preference — use default

If the user picks "no preference" or the list is empty, proceed to Step 5 without --ext.

4.5d. Build the --ext value:

Take the full text block for the chosen style (exactly as output by the script) and use it as the value of brand_style_requirement. The block may contain multiple lines — serialize them into a single JSON string with \n for newlines and \" for any double quotes inside field values:

Example style block output:

Style name: darioamodei
Style labels: Thoughtful long-form essays
Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## Style Overview\nDario writes like a serious intellectual...

Serialized as --ext:

--ext '{"brand_style_requirement":"Style name: darioamodei\nStyle labels: Thoughtful long-form essays\nStyle DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## Style Overview\nDario writes like a serious intellectual..."}'

Important: Pass the brand_style_requirement value completely and verbatim — do NOT truncate Style DNA. Partial style content will degrade output quality.

Step 5: Run the Script

Construct and execute the command. ALWAYS use --json — in Claude Code's Bash tool, stdout is captured, not streamed to the user. JSON mode returns the full answer in a structured response.

IMPORTANT: The SSE stream may take a long time (especially for image generation, research reports, etc.). You MUST set the Bash tool timeout to at least 600000ms (10 minutes) when executing the script to prevent premature termination.

--accept-language selection: Default is en. Match the user's language — if the user writes in Chinese use zh, Japanese use ja, Korean use ko, etc.

--query construction: Do NOT simply pass the user's raw input as-is. You should enrich and refine the query to make it more complete and effective for SuperAgent:

  • Add context: If the conversation has prior context (e.g., the user previously discussed a topic), incorporate relevant details so SuperAgent understands the full picture.
  • Clarify vague requests: If the user says something brief like "continue" or "go on", expand it to describe what should be continued (e.g., "Please continue the previous analysis and provide more details").
  • Supplement missing details: If the user's request implies information they mentioned earlier (e.g., brand name, product type, style preference), include those details in the query.
  • Preserve user intent: Never change the user's core intent. Only add context and clarity — do not inject opinions or redirect the topic.
  • Keep it concise: The query has a 2000-character limit. Enrich the content but stay focused and avoid unnecessary padding.

Examples:

  • User says "continue" → --query "Please continue the analysis above on quantum computing, expanding on real-world applications"
  • User says "one more" → --query "Please generate another product image in a similar style, white background"
  • User says "fix it" → --query "Please revise the tweet generated above, make the tone more casual and add some emojis"

New conversation (first question, no skill):

node .agents/skills/felo-superAgent/scripts/run_superagent.mjs \
  --query "USER_QUERY_HERE" \
  --live-doc-id "LIVE_DOC_ID" \
  --accept-language en \
  --json

New conversation with skill ID, no style selected:

node .agents/skills/felo-superAgent/scripts/run_superagent.mjs \
  --query "Write a tweet about the latest AI trends" \
  --live-doc-id "LIVE_DOC_ID" \
  --skill-id twitter-writer \
  --accept-language en \
  --json

New conversation with skill ID and brand style (from Step 4.5):

node .agents/skills/felo-superAgent/scripts/run_superagent.mjs \
  --query "Write a tweet about the latest AI trends" \
  --live-doc-id "LIVE_DOC_ID" \
  --skill-id twitter-writer \
  --ext '{"brand_style_requirement":"Style name: darioamodei\nStyle labels: Thoughtful long-form essays\nStyle DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## Style Overview\nDario writes like a serious intellectual...(full content)"}' \
  --accept-language en \
  --json

Follow-up question (DEFAULT for 2nd+ messages):

node .agents/skills/felo-superAgent/scripts/run_superagent.mjs \
  --query "USER_FOLLOW_UP_QUERY" \
  --thread-id "THREAD_SHORT_ID_FROM_PREVIOUS" \
  --live-doc-id "LIVE_DOC_ID" \
  --json

Step 6: Extract State and Output the Answer

After the script finishes, parse the JSON output:

{
  "status": "ok",
  "data": {
    "answer": "...",
    "thread_short_id": "CmYpuGwBgCnrUdDx5ZtmxA",
    "live_doc_short_id": "QPetunwpGnkKuZHStP7gwt",
    "live_doc_url": "https://felo.ai/livedoc/QPetunwpGnkKuZHStP7gwt",
    "image_urls": [{ "url": "https://...", "title": "Logo Design" }],
    "discoveries": [{ "title": "Research Report" }],
    "documents": [{ "title": "Generated Document" }],
    "ppts": [{ "title": "Presentation" }],
    "htmls": [{ "title": "HTML Page" }]
  }
}
  1. Output data.answer verbatim as your response text — print it exactly as-is so the user sees the full content.
  2. Output data.image_urls as inline images — if data.image_urls is present and non-empty, render each entry as a Markdown image immediately after the answer:
    ![{title}]({url})
    
    Do NOT skip or omit image URLs. This is the primary output for logo design, product image, and any image generation requests.
  3. Output other tool results — if present, list them after the images:
    • data.discoveries: 🔍 Research report: {title}
    • data.documents: 📄 Document: {title}
    • data.ppts: 📊 Presentation: {title}
    • data.htmls: 🌐 HTML page: {title}
  4. Extract and save data.thread_short_id and data.live_doc_short_id — you MUST use these in the next call.
  5. Optionally show data.live_doc_url so the user can view the LiveDoc canvas in a browser.

Do NOT show thread_short_id or live_doc_short_id to the user unless they ask for it.

Complete Workflow Examples

Example A: Multi-turn Conversation (Most Common)

User: "What is quantum computing?"

Step 2b: No live_doc_id yet → proceed without it (API will auto-assign) Step 3: First question → New conversation Step 4: No special skill → no --skill-id Step 5:

node .agents/skills/felo-superAgent/scripts/run_superagent.mjs \
  --query "What is quantum computing?" \
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
  --accept-language en \
  --json

Step 6: Parse JSON output. Output data.answer verbatim as your response. Save thread_short_id = "CmYpuGwBgCnrUdDx5ZtmxA", live_doc_id = "QPetunwpGnkKuZHStP7gwt" from data.

User: "What are its practical applications?"

Step 2a: Already have live_doc_id → skip Step 3: Follow-up (default) → use saved thread_short_id Step 5:

node .agents/skills/felo-superAgent/scripts/run_superagent.mjs \
  --query "What are its practical applications?" \
  --thread-id "CmYpuGwBgCnrUdDx5ZtmxA" \
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
  --json

Step 6: Parse JSON output. Output data.answer verbatim. Save updated thread_short_id from data (may be the same), keep live_doc_id.

User: "Tell me more about quantum error correction"

Step 3: Still follow-up (same topic) → use saved thread_short_id Step 5: Same pattern as above with new query

Example B: Tweet Writing with Style Selection

User: "Help me write a tweet about AI trends"

Step 2a: Already have live_doc_id → reuse Step 3: New conversation Step 4: User intent matches "write a tweet" → --skill-id twitter-writer Step 4.5: Fetch TWITTER styles (pass --accept-language matching user's language):

node .agents/skills/felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en

Output:

Style name: My Bold Voice
Style labels: bold, provocative
Style DNA: # My Bold Voice Style DNA
...(full content)

Style name: darioamodei
Style labels: Thoughtful long-form essays
Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
...(full content)

Present to user: "Which writing style would you like? 1. My Bold Voice (yours) 2. darioamodei (recommended) 3. No preference"

User selects: "1. My Bold Voice"

Step 5:

node .agents/skills/felo-superAgent/scripts/run_superagent.mjs \
  --query "Help me write a tweet about AI trends" \
  --live-doc-id "QPetunwpGnkKuZHStP7gwt" \
  --skill-id twitter-writer \
  --ext '{"brand_style_requirement":"Style name: My Bold Voice\nStyle labels: bold, provocative\nStyle DNA: # My Bold Voice Style DNA\n...(full content)"}' \
  --accept-language en \
  --json

Step 6: Parse JSON output. Output data.answer verbatim. Save new thread_short_id from data, keep same live_doc_id.

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
253
Forks
53
Last commit
Sep 2026

ahel review

  • K6low
    bundled executables the agent is told to run
  • K1binfo
    installs-packages (in README.md)

Automated review, not a security audit. Ruleset v1+k2.

Advanced
Item type
skill
Key
felo-superagent
Source
github.com/duotify/githubclawtoolkit