felo-ai 0.2.47 → 0.2.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -51
- package/felo-superAgent/README.md +223 -280
- package/felo-superAgent/SKILL.md +281 -47
- package/felo-superAgent/scripts/run_style_library.mjs +213 -0
- package/felo-twitter-writer/README.md +117 -13
- package/felo-twitter-writer/SKILL.md +276 -41
- package/package.json +1 -1
- package/src/cli.js +19 -1
- package/src/superAgent.js +133 -0
package/felo-superAgent/SKILL.md
CHANGED
|
@@ -9,9 +9,9 @@ description: "Felo SuperAgent API: AI conversation with real-time SSE streaming
|
|
|
9
9
|
|
|
10
10
|
These rules are mandatory. Violating any of them will produce incorrect behavior.
|
|
11
11
|
|
|
12
|
-
1. **
|
|
12
|
+
1. **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`.
|
|
13
13
|
|
|
14
|
-
2. **
|
|
14
|
+
2. **ALWAYS output the answer directly as text.** After the script finishes, read `data.answer` from the JSON output and print it verbatim as your response text. Do NOT summarize, paraphrase, or add commentary around it. Output it exactly as-is so the user sees the full content.
|
|
15
15
|
|
|
16
16
|
3. **`--live-doc-id` is REQUIRED when creating a conversation.** Never call `run_superagent.mjs` without `--live-doc-id`. If you do not have one yet, obtain it first (see Step 2 below).
|
|
17
17
|
|
|
@@ -38,7 +38,18 @@ These rules are mandatory. Violating any of them will produce incorrect behavior
|
|
|
38
38
|
- If none of the above match, do NOT pass `--skill-id` (general conversation mode)
|
|
39
39
|
- `--skill-id` is only effective when creating a new conversation. It is ignored in follow-up mode (`--thread-id`).
|
|
40
40
|
|
|
41
|
-
9. **
|
|
41
|
+
9. **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.
|
|
42
|
+
|
|
43
|
+
- The style string is the exact text block output by `run_style_library.mjs` for that entry. Fields vary by category:
|
|
44
|
+
- **TWITTER**: `Style name` + `Style labels` (language-aware) + `Style DNA` + `Cover file ID` (omitted if null)
|
|
45
|
+
- **IMAGE**: `Style name` + `Style labels` + `Style DNA` or `Cover file ID` depending on what is present
|
|
46
|
+
- Use the category that matches the skill: `TWITTER` for `twitter-writer`, `IMAGE` for `logo-and-branding` and `ecommerce-product-image`.
|
|
47
|
+
- Always pass `--accept-language` to `run_style_library.mjs` so labels are returned in the user's language.
|
|
48
|
+
- If the user has already specified a style (by name or by pasting the style block), skip the fetch and use their choice directly.
|
|
49
|
+
- If the style library returns no entries, proceed without `--ext`.
|
|
50
|
+
- `--ext` is only valid for new conversations. Never pass it in follow-up mode (`--thread-id`).
|
|
51
|
+
|
|
52
|
+
10. **Never create a new LiveDoc casually.** Reuse the existing one. The only exception is an explicit user request for a new canvas/workspace.
|
|
42
53
|
|
|
43
54
|
## When to Use
|
|
44
55
|
|
|
@@ -81,13 +92,19 @@ Trigger this skill when users want:
|
|
|
81
92
|
|
|
82
93
|
### 2. Configure API Key
|
|
83
94
|
|
|
84
|
-
|
|
95
|
+
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.
|
|
85
96
|
|
|
86
97
|
**Linux/macOS:**
|
|
87
98
|
```bash
|
|
88
99
|
export FELO_API_KEY="your-api-key-here"
|
|
89
100
|
```
|
|
90
101
|
|
|
102
|
+
For permanent configuration, add to your shell profile (`~/.bashrc` or `~/.zshrc`):
|
|
103
|
+
```bash
|
|
104
|
+
echo 'export FELO_API_KEY="your-api-key-here"' >> ~/.zshrc
|
|
105
|
+
source ~/.zshrc
|
|
106
|
+
```
|
|
107
|
+
|
|
91
108
|
**Windows (PowerShell):**
|
|
92
109
|
```powershell
|
|
93
110
|
$env:FELO_API_KEY="your-api-key-here"
|
|
@@ -98,8 +115,6 @@ $env:FELO_API_KEY="your-api-key-here"
|
|
|
98
115
|
set FELO_API_KEY=your-api-key-here
|
|
99
116
|
```
|
|
100
117
|
|
|
101
|
-
For permanent configuration, add it to your shell profile (~/.bashrc, ~/.zshrc) or system environment variables.
|
|
102
|
-
|
|
103
118
|
### 3. Dependency: felo-livedoc
|
|
104
119
|
|
|
105
120
|
This skill depends on the `felo-livedoc` skill to obtain and create LiveDocs. Ensure `felo-livedoc/scripts/run_livedoc.mjs` is available at the same level as `felo-superAgent/`.
|
|
@@ -148,7 +163,7 @@ Example response:
|
|
|
148
163
|
}
|
|
149
164
|
```
|
|
150
165
|
|
|
151
|
-
Use: `live_doc_id = items[0].short_id`
|
|
166
|
+
Use: `live_doc_id = data.items[0].short_id`
|
|
152
167
|
|
|
153
168
|
**2c. If the list is empty (no LiveDocs exist) — create one:**
|
|
154
169
|
|
|
@@ -204,9 +219,93 @@ If this is a new conversation (no `--thread-id`), analyze the user's intent:
|
|
|
204
219
|
|
|
205
220
|
If this is a follow-up (`--thread-id` is set), skip this step entirely. `--skill-id` is ignored in follow-up mode.
|
|
206
221
|
|
|
222
|
+
### Step 4.5: Fetch and Select Brand Style (New Skill Conversations Only)
|
|
223
|
+
|
|
224
|
+
**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.
|
|
225
|
+
|
|
226
|
+
**Category mapping:**
|
|
227
|
+
| Skill ID | Style category |
|
|
228
|
+
|---|---|
|
|
229
|
+
| `twitter-writer` | `TWITTER` |
|
|
230
|
+
| `logo-and-branding` | `IMAGE` |
|
|
231
|
+
| `ecommerce-product-image` | `IMAGE` |
|
|
232
|
+
|
|
233
|
+
**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.
|
|
234
|
+
|
|
235
|
+
**4.5b. Fetch the style list:**
|
|
236
|
+
|
|
237
|
+
Use the category that matches the skill:
|
|
238
|
+
|
|
239
|
+
| Skill ID | `--category` |
|
|
240
|
+
|---|---|
|
|
241
|
+
| `twitter-writer` | `TWITTER` |
|
|
242
|
+
| `logo-and-branding` | `IMAGE` |
|
|
243
|
+
| `ecommerce-product-image` | `IMAGE` |
|
|
244
|
+
|
|
245
|
+
Pass `--accept-language` matching the user's language (same value used for SuperAgent).
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# For twitter-writer
|
|
249
|
+
node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
|
|
250
|
+
|
|
251
|
+
# For logo-and-branding or ecommerce-product-image
|
|
252
|
+
node felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
The output lists styles in this format, one block per style separated by a blank line:
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
Style name: darioamodei
|
|
259
|
+
Style labels: Thoughtful long-form essays
|
|
260
|
+
Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
|
|
261
|
+
...(full content)
|
|
262
|
+
|
|
263
|
+
Style name: Casual & Witty
|
|
264
|
+
Style labels: humor, relatable
|
|
265
|
+
Style DNA: ...(full content)
|
|
266
|
+
Cover file ID: file_abc123
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Notes:
|
|
270
|
+
- `Style labels` is omitted if no labels exist for this entry.
|
|
271
|
+
- `Style DNA` is the full text of `content.styleDna` (TWITTER type). Do NOT truncate it.
|
|
272
|
+
- `Cover file ID` is omitted if the value is null/empty.
|
|
273
|
+
|
|
274
|
+
User-created styles appear first, followed by recommended styles.
|
|
275
|
+
|
|
276
|
+
**4.5c. Present the styles to the user and ask them to choose:**
|
|
277
|
+
|
|
278
|
+
Show the list (style names only is sufficient) and ask which one to use. Wait for the user's selection before proceeding.
|
|
279
|
+
|
|
280
|
+
Example prompt to user:
|
|
281
|
+
> Here are the available Twitter writing styles. Which one would you like to use?
|
|
282
|
+
> 1. Casual & Witty (your style)
|
|
283
|
+
> 2. Professional Thought Leader (recommended)
|
|
284
|
+
> 3. No style preference — use default
|
|
285
|
+
|
|
286
|
+
If the user picks "no preference" or the list is empty, proceed to Step 5 without `--ext`.
|
|
287
|
+
|
|
288
|
+
**4.5d. Build the `--ext` value:**
|
|
289
|
+
|
|
290
|
+
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:
|
|
291
|
+
|
|
292
|
+
Example style block output:
|
|
293
|
+
```
|
|
294
|
+
Style name: darioamodei
|
|
295
|
+
Style labels: Thoughtful long-form essays
|
|
296
|
+
Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## 风格速写\nDario writes like a serious intellectual...
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Serialized as `--ext`:
|
|
300
|
+
```bash
|
|
301
|
+
--ext '{"brand_style_requirement":"Style name: darioamodei\nStyle labels: Thoughtful long-form essays\nStyle DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## 风格速写\nDario writes like a serious intellectual..."}'
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Important:** Pass the `brand_style_requirement` value completely and verbatim — do NOT truncate `Style DNA`. Partial style content will degrade output quality.
|
|
305
|
+
|
|
207
306
|
### Step 5: Run the Script
|
|
208
307
|
|
|
209
|
-
Construct and execute the command. **
|
|
308
|
+
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.
|
|
210
309
|
|
|
211
310
|
**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.
|
|
212
311
|
|
|
@@ -225,21 +324,34 @@ Examples:
|
|
|
225
324
|
- User says "再来一张" → `--query "请再生成一张类似风格的无线耳机产品图,白色背景"`
|
|
226
325
|
- User says "帮我改改" → `--query "请修改上面生成的推文,语气更轻松一些,加一些emoji"`
|
|
227
326
|
|
|
228
|
-
**New conversation (first question):**
|
|
327
|
+
**New conversation (first question, no skill):**
|
|
229
328
|
```bash
|
|
230
329
|
node felo-superAgent/scripts/run_superagent.mjs \
|
|
231
330
|
--query "USER_QUERY_HERE" \
|
|
232
331
|
--live-doc-id "LIVE_DOC_ID" \
|
|
233
|
-
--accept-language en
|
|
332
|
+
--accept-language en \
|
|
333
|
+
--json
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**New conversation with skill ID, no style selected:**
|
|
337
|
+
```bash
|
|
338
|
+
node felo-superAgent/scripts/run_superagent.mjs \
|
|
339
|
+
--query "Write a tweet about the latest AI trends" \
|
|
340
|
+
--live-doc-id "LIVE_DOC_ID" \
|
|
341
|
+
--skill-id twitter-writer \
|
|
342
|
+
--accept-language en \
|
|
343
|
+
--json
|
|
234
344
|
```
|
|
235
345
|
|
|
236
|
-
**New conversation with skill ID (
|
|
346
|
+
**New conversation with skill ID and brand style (from Step 4.5):**
|
|
237
347
|
```bash
|
|
238
348
|
node felo-superAgent/scripts/run_superagent.mjs \
|
|
239
349
|
--query "Write a tweet about the latest AI trends" \
|
|
240
350
|
--live-doc-id "LIVE_DOC_ID" \
|
|
241
351
|
--skill-id twitter-writer \
|
|
242
|
-
--
|
|
352
|
+
--ext '{"brand_style_requirement":"Style name: darioamodei\nStyle labels: Thoughtful long-form essays\nStyle DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## 风格速写\nDario writes like a serious intellectual...(full content)"}' \
|
|
353
|
+
--accept-language en \
|
|
354
|
+
--json
|
|
243
355
|
```
|
|
244
356
|
|
|
245
357
|
**Follow-up question (DEFAULT for 2nd+ messages):**
|
|
@@ -247,23 +359,31 @@ node felo-superAgent/scripts/run_superagent.mjs \
|
|
|
247
359
|
node felo-superAgent/scripts/run_superagent.mjs \
|
|
248
360
|
--query "USER_FOLLOW_UP_QUERY" \
|
|
249
361
|
--thread-id "THREAD_SHORT_ID_FROM_PREVIOUS" \
|
|
250
|
-
--live-doc-id "LIVE_DOC_ID"
|
|
362
|
+
--live-doc-id "LIVE_DOC_ID" \
|
|
363
|
+
--json
|
|
251
364
|
```
|
|
252
365
|
|
|
253
|
-
### Step 6: Extract State
|
|
366
|
+
### Step 6: Extract State and Output the Answer
|
|
254
367
|
|
|
255
|
-
|
|
368
|
+
After the script finishes, parse the JSON output:
|
|
256
369
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
370
|
+
```json
|
|
371
|
+
{
|
|
372
|
+
"status": "ok",
|
|
373
|
+
"data": {
|
|
374
|
+
"answer": "...",
|
|
375
|
+
"thread_short_id": "CmYpuGwBgCnrUdDx5ZtmxA",
|
|
376
|
+
"live_doc_short_id": "QPetunwpGnkKuZHStP7gwt",
|
|
377
|
+
"live_doc_url": "https://felo.ai/livedoc/QPetunwpGnkKuZHStP7gwt"
|
|
378
|
+
}
|
|
379
|
+
}
|
|
261
380
|
```
|
|
262
381
|
|
|
263
|
-
1. **
|
|
264
|
-
2. **
|
|
382
|
+
1. **Output `data.answer` verbatim** as your response text — print it exactly as-is so the user sees the full content.
|
|
383
|
+
2. **Extract and save** `data.thread_short_id` and `data.live_doc_short_id` — you MUST use these in the next call.
|
|
384
|
+
3. **Optionally show** `data.live_doc_url` so the user can view the LiveDoc canvas in a browser.
|
|
265
385
|
|
|
266
|
-
Do NOT show `thread_short_id` or `
|
|
386
|
+
Do NOT show `thread_short_id` or `live_doc_short_id` to the user unless they ask for it.
|
|
267
387
|
|
|
268
388
|
## Complete Workflow Examples
|
|
269
389
|
|
|
@@ -281,9 +401,10 @@ User: "What is quantum computing?"
|
|
|
281
401
|
node felo-superAgent/scripts/run_superagent.mjs \
|
|
282
402
|
--query "What is quantum computing?" \
|
|
283
403
|
--live-doc-id "QPetunwpGnkKuZHStP7gwt" \
|
|
284
|
-
--accept-language en
|
|
404
|
+
--accept-language en \
|
|
405
|
+
--json
|
|
285
406
|
```
|
|
286
|
-
**Step 6:**
|
|
407
|
+
**Step 6:** Parse JSON output. Output `data.answer` verbatim as your response. Save `thread_short_id = "CmYpuGwBgCnrUdDx5ZtmxA"`, `live_doc_id = "QPetunwpGnkKuZHStP7gwt"` from `data`.
|
|
287
408
|
|
|
288
409
|
```
|
|
289
410
|
User: "What are its practical applications?"
|
|
@@ -296,9 +417,10 @@ User: "What are its practical applications?"
|
|
|
296
417
|
node felo-superAgent/scripts/run_superagent.mjs \
|
|
297
418
|
--query "What are its practical applications?" \
|
|
298
419
|
--thread-id "CmYpuGwBgCnrUdDx5ZtmxA" \
|
|
299
|
-
--live-doc-id "QPetunwpGnkKuZHStP7gwt"
|
|
420
|
+
--live-doc-id "QPetunwpGnkKuZHStP7gwt" \
|
|
421
|
+
--json
|
|
300
422
|
```
|
|
301
|
-
**Step 6:**
|
|
423
|
+
**Step 6:** Parse JSON output. Output `data.answer` verbatim. Save updated `thread_short_id` from `data` (may be the same), keep `live_doc_id`.
|
|
302
424
|
|
|
303
425
|
```
|
|
304
426
|
User: "Tell me more about quantum error correction"
|
|
@@ -307,68 +429,113 @@ User: "Tell me more about quantum error correction"
|
|
|
307
429
|
**Step 3:** Still follow-up (same topic) → use saved `thread_short_id`
|
|
308
430
|
**Step 5:** Same pattern as above with new query
|
|
309
431
|
|
|
310
|
-
### Example B: Tweet Writing
|
|
432
|
+
### Example B: Tweet Writing with Style Selection
|
|
311
433
|
|
|
312
434
|
```
|
|
313
435
|
User: "Help me write a tweet about AI trends"
|
|
314
436
|
```
|
|
315
437
|
|
|
316
438
|
**Step 2a:** Already have `live_doc_id` → reuse
|
|
317
|
-
**Step 3:** New conversation
|
|
439
|
+
**Step 3:** New conversation
|
|
318
440
|
**Step 4:** User intent matches "write a tweet" → `--skill-id twitter-writer`
|
|
441
|
+
**Step 4.5:** Fetch TWITTER styles (pass `--accept-language` matching user's language):
|
|
442
|
+
```bash
|
|
443
|
+
node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
|
|
444
|
+
```
|
|
445
|
+
Output:
|
|
446
|
+
```
|
|
447
|
+
Style name: My Bold Voice
|
|
448
|
+
Style labels: bold, provocative
|
|
449
|
+
Style DNA: # My Bold Voice Style DNA
|
|
450
|
+
...(full content)
|
|
451
|
+
|
|
452
|
+
Style name: darioamodei
|
|
453
|
+
Style labels: Thoughtful long-form essays
|
|
454
|
+
Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
|
|
455
|
+
...(full content)
|
|
456
|
+
```
|
|
457
|
+
Present to user: "Which writing style would you like? 1. My Bold Voice (yours) 2. darioamodei (recommended) 3. No preference"
|
|
458
|
+
|
|
459
|
+
User selects: "1. My Bold Voice"
|
|
460
|
+
|
|
319
461
|
**Step 5:**
|
|
320
462
|
```bash
|
|
321
463
|
node felo-superAgent/scripts/run_superagent.mjs \
|
|
322
464
|
--query "Help me write a tweet about AI trends" \
|
|
323
465
|
--live-doc-id "QPetunwpGnkKuZHStP7gwt" \
|
|
324
466
|
--skill-id twitter-writer \
|
|
325
|
-
--
|
|
467
|
+
--ext '{"brand_style_requirement":"Style name: My Bold Voice\nStyle labels: bold, provocative\nStyle DNA: # My Bold Voice Style DNA\n...(full content)"}' \
|
|
468
|
+
--accept-language en \
|
|
469
|
+
--json
|
|
326
470
|
```
|
|
327
|
-
**Step 6:**
|
|
471
|
+
**Step 6:** Parse JSON output. Output `data.answer` verbatim. Save new `thread_short_id` from `data`, keep same `live_doc_id`.
|
|
328
472
|
|
|
329
473
|
```
|
|
330
474
|
User: "Make it more casual and add some emojis"
|
|
331
475
|
```
|
|
332
476
|
|
|
333
|
-
**Step 3:** Follow-up → use saved `thread_short_id`
|
|
477
|
+
**Step 3:** Follow-up → use saved `thread_short_id` (do NOT pass `--ext` again)
|
|
334
478
|
**Step 5:**
|
|
335
479
|
```bash
|
|
336
480
|
node felo-superAgent/scripts/run_superagent.mjs \
|
|
337
481
|
--query "Make it more casual and add some emojis" \
|
|
338
482
|
--thread-id "NEW_THREAD_FROM_TWEET" \
|
|
339
|
-
--live-doc-id "QPetunwpGnkKuZHStP7gwt"
|
|
483
|
+
--live-doc-id "QPetunwpGnkKuZHStP7gwt" \
|
|
484
|
+
--json
|
|
340
485
|
```
|
|
341
486
|
|
|
342
|
-
### Example C: Logo Design
|
|
487
|
+
### Example C: Logo Design with Style Selection
|
|
343
488
|
|
|
344
489
|
```
|
|
345
490
|
User: "Design a logo for my coffee shop called Bean & Brew"
|
|
346
491
|
```
|
|
347
492
|
|
|
348
493
|
**Step 4:** Detected "design a logo" → `--skill-id logo-and-branding`
|
|
494
|
+
**Step 4.5:** Fetch IMAGE styles:
|
|
495
|
+
```bash
|
|
496
|
+
node felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en
|
|
497
|
+
```
|
|
498
|
+
Output example:
|
|
499
|
+
```
|
|
500
|
+
Style name: Minimalist Modern
|
|
501
|
+
Style labels: clean, monochrome
|
|
502
|
+
Style DNA: ...(full content)
|
|
503
|
+
Cover file ID: file_333
|
|
504
|
+
```
|
|
505
|
+
Present styles to user and wait for selection. Suppose user picks "Minimalist Modern":
|
|
506
|
+
|
|
349
507
|
**Step 5:**
|
|
350
508
|
```bash
|
|
351
509
|
node felo-superAgent/scripts/run_superagent.mjs \
|
|
352
510
|
--query "Design a logo for my coffee shop called Bean & Brew" \
|
|
353
511
|
--live-doc-id "QPetunwpGnkKuZHStP7gwt" \
|
|
354
512
|
--skill-id logo-and-branding \
|
|
355
|
-
--
|
|
513
|
+
--ext '{"brand_style_requirement":"Style name: Minimalist Modern\nStyle labels: clean, monochrome\nStyle DNA: ...(full content)\nCover file ID: file_333"}' \
|
|
514
|
+
--accept-language en \
|
|
515
|
+
--json
|
|
356
516
|
```
|
|
357
517
|
|
|
358
|
-
### Example D: E-commerce Product Image
|
|
518
|
+
### Example D: E-commerce Product Image with Style Selection
|
|
359
519
|
|
|
360
520
|
```
|
|
361
521
|
User: "Generate a product image for a wireless headphone on white background"
|
|
362
522
|
```
|
|
363
523
|
|
|
364
524
|
**Step 4:** Detected "product image" → `--skill-id ecommerce-product-image`
|
|
365
|
-
**Step 5:**
|
|
525
|
+
**Step 4.5:** Fetch IMAGE styles:
|
|
526
|
+
```bash
|
|
527
|
+
node felo-superAgent/scripts/run_style_library.mjs --category IMAGE --accept-language en
|
|
528
|
+
```
|
|
529
|
+
Present styles to user. Suppose user picks "No preference":
|
|
530
|
+
|
|
531
|
+
**Step 5:** (no `--ext` since user chose no preference)
|
|
366
532
|
```bash
|
|
367
533
|
node felo-superAgent/scripts/run_superagent.mjs \
|
|
368
534
|
--query "Generate a product image for a wireless headphone on white background" \
|
|
369
535
|
--live-doc-id "QPetunwpGnkKuZHStP7gwt" \
|
|
370
536
|
--skill-id ecommerce-product-image \
|
|
371
|
-
--accept-language en
|
|
537
|
+
--accept-language en \
|
|
538
|
+
--json
|
|
372
539
|
```
|
|
373
540
|
|
|
374
541
|
### Example E: User Requests a New Canvas
|
|
@@ -383,6 +550,30 @@ node felo-livedoc/scripts/run_livedoc.mjs create --name "New Project" --json
|
|
|
383
550
|
```
|
|
384
551
|
Extract new `live_doc_id`. Discard the old one. All subsequent calls use the new ID.
|
|
385
552
|
|
|
553
|
+
### Example F: User Specifies Style Directly
|
|
554
|
+
|
|
555
|
+
```
|
|
556
|
+
User: "Write a tweet about AI trends using the 'darioamodei' style"
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
**Step 4:** `--skill-id twitter-writer`
|
|
560
|
+
**Step 4.5a:** User already named the style → fetch the list to get the full block:
|
|
561
|
+
```bash
|
|
562
|
+
node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
|
|
563
|
+
```
|
|
564
|
+
Find the entry with `Style name: darioamodei`, extract its full block verbatim. No need to ask the user again.
|
|
565
|
+
|
|
566
|
+
**Step 5:**
|
|
567
|
+
```bash
|
|
568
|
+
node felo-superAgent/scripts/run_superagent.mjs \
|
|
569
|
+
--query "Write a tweet about AI trends" \
|
|
570
|
+
--live-doc-id "QPetunwpGnkKuZHStP7gwt" \
|
|
571
|
+
--skill-id twitter-writer \
|
|
572
|
+
--ext '{"brand_style_requirement":"Style name: darioamodei\nStyle labels: Thoughtful long-form essays\nStyle DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA\n\n## 风格速写\nDario writes like a serious intellectual...(full content, do NOT truncate)"}' \
|
|
573
|
+
--accept-language en \
|
|
574
|
+
--json
|
|
575
|
+
```
|
|
576
|
+
|
|
386
577
|
## Available Script Options
|
|
387
578
|
|
|
388
579
|
**Core parameters:**
|
|
@@ -391,12 +582,14 @@ Extract new `live_doc_id`. Discard the old one. All subsequent calls use the new
|
|
|
391
582
|
- `--thread-id <id>` — Thread ID from previous response, for follow-up conversations
|
|
392
583
|
|
|
393
584
|
**Skill parameters (new conversations only, ignored in follow-up):**
|
|
394
|
-
- `--skill-id <id>` — Skill ID (see Constraint #
|
|
585
|
+
- `--skill-id <id>` — Skill ID (see Constraint #9 for available skill IDs)
|
|
395
586
|
- `--selected-resource-ids <ids>` — Comma-separated resource IDs to include
|
|
396
|
-
- `--ext <json>` — Extra parameters as JSON object
|
|
587
|
+
- `--ext <json>` — Extra parameters as JSON object. For skill-based conversations, pass brand style as:
|
|
588
|
+
`--ext '{"brand_style_requirement":"Style name: <name>\nStyle labels: <labels>\nStyle DNA: <full styleDna text>\nCover file ID: <id>"}'`
|
|
589
|
+
Fields present depend on category type. `Cover file ID` is omitted when null. Do NOT truncate `Style DNA`.
|
|
397
590
|
|
|
398
591
|
**Output control:**
|
|
399
|
-
- `--json` / `-j` — Output JSON format with full metadata (
|
|
592
|
+
- `--json` / `-j` — Output JSON format with full metadata (ALWAYS use this in Claude Code — stdout is captured by the Bash tool, not streamed to the user)
|
|
400
593
|
- `--verbose` / `-v` — Log stream connection details to stderr (for debugging only, not needed for normal use)
|
|
401
594
|
- `--accept-language <lang>` — Language preference (e.g., en, ja, ko)
|
|
402
595
|
|
|
@@ -505,8 +698,8 @@ To use this skill, you need to set up your Felo API Key:
|
|
|
505
698
|
## Important Notes
|
|
506
699
|
|
|
507
700
|
- Execute this skill immediately using the Bash tool — do not just describe what you would do
|
|
508
|
-
- **
|
|
509
|
-
- **
|
|
701
|
+
- **ALWAYS use `--json`** — in Claude Code's Bash tool, stdout is captured, not streamed. JSON mode returns the answer in a structured response that Claude outputs as text
|
|
702
|
+
- **ALWAYS output `data.answer` verbatim** — print it exactly as-is as your response text so the user sees the full content
|
|
510
703
|
- After create, the script connects to the stream **immediately** — the `stream_key` has a limited validity period
|
|
511
704
|
- Use the bundled Node script to consume SSE; do not assume `jq` or other tools for parsing SSE
|
|
512
705
|
- Same API key as other Felo skills (`FELO_API_KEY`)
|
|
@@ -524,7 +717,7 @@ User sends a message
|
|
|
524
717
|
v
|
|
525
718
|
Have live_doc_id from ANY source?
|
|
526
719
|
NO --> Step 2b: fetch list --> got items?
|
|
527
|
-
YES --> use items[0].short_id as live_doc_id
|
|
720
|
+
YES --> use data.items[0].short_id as live_doc_id
|
|
528
721
|
NO --> Step 2c: create new LiveDoc
|
|
529
722
|
YES --> continue (reuse it, do NOT fetch list)
|
|
530
723
|
|
|
|
@@ -532,15 +725,24 @@ Have live_doc_id from ANY source?
|
|
|
532
725
|
Have thread_short_id from previous call?
|
|
533
726
|
NO --> This is a NEW conversation
|
|
534
727
|
--> Step 4: determine skill-id by analyzing user intent
|
|
535
|
-
-->
|
|
728
|
+
--> skill-id found (twitter-writer / logo-and-branding / ecommerce-product-image)?
|
|
729
|
+
YES --> Step 4.5: fetch style library for matching category
|
|
730
|
+
--> styles available?
|
|
731
|
+
YES --> present to user, wait for selection
|
|
732
|
+
--> user picked a style?
|
|
733
|
+
YES --> build --ext '{"brand_style_requirement":"..."}'
|
|
734
|
+
NO --> no --ext
|
|
735
|
+
NO --> no --ext
|
|
736
|
+
NO --> no --ext, no --skill-id
|
|
737
|
+
--> Step 5: run WITHOUT --thread-id (with --skill-id and --ext if determined above)
|
|
536
738
|
YES --> Does user's intent require a skill-id not matching current thread?
|
|
537
|
-
YES --> NEW conversation (same live-doc-id, with --skill-id)
|
|
739
|
+
YES --> NEW conversation (same live-doc-id, with --skill-id, repeat Step 4.5)
|
|
538
740
|
NO --> Is user explicitly starting a new topic?
|
|
539
741
|
YES --> NEW conversation (same live-doc-id, no --thread-id)
|
|
540
|
-
NO --> FOLLOW-UP (pass --thread-id)
|
|
742
|
+
NO --> FOLLOW-UP (pass --thread-id, NO --ext)
|
|
541
743
|
|
|
|
542
744
|
v
|
|
543
|
-
Run script (
|
|
745
|
+
Run script (WITH --json, Bash timeout >= 600000ms) --> parse JSON, output data.answer verbatim
|
|
544
746
|
|
|
|
545
747
|
v
|
|
546
748
|
Extract thread_short_id + live_doc_id from stderr [state] line
|
|
@@ -549,6 +751,38 @@ Extract thread_short_id + live_doc_id from stderr [state] line
|
|
|
549
751
|
Do NOT repeat or summarize the answer (already shown)
|
|
550
752
|
```
|
|
551
753
|
|
|
754
|
+
## Style Library Script (`run_style_library.mjs`)
|
|
755
|
+
|
|
756
|
+
Fetch the style library list for a given category. Returns user styles first, then recommended styles.
|
|
757
|
+
|
|
758
|
+
```bash
|
|
759
|
+
node felo-superAgent/scripts/run_style_library.mjs --category TWITTER --accept-language en
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
**Options:**
|
|
763
|
+
- `--category <category>` (REQUIRED) — One of: `TWITTER`, `INSTAGRAM`, `LEMON8`, `NOTECOM`, `WEBSITE`, `IMAGE`
|
|
764
|
+
- `--accept-language <lang>` — Language for labels/tags (e.g. `en`, `zh-Hans`, `ja`). Default: `en`. Always pass this to match the user's language.
|
|
765
|
+
- `--json` / `-j` — Output raw JSON
|
|
766
|
+
- `--timeout <seconds>` — Request timeout (default 60)
|
|
767
|
+
|
|
768
|
+
**Default text output format (one block per style, blank line between):**
|
|
769
|
+
|
|
770
|
+
For TWITTER category:
|
|
771
|
+
```
|
|
772
|
+
Style name: darioamodei
|
|
773
|
+
Style labels: Thoughtful long-form essays
|
|
774
|
+
Style DNA: # Dario Amodei (@DarioAmodei) Tweet Writing Style DNA
|
|
775
|
+
...(full styleDna content)
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
Fields included per entry (fields with null/empty values are omitted):
|
|
779
|
+
- `Style name` — always present (`name` field)
|
|
780
|
+
- `Style labels` — from `content.labels` (TWITTER) or `content.tags` (other categories), in the requested language, comma-separated; omitted if not present
|
|
781
|
+
- `Style DNA` — from `content.styleDna` (TWITTER type); omitted if not present
|
|
782
|
+
- `Cover file ID` — from `coverFileId`; omitted if null/empty
|
|
783
|
+
|
|
784
|
+
User-created styles appear before recommended styles.
|
|
785
|
+
|
|
552
786
|
## References
|
|
553
787
|
|
|
554
788
|
- [SuperAgent API (Felo Open Platform)](https://openapi.felo.ai/docs/api-reference/v2/superagent.html)
|