277 lines
13 KiB
Markdown
277 lines
13 KiB
Markdown
---
|
||
name: sn-image-base
|
||
description: |
|
||
Base-layer skill for the SenseNova-Skills project, providing low-level APIs for image generation, recognition (VLM), and text optimization (LLM).
|
||
This skill does not preprocess inputs; it only calls backend services and returns results.
|
||
This skill is not user-facing and is intended for upper-layer skills only.
|
||
triggers:
|
||
- "SenseNova-Skills Image Generation"
|
||
- "SenseNova-Skills 图像基础工具"
|
||
- "sn 图像基础工具"
|
||
- "SenseNova 图像基础工具"
|
||
- "SenseNova Image Generation"
|
||
- "sn-image-base"
|
||
metadata:
|
||
project: SenseNova-Skills
|
||
tier: 0
|
||
category: infrastructure
|
||
user_visible: false
|
||
---
|
||
|
||
# sn-image-base
|
||
|
||
## Dependency Installation
|
||
|
||
```bash
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
## Overview
|
||
|
||
`sn-image-base` is the base-layer skill (tier 0) of the SenseNova-Skills project and provides three low-level tools:
|
||
|
||
- `sn-image-generate`: image generation (calls text-to-image-no-enhance API)
|
||
- `sn-image-recognize`: image recognition (uses VLM to analyze image content)
|
||
- `sn-text-optimize`: text optimization (uses LLM to process text)
|
||
|
||
This skill **does not perform any input preprocessing** and only calls backend services to return results.
|
||
|
||
## Tools List
|
||
|
||
### sn-image-generate
|
||
|
||
Image generation tool that calls the text-to-image-no-enhance API.
|
||
|
||
`--prompt` is required; all other parameters are optional:
|
||
|
||
| Parameter | Type | Default | Description |
|
||
|------|------|--------|------|
|
||
| `--prompt` | string | **Required** | Prompt text for image generation |
|
||
| `--negative-prompt` | string | `""` | Negative prompt |
|
||
| `--image-size` | string | `2k` | Image size preset, supports `2k` only |
|
||
| `--aspect-ratio` | string | `16:9` | Aspect ratio, e.g. `1:1`, `16:9`, `9:16` |
|
||
| `--seed` | int | `None` | Random seed for reproducible generation |
|
||
| `--unet-name` | string | `None` | Specify a UNet model name |
|
||
| `--api-key` | string | `SN_IMAGE_GEN_API_KEY` -> `SN_API_KEY` | API key (CLI argument has priority; `MissingApiKeyError` is raised when all are empty) |
|
||
| `--base-url` | string | `SN_IMAGE_GEN_BASE_URL` -> `SN_BASE_URL` | API base URL (CLI argument has priority) |
|
||
| `--poll-interval` | float | `5.0` | Polling interval (seconds) |
|
||
| `--timeout` | float | `300.0` | Timeout (seconds) |
|
||
| `--insecure` | flag | `False` | Disable TLS verification |
|
||
| `--save-path` | Path | Auto-generated | Save path |
|
||
|
||
### sn-image-recognize
|
||
|
||
Image recognition tool that uses VLM (Vision Language Model) to analyze image content. Supports multiple image inputs.
|
||
|
||
`--images` and `--user-prompt` (or `--user-prompt-path`) are required. All other parameters use three-level defaults (CLI > env var > built-in default):
|
||
|
||
| Parameter | Type | Built-in Default | Env Var | Description |
|
||
|------|------|-----------|---------|------|
|
||
| `--api-key` | string | No hardcoded default | `SN_VISION_API_KEY` -> `SN_CHAT_API_KEY` -> `SN_API_KEY` | Chat runtime API key; raises `MissingApiKeyError` when all are unset |
|
||
| `--base-url` | string | `SN_CHAT_BASE_URL` default | `SN_VISION_BASE_URL` -> `SN_CHAT_BASE_URL` -> `SN_BASE_URL` | Vision provider base URL; falls back to shared chat/global provider |
|
||
| `--model` | string | `sensenova-6.7-flash-lite` | `SN_VISION_MODEL` -> `SN_CHAT_MODEL` | Vision-capable model name |
|
||
| `--vlm-type` | string | `openai-completions` | `SN_VISION_TYPE` -> `SN_CHAT_TYPE` | Chat protocol type override |
|
||
| `--user-prompt-path` | string | `None` | - | Local file path, mutually exclusive with `--user-prompt` |
|
||
| `--system-prompt-path` | string | `None` | - | Local file path, mutually exclusive with `--system-prompt` |
|
||
|
||
Available values for `--vlm-type`:
|
||
|
||
- `openai-completions`: OpenAI-compatible `/v1/chat/completions` interface
|
||
- `anthropic-messages`: Anthropic Messages `/v1/messages` interface
|
||
|
||
### sn-text-optimize
|
||
|
||
Text optimization tool that uses LLM (Language Model) to optimize text content. Does not accept image inputs.
|
||
|
||
`--user-prompt` (or `--user-prompt-path`) is required. All other parameters use three-level defaults (CLI > env var > built-in default):
|
||
|
||
| Parameter | Type | Built-in Default | Env Var | Description |
|
||
|------|------|-----------|---------|------|
|
||
| `--api-key` | string | No hardcoded default | `SN_TEXT_API_KEY` -> `SN_CHAT_API_KEY` -> `SN_API_KEY` | Chat runtime API key; raises `MissingApiKeyError` when all are unset |
|
||
| `--base-url` | string | `SN_CHAT_BASE_URL` default | `SN_TEXT_BASE_URL` -> `SN_CHAT_BASE_URL` -> `SN_BASE_URL` | Text provider base URL; falls back to shared chat/global provider |
|
||
| `--model` | string | `sensenova-6.7-flash-lite` | `SN_TEXT_MODEL` -> `SN_CHAT_MODEL` | Text model name |
|
||
| `--llm-type` | string | `openai-completions` | `SN_TEXT_TYPE` -> `SN_CHAT_TYPE` | Chat protocol type override |
|
||
| `--user-prompt-path` | string | `None` | - | Local file path, mutually exclusive with `--user-prompt` |
|
||
| `--system-prompt-path` | string | `None` | - | Local file path, mutually exclusive with `--system-prompt` |
|
||
|
||
Available values for `--llm-type`:
|
||
|
||
- `openai-completions`: OpenAI-compatible `/v1/chat/completions` interface
|
||
- `anthropic-messages`: Anthropic Messages `/v1/messages` interface
|
||
|
||
## VLM vs LLM
|
||
|
||
| Tool | Model Type | Image Input | Interface Type Parameter |
|
||
|------|----------|-----------------|-------------|
|
||
| `sn-image-recognize` | VLM (Vision Language Model) | Yes, supports multiple images | `--vlm-type` |
|
||
| `sn-text-optimize` | LLM (Language Model) | No, text only | `--llm-type` |
|
||
|
||
## Usage
|
||
|
||
All tools are called through the unified `sn_agent_runner.py` entrypoint:
|
||
|
||
```bash
|
||
# Image generation (only prompt required; api-key/base-url have defaults)
|
||
python scripts/sn_agent_runner.py sn-image-generate \
|
||
--prompt "..."
|
||
|
||
# Image generation (override base-url)
|
||
python scripts/sn_agent_runner.py sn-image-generate \
|
||
--prompt "..." \
|
||
--base-url "https://custom-endpoint.com/v1"
|
||
|
||
# Image generation (explicitly override api-key)
|
||
python scripts/sn_agent_runner.py sn-image-generate \
|
||
--prompt "..." \
|
||
--api-key "sk-xxx"
|
||
|
||
# Image recognition (VLM) - minimal call (uses built-in Sensenova defaults)
|
||
python scripts/sn_agent_runner.py sn-image-recognize \
|
||
--user-prompt "Describe the image" \
|
||
--images "path/to/image.png"
|
||
|
||
# Image recognition (VLM) - override to Anthropic Claude API compatible (messages interface)
|
||
python scripts/sn_agent_runner.py sn-image-recognize \
|
||
--user-prompt "Describe the image" \
|
||
--images "path/to/image.png" \
|
||
--api-key "sk-ant-xxx" \
|
||
--base-url "https://api.anthropic.com" \
|
||
--model "claude-sonnet-4-6" \
|
||
--vlm-type "anthropic-messages"
|
||
|
||
# Text optimization (LLM) - minimal call (uses built-in Sensenova defaults)
|
||
python scripts/sn_agent_runner.py sn-text-optimize \
|
||
--user-prompt "Optimize the text: ..."
|
||
|
||
# Text optimization (LLM) - override to Anthropic Claude API compatible (messages interface)
|
||
python scripts/sn_agent_runner.py sn-text-optimize \
|
||
--user-prompt "Optimize the text: ..." \
|
||
--api-key "sk-ant-xxx" \
|
||
--base-url "https://api.anthropic.com" \
|
||
--model "claude-sonnet-4-6" \
|
||
--llm-type "anthropic-messages"
|
||
```
|
||
|
||
### Default Parameter Behavior
|
||
|
||
Authentication parameters for `sn-image-generate` have the following default behavior:
|
||
|
||
| Parameter | Default | Override | Description |
|
||
|------|--------|----------|------|
|
||
| `--base-url` | `SN_IMAGE_GEN_BASE_URL` -> `SN_BASE_URL` | `--base-url "..."` | CLI argument has priority |
|
||
| `--api-key` | `SN_IMAGE_GEN_API_KEY` -> `SN_API_KEY` | `--api-key "..."` | CLI argument has priority; throws `MissingApiKeyError` if all values are empty |
|
||
|
||
`sn-image-recognize` and `sn-text-optimize` use priority: **CLI argument > command-specific env var > shared `SN_CHAT_*` env var > global `SN_*` env var > built-in default**.
|
||
|
||
| Parameter | Built-in Default | Vision Env Var | Text Env Var |
|
||
|------|-----------|-------------|-------------|
|
||
| `--api-key` | None (must be provided) | `SN_VISION_API_KEY` -> `SN_CHAT_API_KEY` -> `SN_API_KEY` | `SN_TEXT_API_KEY` -> `SN_CHAT_API_KEY` -> `SN_API_KEY` |
|
||
| `--base-url` | `https://token.sensenova.cn/v1` | `SN_VISION_BASE_URL` -> `SN_CHAT_BASE_URL` -> `SN_BASE_URL` | `SN_TEXT_BASE_URL` -> `SN_CHAT_BASE_URL` -> `SN_BASE_URL` |
|
||
| `--model` | `sensenova-6.7-flash-lite` | `SN_VISION_MODEL` -> `SN_CHAT_MODEL` | `SN_TEXT_MODEL` -> `SN_CHAT_MODEL` |
|
||
| `--vlm-type` / `--llm-type` | `openai-completions` | `SN_VISION_TYPE` -> `SN_CHAT_TYPE` | `SN_TEXT_TYPE` -> `SN_CHAT_TYPE` |
|
||
|
||
`api_key` resolution order (high to low): CLI `--api-key` > command-specific key (`SN_VISION_API_KEY`/`SN_TEXT_API_KEY`) > `SN_CHAT_API_KEY` > `SN_API_KEY`. If all are unset, `MissingApiKeyError` is raised.
|
||
|
||
Only `--api-key` must be provided via CLI or environment; base URL, model, and interface type have shared chat defaults.
|
||
|
||
## Agent Configuration Integration
|
||
|
||
The agent can automatically read parameters from `openclaw.json` without manual input:
|
||
|
||
| CLI Parameter | openclaw.json Field | Example |
|
||
|-----------|-------------------|--------|
|
||
| `--base-url` | `providers.<name>.baseUrl` | `https://api.anthropic.com` |
|
||
| `--llm-type` | `providers.<name>.api` | `anthropic-messages` / `openai-completions` |
|
||
| `--vlm-type` | `providers.<name>.api` | `anthropic-messages` / `openai-completions` |
|
||
| `--model` | `providers.<name>.models[].id` | `claude-sonnet-4-6` |
|
||
| `--api-key` | `providers.<name>.apiKey` or env var | `sk-cp-...` |
|
||
|
||
Note: `--llm-type` and `--vlm-type` share the same `providers.<name>.api` field and are used by LLM and VLM tools respectively.
|
||
|
||
Mapping between `provider.api` and interface type:
|
||
|
||
| api Value | Corresponding `--llm-type` / `--vlm-type` | Endpoint Path |
|
||
|--------|----------------------------------|---------------|
|
||
| `anthropic-messages` | `anthropic-messages` | `/v1/messages` |
|
||
| `openai-completions` | `openai-completions` | `/v1/chat/completions` |
|
||
| `openai-responses` | (future extension) | `/responses` |
|
||
|
||
## Mapping Between base-url and Interface Type
|
||
|
||
Different API types have different requirements for base-url format:
|
||
|
||
| Type | `--llm-type` / `--vlm-type` | Recommended base-url | Code Appended Path | Final URL Example |
|
||
|------|------------------------------|---------------|--------------|---------------|
|
||
| LLM | `openai-completions` | `https://token.sensenova.cn/v1` | `/chat/completions` | `https://token.sensenova.cn/v1/chat/completions` |
|
||
| LLM | `anthropic-messages` | `https://api.anthropic.com/v1` | `/messages` | `https://api.anthropic.com/v1/messages` |
|
||
| VLM | `openai-completions` | `https://token.sensenova.cn/v1` | `/chat/completions` | `https://token.sensenova.cn/v1/chat/completions` |
|
||
| VLM | `anthropic-messages` | `https://api.anthropic.com/v1` | `/messages` | `https://api.anthropic.com/v1/messages` |
|
||
|
||
**Note**:
|
||
|
||
- Recommended chat base URLs include the provider API version path, for example `/v1`.
|
||
- For compatibility, if the configured chat base URL has no path, the runner appends `/v1/chat/completions` or `/v1/messages`.
|
||
- If the configured chat base URL already has a path such as `/v1`, the runner appends only `/chat/completions` or `/messages`.
|
||
- Some providers use versioned paths other than `/v1`, such as Gemini's `/v1beta/openai`.
|
||
|
||
## Output Format
|
||
|
||
All tools support two output formats:
|
||
|
||
- `--output-format text` (default): outputs plain text result
|
||
- `--output-format json`: outputs JSON, including `status` and `elapsed_seconds` (runtime in seconds, rounded to 2 decimals)
|
||
|
||
JSON output for `sn-image-recognize` and `sn-text-optimize` also includes `model`, `base_url`, and `interface_type` to verify the effective runtime configuration:
|
||
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"result": "...",
|
||
"model": "sensenova-6.7-flash-lite",
|
||
"base_url": "https://token.sensenova.cn/v1",
|
||
"interface_type": "openai-completions",
|
||
"elapsed_seconds": 1.23
|
||
}
|
||
```
|
||
|
||
On failure:
|
||
|
||
```json
|
||
{
|
||
"status": "failed",
|
||
"error": "error message",
|
||
"elapsed_seconds": 0.05
|
||
}
|
||
```
|
||
|
||
## Input/Output Specification
|
||
|
||
See `references/api_spec.md` for details.
|
||
|
||
|
||
---
|
||
|
||
> ⚠️ **厂商绑定**:此 skill 绑定 SenseNova 专用 API(图像生成、识别、文本优化),无法替换为其他模型。如果 SenseNova 不再免费或无 plan,此 skill 将不可用。
|
||
>
|
||
**依赖**: SN_API_KEY (SenseNova 平台 API key), Pillow (`~/.hermes/hermes-agent/venv/bin/pip3 install Pillow`)
|
||
**配置参考**: `references/sensenova-config.md`
|
||
**可替代方案**: comfyui (本地图像生成) + mmx vision (图像理解)
|
||
|
||
## Pitfalls
|
||
|
||
### Pillow 依赖未安装
|
||
**Symptom**: `ModuleNotFoundError: No module named 'PIL'`
|
||
**Root cause**: sn-image-generate 使用 PIL 处理图像,但系统 Python 或 venv 中未安装 Pillow。
|
||
**Fix**: `pip install Pillow`(如果使用 hermes-agent 的 venv,需要用 `~/.hermes/hermes-agent/venv/bin/pip3 install Pillow`)。
|
||
**Note**: hermes-agent 的 Python 路径是 `~/.hermes/hermes-agent/venv/bin/python3`,不是系统 python3。
|
||
|
||
### API 限流策略
|
||
SenseNova 的限流是按 **5 小时窗口**计算,不是按分钟:
|
||
- sensenova-6.7-flash-lite: 1500 次/5小时
|
||
- sensenova-u1-fast: 1500 次/5小时
|
||
- deepseek-v4-flash: 150 次/5小时(最严)
|
||
|
||
### Base URL
|
||
所有 SenseNova 模型统一使用: `https://token.sensenova.cn/v1`
|
||
|