Felo SuperAgent Skill
SkillMediaGenerates product photos, logos, and branding images through an ongoing AI chat.
Available today. Use it from your connected AI after setup.
No other account needed.
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.
-
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.mjswith--skill-id ecommerce-product-imageorlogo-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. -
ALWAYS use
--jsonflag. 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 fieldsthread_short_idandlive_doc_short_id. -
ALWAYS output the answer and all tool results. After the script finishes: (a) print
data.answerverbatim as your response text — do NOT summarize or paraphrase; (b) render every entry indata.image_urlsas a Markdown inline imageimmediately after the answer — NEVER skip image URLs; (c) list any entries indata.discoveries,data.documents,data.ppts,data.htmls. -
--live-doc-idis optional for the first call.run_superagent.mjsworks without--live-doc-id— the API will auto-assign a LiveDoc and return itslive_doc_short_idin 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 returnedlive_doc_short_id(see Constraint #4 and Step 2). -
Reuse
live_doc_idfrom ANY source. If you already have alive_doc_idfrom 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-idwhen you truly have no ID from any source. (Note:live_doc_idcorresponds to the API fieldlive_doc_short_idand the[state]output keylive_doc_short_id.) -
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". -
Default behavior is follow-up, not new conversation. After the first question, every subsequent user message is a follow-up. You MUST pass
--thread-idfrom 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-idonly takes effect in new conversations
-
Always persist state. After every call, extract
thread_short_idandlive_doc_idfrom the stderr[state]line (wherelive_doc_idis output aslive_doc_short_id). Use them in the next call. Losing these IDs breaks conversation continuity. -
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 postslogo-and-branding— For creating logos, brand designs, or visual identityecommerce-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-idwith that value - If none of the above match, do NOT pass
--skill-id(general conversation mode) --skill-idis only effective when creating a new conversation. It is ignored in follow-up mode (--thread-id).
-
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 callingrun_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.mjsfor 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 DNAorCover file IDdepending on what is present
- TWITTER:
- Use the category that matches the skill:
TWITTERfortwitter-writer,IMAGEforlogo-and-brandingandecommerce-product-image. - Always pass
--accept-languagetorun_style_library.mjsso 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. --extis only valid for new conversations. Never pass it in follow-up mode (--thread-id).
- The style string is the exact text block output by
-
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-brandingskill) - E-commerce images: Generate product images for e-commerce use (auto-selects
ecommerce-product-imageskill). 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-writerinstead) - 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
- Visit felo.ai and log in (or register)
- Click your avatar in the top right corner → Settings
- Navigate to the "API Keys" tab
- Click "Create New Key" to generate a new API Key
- 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:
| Condition | Mode | What 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 thread | New conversation | --live-doc-id + --skill-id (same LiveDoc) |
| User explicitly says "new canvas" / "new LiveDoc" | New conversation | Omit --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 postslogo-and-branding— For creating logos, brand designs, or visual identityecommerce-product-image— For generating product images for e-commerce use
How to decide:
- If the user explicitly specifies a skill-id, use that value
- Otherwise, analyze the user's request and determine if it matches one of the above
- 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 ID | Style category |
|---|---|
twitter-writer | TWITTER |
logo-and-branding | IMAGE |
ecommerce-product-image | IMAGE |
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-writer | TWITTER |
logo-and-branding | IMAGE |
ecommerce-product-image | IMAGE |
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 labelsis omitted if no labels exist for this entry.Style DNAis the full text ofcontent.styleDna(TWITTER type). Do NOT truncate it.Cover file IDis 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?
- Casual & Witty (your style)
- Professional Thought Leader (recommended)
- 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" }]
}
}
- Output
data.answerverbatim as your response text — print it exactly as-is so the user sees the full content. - Output
data.image_urlsas inline images — ifdata.image_urlsis present and non-empty, render each entry as a Markdown image immediately after the answer:
Do NOT skip or omit image URLs. This is the primary output for logo design, product image, and any image generation requests. - 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}
- Extract and save
data.thread_short_idanddata.live_doc_short_id— you MUST use these in the next call. - Optionally show
data.live_doc_urlso 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 runK1binfo
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