Generate photos where your OpenClaw character looks the same every time — selfies, group shots,
portraits, stylized scenes, and more — all through tuqu.ai's image generation API. The skill handles
character identity preservation, prompt enhancement, preset application, balance management, and
billing.
clawhub install openclaw-selfie
Or with the native OpenClaw command:
openclaw skills install openclaw-selfie
python3 in PATH). its own key — the skill passes it explicitly per request via --service-key.
After installation, verify the skill is working:
# Check that the helper script runs
python3 scripts/tuqu_request.py GET /api/catalog --query type=all
# Check available models and pricing
python3 scripts/tuqu_request.py GET /api/pricing-config
If both commands return JSON, the skill is ready. Authenticated calls (generation, balance, etc.)
also require --service-key .
Only set these when you need to point at a non-default host:
TUQU_BASE_URL — defaults to https://photo.tuqu.aiTUQU_BILLING_BASE_URL — defaults to https://billing.tuqu.ai/dream-weaverAll API calls go through scripts/tuqu_request.py. The helper auto-selects the correct host and
auth mode for each endpoint, keeps credentials explicit via --service-key, and prints formatted
JSON for direct inspection.
Detailed API semantics are in TUQU_API.md. Exact request/response fields are in
references/endpoints.md and task sequences in
Authenticated calls must pass --service-key explicitly on every request. Do not
rely on a shared credential environment variable — different OpenClaw roles can carry different keys.
List or query data:
python3 scripts/tuqu_request.py GET /api/catalog --query type=all
python3 scripts/tuqu_request.py GET /api/model-costs
python3 scripts/tuqu_request.py GET /api/pricing-config
Send a small JSON body inline:
python3 scripts/tuqu_request.py POST /api/enhance-prompt \
--json '{"category":"portrait","prompt":"soft editorial portrait with window light"}'
Send a larger payload from disk:
python3 scripts/tuqu_request.py POST /api/v2/generate-image \
--service-key <role-service-key> \
--body-file payloads/generate-image.json
Override helper defaults only with a documented reason:
python3 scripts/tuqu_request.py POST /api/custom-path \
--base-url https://photo.tuqu.ai \
--auth-mode user-key \
--service-key <role-service-key> \
--json '{"prompt":"example"}'
Before picking an endpoint, classify the user request into one of these buckets:
自拍, 照片, 写真, 发张图, or similar wording that implies the current role should be in frame
the user explicitly wants the current role or a saved character to appear in the image
landscape, objects, scenery, atmosphere shots, or pure image editing without the current role
If the request is ambiguous, decide whether the current role needs to appear in the final image.
自拍 as current-role-on-camera by default.自拍 means the current role appears in the image. It does not mean a phone must be visible.current role into the frame.
image.
Use identity-preserving routing when the current role must appear:
POST /api/v2/generate-for-characterPOST /api/v2/generate-imageKeep all supported calls on scripts/tuqu_request.py.
When the current role must appear in the frame, enforce this order:
/api/characters./api/billing/balance./api/v2/generate-for-character.Helper sequence:
python3 scripts/tuqu_request.py GET /api/characters --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/characters \
--service-key <role-service-key> \
--body-file payloads/create-character.json
python3 scripts/tuqu_request.py POST /api/billing/balance --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/v2/generate-for-character \
--service-key <role-service-key> \
--body-file payloads/generate-for-character.json
Use the create-character step only when the current role does not already have a usable Tuqu
character.
framing.
自拍 or 发张图, assume the goal is a natural current-role portrait ratherthan a literal handheld-phone shot.
python3 scripts/tuqu_request.py GET /api/catalog --query type=all
python3 scripts/tuqu_request.py GET /api/model-costs
python3 scripts/tuqu_request.py GET /api/pricing-config
Use /api/pricing-config before accepting a user-supplied model name. Match the requested model
to a real models[].id, then use that modelId in later generation payloads.
python3 scripts/tuqu_request.py POST /api/enhance-prompt \
--json '{"category":"portrait","prompt":"soft editorial portrait with window light"}'
python3 scripts/tuqu_request.py POST /api/v2/generate-image \
--service-key <role-service-key> \
--body-file payloads/generate-image.json
Example payloads/generate-image.json:
{
"prompt": "cinematic portrait in warm sunset light",
"referenceImageUrls": ["https://example.com/reference.jpg"],
"resolution": "2K",
"ratio": "Original",
"modelId": "seedream45"
}
python3 scripts/tuqu_request.py GET /api/catalog --query type=all
python3 scripts/tuqu_request.py POST /api/v2/apply-preset \
--service-key <role-service-key> \
--body-file payloads/apply-preset.json
python3 scripts/tuqu_request.py GET /api/characters --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/characters \
--service-key <role-service-key> \
--body-file payloads/create-character.json
python3 scripts/tuqu_request.py PUT /api/characters/<character-id> \
--service-key <role-service-key> \
--body-file payloads/update-character.json
python3 scripts/tuqu_request.py DELETE /api/characters/<character-id> \
--service-key <role-service-key>
python3 scripts/tuqu_request.py GET /api/characters --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/billing/balance --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/v2/generate-for-character \
--service-key <role-service-key> \
--body-file payloads/generate-for-character.json
Optionally refine the scene prompt first with /api/enhance-prompt. When the request is a selfie
or other current-role portrait, make sure the character check and balance check happen before the
generation call.
python3 scripts/tuqu_request.py GET /api/history --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/history \
--service-key <role-service-key> \
--body-file payloads/history-item.json
python3 scripts/tuqu_request.py DELETE /api/history/<history-id> --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/billing/balance --service-key <role-service-key>
python3 scripts/tuqu_request.py GET /api/v1/recharge/plans --service-key <role-service-key>
python3 scripts/tuqu_request.py POST /api/v1/recharge/wechat \
--service-key <role-service-key> \
--json '{"planId":"698b7fead4c733c85f2a9c74"}'
python3 scripts/tuqu_request.py POST /api/v1/recharge/stripe \
--service-key <role-service-key> \
--json '{"planId":"698b7fead4c733c85f2a9c74","successUrl":"https://your-app.com/payment/success","cancelUrl":"https://your-app.com/payment/cancel"}'
scripts/tuqu_request.py instead of ad-hoc curl for supported endpoints.freestyle/edit-only.
/api/v2/generate-for-character./api/v2/generate-image.then generate.
--service-key on every authenticated helper call.--body-file for large JSON payloads, especially generation and preset payloads./api/catalog as the source of truth for presetId, preset type, and preset variables./api/pricing-config to resolve user-supplied model names before setting modelId.自拍 as front-camera composition with the current role visible and the phone notvisible unless explicitly requested.
image.
共 1 个版本