Install
openclaw skills install ssy-batchjob-async-jobUse BatchJob HTTP APIs for strict upload validation, precheck, submit, polling, and cancellation. Full-auto file source resolution (file_id/local path/public...
openclaw skills install ssy-batchjob-async-jobUse this skill when the user wants to run or manage batch jobs through the BatchJob service.
BATCHJOB_BASE_URLBATCHJOB_BEARER_TOKENAll HTTP requests must include:
-H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}"
-H "Content-Type: application/json"
POST /v1/batch/files:uploadPOST /v1/batch/jobs:precheckPOST /v1/batch/jobsGET /v1/batch/jobs/{job_id}GET /v1/batch/jobs?page=1&page_size=10&status=...POST /v1/batch/jobs/{job_id}:cancelfile_id first.jsonl, csv, xlsx, xls (BatchJob normalizes to internal JSONL).jsonl, each line must be either:
contents + optional generationConfig)prompt + optional aspect_ratio / image_urls, where image_urls must be publicly reachable URLs)model mode after a file message, treat it as confirmation and continue automatically.row_count <= 0.output_summary_url automatically; only do it when user asks for detailed failure reason.completed, failed, partially_failed), stop execution and return summary immediately.BatchJob internal execution expects each JSONL line to be a VertexGeminiImageRequest shape.
contents[0].parts[0].text contains prompt textgenerationConfig.imageConfig.aspectRatio is optionalgenerationConfig.responseModalities should include IMAGE and TEXT{"prompt":"...","aspect_ratio":"1:1"} is acceptable; server will normalize it to Vertex format.contents nor prompt, stop and ask user to provide valid data.method + url + body (for example /v1/chat/completions payload).at least one contents field is required.When user asks you to generate a template/demo file for BatchJob image tasks:
prompt,aspect_ratio,image_urlsprompt / aspect_ratio / image_urlsimage_urls is provided, it must be publicly accessible (http/https).custom_id + method + url + body) as final upload fileWhen user asks for format/template, return:
prompt required, aspect_ratio/image_urls optional, and image_urls must be public URLs)./home/node/.openclaw/workspace/templates/batchjob-input-template.csv/home/node/.openclaw/workspace/templates/batchjob-input-template.jsonl/home/node/.openclaw/workspace/templates/batchjob-format-guide.mdDo not output OpenAI batch envelope examples in template replies.
file_id:
file_url (http:// or https://):
file_path:
/tmp/..., MEDIA:<path>, /tmp/openclaw-media/....Resolver output must be normalized to one of:
file_idfile_path (readable local file)model and mode; if missing, use safe defaults (model=google/gemini-2.5-flash-image, mode=fast) and tell user.file_path, upload via POST /v1/batch/files:upload to get file_id.
.jsonl, inspect a few non-empty lines first:
contents exists, upload as-is.prompt/aspect_ratio/image_urls exists, upload as-is (server will normalize).method + url + body exists, stop and ask user to switch to BatchJob schema.unsupported file type for csv/xlsx/xls, convert once to JSONL and retry upload once.unsupported schema, no valid data rows), stop immediately and return fix guidance.record_count (prefer uploaded file row_count).file_id.completed, failed, partially_failed) with bounded timeout:
job_id, then stop.job_id, status, progress, and output_summary_url.When user only asks for estimate, stop at precheck and do not submit.
Use this when resolver cannot read file bytes from current channel/context:
我拿到了“文件引用”,但当前运行环境无法直接读取该附件内容。请任选其一:
1) 直接发一个可公网下载的 URL
2) 提供本机可读路径(如 /tmp/xxx.csv)
3) 先把文件上传到 BatchJob,给我 file_id
If the current channel supports resending as direct attachment path in context, also ask user to resend once.
FILE_URL="https://example.com/input.jsonl"
EXT="${FILE_URL##*.}"
FILE_PATH="$(mktemp "/tmp/batchjob-input.XXXXXX.${EXT:-jsonl}")"
curl -fL --retry 3 --connect-timeout 10 "$FILE_URL" -o "$FILE_PATH"
Use this before upload to avoid wrong schema submission.
SRC_JSONL="/tmp/input.jsonl"
FIRST_LINE="$(grep -m1 -v '^[[:space:]]*$' "$SRC_JSONL")"
echo "$FIRST_LINE" | jq -e '
(has("contents")) or
(has("prompt")) and ( (has("method")|not) and (has("url")|not) and (has("body")|not) )
' >/dev/null || {
echo "JSONL schema invalid for BatchJob: requires contents or prompt-only schema"
exit 1
}
If message context already includes local attachment path, treat it as FILE_PATH directly.
FILE_PATH="/tmp/openclaw-media/your-uploaded-file.jsonl"
If only a channel token/link is provided but no downloadable URL and no local path, try channel adapter download first. If adapter is unavailable, use fallback interaction.
FILE_PATH="/path/to/input.jsonl"
FILE_NAME="$(basename "${FILE_PATH}")"
test -f "${FILE_PATH}" || { echo "文件 ${FILE_PATH} 不存在"; exit 1; }
FILE_CONTENT_B64="$(base64 < "${FILE_PATH}" | tr -d '\n')"
curl -sS "${BATCHJOB_BASE_URL}/v1/batch/files:upload" \
-H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"filename\":\"${FILE_NAME}\",\"mode\":\"fast\",\"content\":\"${FILE_CONTENT_B64}\"}"
curl -sS "${BATCHJOB_BASE_URL}/v1/batch/jobs:precheck" \
-H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"record_count": 100, "model": "google/gemini-2.5-flash-image", "mode": "fast"}'
curl -sS "${BATCHJOB_BASE_URL}/v1/batch/jobs" \
-H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"file_id": "your-file-id", "model": "google/gemini-2.5-flash-image", "mode": "fast"}'
curl -sS "${BATCHJOB_BASE_URL}/v1/batch/jobs/${JOB_ID}" \
-H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}"
curl -sS "${BATCHJOB_BASE_URL}/v1/batch/jobs/${JOB_ID}:cancel" \
-H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"reason":"user requested cancellation"}'