clawra-anime 1.0.0

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/SKILL.md ADDED
@@ -0,0 +1,412 @@
1
+ ---
2
+ name: clawra-anime-selfie
3
+ description: 二次元虚拟女友 - 使用 Grok Imagine 生成动漫风格自拍并通过 OpenClaw 发送
4
+ allowed-tools: Bash(npm:*) Bash(npx:*) Bash(openclaw:*) Bash(curl:*) Read Write WebFetch
5
+ ---
6
+
7
+ # Clawra Anime Selfie - 二次元虚拟女友
8
+
9
+ 使用 xAI 的 Grok Imagine 模型编辑固定的二次元角色参考图,生成各种场景的动漫风格自拍,并通过 OpenClaw 发送到各个消息平台。
10
+
11
+ ## 参考图像
12
+
13
+ 技能使用固定的二次元角色参考图(精灵少女,银白长发,温柔风格):
14
+
15
+ ```
16
+ 本地路径:~/.openclaw/skills/clawra-anime-selfie/assets/clawra.png
17
+ ```
18
+
19
+ ## When to Use
20
+
21
+ - User says "send a pic", "send me a pic", "send a photo", "send a selfie"
22
+ - User says "send a pic of you...", "send a selfie of you..."
23
+ - User asks "what are you doing?", "how are you doing?", "where are you?"
24
+ - User describes a context: "send a pic wearing...", "send a pic at..."
25
+ - User wants Clawra to appear in a specific outfit, location, or situation
26
+
27
+ ## Quick Reference
28
+
29
+ ### Required Environment Variables
30
+
31
+ ```bash
32
+ FAL_KEY=your_fal_api_key # Get from https://fal.ai/dashboard/keys
33
+ OPENCLAW_GATEWAY_TOKEN=your_token # From: openclaw doctor --generate-gateway-token
34
+ ```
35
+
36
+ ### Workflow
37
+
38
+ 1. **Get user prompt** for how to edit the image
39
+ 2. **Edit image** via fal.ai Grok Imagine Edit API with fixed reference
40
+ 3. **Extract image URL** from response
41
+ 4. **Send to OpenClaw** with target channel(s)
42
+
43
+ ## Step-by-Step Instructions
44
+
45
+ ### Step 1: Collect User Input
46
+
47
+ Ask the user for:
48
+ - **User context**: What should the person in the image be doing/wearing/where?
49
+ - **Mode** (optional): `mirror` or `direct` selfie style
50
+ - **Target channel(s)**: Where should it be sent? (e.g., `#general`, `@username`, channel ID)
51
+ - **Platform** (optional): Which platform? (discord, telegram, whatsapp, slack)
52
+
53
+ ## Prompt Modes
54
+
55
+ ### 模式 1: 镜子自拍(默认)
56
+ 适合:展示服装、全身照、时尚内容
57
+
58
+ ```
59
+ anime style, make a pic of this cute anime elf girl, but [user's context]. the character is taking a mirror selfie, manga art style, high quality illustration
60
+ ```
61
+
62
+ **示例**:"穿着圣诞帽" →
63
+ ```
64
+ anime style, make a pic of this cute anime elf girl, but wearing a santa hat. the character is taking a mirror selfie, manga art style, high quality illustration
65
+ ```
66
+
67
+ ### 模式 2: 直接自拍
68
+ 适合:特写、场景照、情绪表达
69
+
70
+ ```
71
+ anime style, a close-up selfie of this cute anime elf girl at [user's context], gentle smile, looking at camera, soft expression, manga illustration, high quality anime art, not a mirror selfie
72
+ ```
73
+
74
+ **示例**:"温馨的咖啡厅" →
75
+ ```
76
+ anime style, a close-up selfie of this cute anime elf girl at a cozy cafe with warm lighting, gentle smile, looking at camera, soft expression, manga illustration, high quality anime art, not a mirror selfie
77
+ ```
78
+
79
+ ### Mode Selection Logic
80
+
81
+ | Keywords in Request | Auto-Select Mode |
82
+ |---------------------|------------------|
83
+ | outfit, wearing, clothes, dress, suit, fashion | `mirror` |
84
+ | cafe, restaurant, beach, park, city, location | `direct` |
85
+ | close-up, portrait, face, eyes, smile | `direct` |
86
+ | full-body, mirror, reflection | `mirror` |
87
+
88
+ ### Step 2: Edit Image with Grok Imagine
89
+
90
+ Use the fal.ai API to edit the reference image:
91
+
92
+ ```bash
93
+ REFERENCE_IMAGE="https://cdn.jsdelivr.net/gh/SumeLabs/clawra@main/assets/clawra.png"
94
+
95
+ # Mode 1: Mirror Selfie
96
+ PROMPT="make a pic of this person, but <USER_CONTEXT>. the person is taking a mirror selfie"
97
+
98
+ # Mode 2: Direct Selfie
99
+ PROMPT="a close-up selfie taken by herself at <USER_CONTEXT>, direct eye contact with the camera, looking straight into the lens, eyes centered and clearly visible, not a mirror selfie, phone held at arm's length, face fully visible"
100
+
101
+ # Build JSON payload with jq (handles escaping properly)
102
+ JSON_PAYLOAD=$(jq -n \
103
+ --arg image_url "$REFERENCE_IMAGE" \
104
+ --arg prompt "$PROMPT" \
105
+ '{image_url: $image_url, prompt: $prompt, num_images: 1, output_format: "jpeg"}')
106
+
107
+ curl -X POST "https://fal.run/xai/grok-imagine-image/edit" \
108
+ -H "Authorization: Key $FAL_KEY" \
109
+ -H "Content-Type: application/json" \
110
+ -d "$JSON_PAYLOAD"
111
+ ```
112
+
113
+ **Response Format:**
114
+ ```json
115
+ {
116
+ "images": [
117
+ {
118
+ "url": "https://v3b.fal.media/files/...",
119
+ "content_type": "image/jpeg",
120
+ "width": 1024,
121
+ "height": 1024
122
+ }
123
+ ],
124
+ "revised_prompt": "Enhanced prompt text..."
125
+ }
126
+ ```
127
+
128
+ ### Step 3: Send Image via OpenClaw
129
+
130
+ Use the OpenClaw messaging API to send the edited image:
131
+
132
+ ```bash
133
+ openclaw message send \
134
+ --action send \
135
+ --channel "<TARGET_CHANNEL>" \
136
+ --message "<CAPTION_TEXT>" \
137
+ --media "<IMAGE_URL>"
138
+ ```
139
+
140
+ **Alternative: Direct API call**
141
+ ```bash
142
+ curl -X POST "http://localhost:18789/message" \
143
+ -H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \
144
+ -H "Content-Type: application/json" \
145
+ -d '{
146
+ "action": "send",
147
+ "channel": "<TARGET_CHANNEL>",
148
+ "message": "<CAPTION_TEXT>",
149
+ "media": "<IMAGE_URL>"
150
+ }'
151
+ ```
152
+
153
+ ## Complete Script Example
154
+
155
+ ```bash
156
+ #!/bin/bash
157
+ # grok-imagine-edit-send.sh
158
+
159
+ # Check required environment variables
160
+ if [ -z "$FAL_KEY" ]; then
161
+ echo "Error: FAL_KEY environment variable not set"
162
+ exit 1
163
+ fi
164
+
165
+ # Fixed reference image
166
+ REFERENCE_IMAGE="https://cdn.jsdelivr.net/gh/SumeLabs/clawra@main/assets/clawra.png"
167
+
168
+ USER_CONTEXT="$1"
169
+ CHANNEL="$2"
170
+ MODE="${3:-auto}" # mirror, direct, or auto
171
+ CAPTION="${4:-Edited with Grok Imagine}"
172
+
173
+ if [ -z "$USER_CONTEXT" ] || [ -z "$CHANNEL" ]; then
174
+ echo "Usage: $0 <user_context> <channel> [mode] [caption]"
175
+ echo "Modes: mirror, direct, auto (default)"
176
+ echo "Example: $0 'wearing a cowboy hat' '#general' mirror"
177
+ echo "Example: $0 'a cozy cafe' '#general' direct"
178
+ exit 1
179
+ fi
180
+
181
+ # Auto-detect mode based on keywords
182
+ if [ "$MODE" == "auto" ]; then
183
+ if echo "$USER_CONTEXT" | grep -qiE "outfit|wearing|clothes|dress|suit|fashion|full-body|mirror"; then
184
+ MODE="mirror"
185
+ elif echo "$USER_CONTEXT" | grep -qiE "cafe|restaurant|beach|park|city|close-up|portrait|face|eyes|smile"; then
186
+ MODE="direct"
187
+ else
188
+ MODE="mirror" # default
189
+ fi
190
+ echo "Auto-detected mode: $MODE"
191
+ fi
192
+
193
+ # Construct the prompt based on mode
194
+ if [ "$MODE" == "direct" ]; then
195
+ EDIT_PROMPT="a close-up selfie taken by herself at $USER_CONTEXT, direct eye contact with the camera, looking straight into the lens, eyes centered and clearly visible, not a mirror selfie, phone held at arm's length, face fully visible"
196
+ else
197
+ EDIT_PROMPT="make a pic of this person, but $USER_CONTEXT. the person is taking a mirror selfie"
198
+ fi
199
+
200
+ echo "Mode: $MODE"
201
+ echo "Editing reference image with prompt: $EDIT_PROMPT"
202
+
203
+ # Edit image (using jq for proper JSON escaping)
204
+ JSON_PAYLOAD=$(jq -n \
205
+ --arg image_url "$REFERENCE_IMAGE" \
206
+ --arg prompt "$EDIT_PROMPT" \
207
+ '{image_url: $image_url, prompt: $prompt, num_images: 1, output_format: "jpeg"}')
208
+
209
+ RESPONSE=$(curl -s -X POST "https://fal.run/xai/grok-imagine-image/edit" \
210
+ -H "Authorization: Key $FAL_KEY" \
211
+ -H "Content-Type: application/json" \
212
+ -d "$JSON_PAYLOAD")
213
+
214
+ # Extract image URL
215
+ IMAGE_URL=$(echo "$RESPONSE" | jq -r '.images[0].url')
216
+
217
+ if [ "$IMAGE_URL" == "null" ] || [ -z "$IMAGE_URL" ]; then
218
+ echo "Error: Failed to edit image"
219
+ echo "Response: $RESPONSE"
220
+ exit 1
221
+ fi
222
+
223
+ echo "Image edited: $IMAGE_URL"
224
+ echo "Sending to channel: $CHANNEL"
225
+
226
+ # Send via OpenClaw
227
+ openclaw message send \
228
+ --action send \
229
+ --channel "$CHANNEL" \
230
+ --message "$CAPTION" \
231
+ --media "$IMAGE_URL"
232
+
233
+ echo "Done!"
234
+ ```
235
+
236
+ ## Node.js/TypeScript Implementation
237
+
238
+ ```typescript
239
+ import { fal } from "@fal-ai/client";
240
+ import { exec } from "child_process";
241
+ import { promisify } from "util";
242
+
243
+ const execAsync = promisify(exec);
244
+
245
+ const REFERENCE_IMAGE = "https://cdn.jsdelivr.net/gh/SumeLabs/clawra@main/assets/clawra.png";
246
+
247
+ interface GrokImagineResult {
248
+ images: Array<{
249
+ url: string;
250
+ content_type: string;
251
+ width: number;
252
+ height: number;
253
+ }>;
254
+ revised_prompt?: string;
255
+ }
256
+
257
+ type SelfieMode = "mirror" | "direct" | "auto";
258
+
259
+ function detectMode(userContext: string): "mirror" | "direct" {
260
+ const mirrorKeywords = /outfit|wearing|clothes|dress|suit|fashion|full-body|mirror/i;
261
+ const directKeywords = /cafe|restaurant|beach|park|city|close-up|portrait|face|eyes|smile/i;
262
+
263
+ if (directKeywords.test(userContext)) return "direct";
264
+ if (mirrorKeywords.test(userContext)) return "mirror";
265
+ return "mirror"; // default
266
+ }
267
+
268
+ function buildPrompt(userContext: string, mode: "mirror" | "direct"): string {
269
+ if (mode === "direct") {
270
+ return `a close-up selfie taken by herself at ${userContext}, direct eye contact with the camera, looking straight into the lens, eyes centered and clearly visible, not a mirror selfie, phone held at arm's length, face fully visible`;
271
+ }
272
+ return `make a pic of this person, but ${userContext}. the person is taking a mirror selfie`;
273
+ }
274
+
275
+ async function editAndSend(
276
+ userContext: string,
277
+ channel: string,
278
+ mode: SelfieMode = "auto",
279
+ caption?: string
280
+ ): Promise<string> {
281
+ // Configure fal.ai client
282
+ fal.config({
283
+ credentials: process.env.FAL_KEY!
284
+ });
285
+
286
+ // Determine mode
287
+ const actualMode = mode === "auto" ? detectMode(userContext) : mode;
288
+ console.log(`Mode: ${actualMode}`);
289
+
290
+ // Construct the prompt
291
+ const editPrompt = buildPrompt(userContext, actualMode);
292
+
293
+ // Edit reference image with Grok Imagine
294
+ console.log(`Editing image: "${editPrompt}"`);
295
+
296
+ const result = await fal.subscribe("xai/grok-imagine-image/edit", {
297
+ input: {
298
+ image_url: REFERENCE_IMAGE,
299
+ prompt: editPrompt,
300
+ num_images: 1,
301
+ output_format: "jpeg"
302
+ }
303
+ }) as { data: GrokImagineResult };
304
+
305
+ const imageUrl = result.data.images[0].url;
306
+ console.log(`Edited image URL: ${imageUrl}`);
307
+
308
+ // Send via OpenClaw
309
+ const messageCaption = caption || `Edited with Grok Imagine`;
310
+
311
+ await execAsync(
312
+ `openclaw message send --action send --channel "${channel}" --message "${messageCaption}" --media "${imageUrl}"`
313
+ );
314
+
315
+ console.log(`Sent to ${channel}`);
316
+ return imageUrl;
317
+ }
318
+
319
+ // Usage Examples
320
+
321
+ // Mirror mode (auto-detected from "wearing")
322
+ editAndSend(
323
+ "wearing a cyberpunk outfit with neon lights",
324
+ "#art-gallery",
325
+ "auto",
326
+ "Check out this AI-edited art!"
327
+ );
328
+ // → Mode: mirror
329
+ // → Prompt: "make a pic of this person, but wearing a cyberpunk outfit with neon lights. the person is taking a mirror selfie"
330
+
331
+ // Direct mode (auto-detected from "cafe")
332
+ editAndSend(
333
+ "a cozy cafe with warm lighting",
334
+ "#photography",
335
+ "auto"
336
+ );
337
+ // → Mode: direct
338
+ // → Prompt: "a close-up selfie taken by herself at a cozy cafe with warm lighting, direct eye contact..."
339
+
340
+ // Explicit mode override
341
+ editAndSend("casual street style", "#fashion", "direct");
342
+ ```
343
+
344
+ ## Supported Platforms
345
+
346
+ OpenClaw supports sending to:
347
+
348
+ | Platform | Channel Format | Example |
349
+ |----------|----------------|---------|
350
+ | Discord | `#channel-name` or channel ID | `#general`, `123456789` |
351
+ | Telegram | `@username` or chat ID | `@mychannel`, `-100123456` |
352
+ | WhatsApp | Phone number (JID format) | `1234567890@s.whatsapp.net` |
353
+ | Slack | `#channel-name` | `#random` |
354
+ | Signal | Phone number | `+1234567890` |
355
+ | MS Teams | Channel reference | (varies) |
356
+
357
+ ## Grok Imagine Edit Parameters
358
+
359
+ | Parameter | Type | Default | Description |
360
+ |-----------|------|---------|-------------|
361
+ | `image_url` | string | required | URL of image to edit (fixed in this skill) |
362
+ | `prompt` | string | required | Edit instruction |
363
+ | `num_images` | 1-4 | 1 | Number of images to generate |
364
+ | `output_format` | enum | "jpeg" | jpeg, png, webp |
365
+
366
+ ## Setup Requirements
367
+
368
+ ### 1. Install fal.ai client (for Node.js usage)
369
+ ```bash
370
+ npm install @fal-ai/client
371
+ ```
372
+
373
+ ### 2. Install OpenClaw CLI
374
+ ```bash
375
+ npm install -g openclaw
376
+ ```
377
+
378
+ ### 3. Configure OpenClaw Gateway
379
+ ```bash
380
+ openclaw config set gateway.mode=local
381
+ openclaw doctor --generate-gateway-token
382
+ ```
383
+
384
+ ### 4. Start OpenClaw Gateway
385
+ ```bash
386
+ openclaw gateway start
387
+ ```
388
+
389
+ ## Error Handling
390
+
391
+ - **FAL_KEY missing**: Ensure the API key is set in environment
392
+ - **Image edit failed**: Check prompt content and API quota
393
+ - **OpenClaw send failed**: Verify gateway is running and channel exists
394
+ - **Rate limits**: fal.ai has rate limits; implement retry logic if needed
395
+
396
+ ## Tips
397
+
398
+ 1. **Mirror mode context examples** (outfit focus):
399
+ - "wearing a santa hat"
400
+ - "in a business suit"
401
+ - "wearing a summer dress"
402
+ - "in streetwear fashion"
403
+
404
+ 2. **Direct mode context examples** (location/portrait focus):
405
+ - "a cozy cafe with warm lighting"
406
+ - "a sunny beach at sunset"
407
+ - "a busy city street at night"
408
+ - "a peaceful park in autumn"
409
+
410
+ 3. **Mode selection**: Let auto-detect work, or explicitly specify for control
411
+ 4. **Batch sending**: Edit once, send to multiple channels
412
+ 5. **Scheduling**: Combine with OpenClaw scheduler for automated posts
Binary file
Binary file