BatchJob Async Job Skill
name: batchjob-async-job
by cocovs · published 2026-03-22
$ claw add gh:cocovs/cocovs-ssy-batchjob-async-job---
name: batchjob-async-job
description: "Use BatchJob HTTP APIs for strict upload validation, precheck, submit, polling, and cancellation. Full-auto file source resolution (file_id/local path/public URL/channel attachment path) with fallback interaction only when source is not readable."
metadata: { "openclaw": { "emoji": "🧪", "requires": { "bins": ["curl"], "env": ["BATCHJOB_BASE_URL", "BATCHJOB_BEARER_TOKEN"] } } }
---
# BatchJob Async Job Skill
Use this skill when the user wants to run or manage batch jobs through the BatchJob service.
Required Environment
All HTTP requests must include:
-H "Authorization: Bearer ${BATCHJOB_BEARER_TOKEN}"
-H "Content-Type: application/json"API Endpoints
Automation Policy (Default)
- canonical Vertex format (`contents` + optional `generationConfig`)
- simple prompt format (`prompt` + optional `aspect_ratio` / `image_urls`, where `image_urls` must be publicly reachable URLs)
Guardrails (Must Follow)
JSONL Compatibility Rule (Important)
BatchJob internal execution expects each JSONL line to be a `VertexGeminiImageRequest` shape.
- `contents[0].parts[0].text` contains prompt text
- `generationConfig.imageConfig.aspectRatio` is optional
- `generationConfig.responseModalities` should include `IMAGE` and `TEXT`
- OpenAI Batch style lines containing `method` + `url` + `body` (for example `/v1/chat/completions` payload).
- This schema will fail with Vertex error: `at least one contents field is required`.
Dataset Output Rule (Important)
When user asks you to generate a template/demo file for BatchJob image tasks:
User Template Response (Important)
When user asks for format/template, return:
1. A short explanation (`prompt` required, `aspect_ratio`/`image_urls` optional, and `image_urls` must be public URLs).
2. One copyable CSV snippet (default).
3. Optionally one JSONL snippet (simple prompt schema).
4. Local template file paths (if available):
- `/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.md`
Do not output OpenAI batch envelope examples in template replies.
File Source Resolver (Strict Order)
1. Existing `file_id`:
- if provided, skip upload.
2. Public `file_url` (`http://` or `https://`):
- download to temp local file, then upload.
3. Explicit local `file_path`:
- if readable, upload.
4. Inbound attachment local path from channel/runtime context:
- examples: `/tmp/...`, `MEDIA:<path>`, `/tmp/openclaw-media/...`.
- if readable, upload.
5. Channel private file token/object (no local path, no public URL):
- if runtime has a channel adapter that can download attachment bytes, use it and upload.
- if not available, enter fallback interaction.
Resolver output must be normalized to one of:
Execution Flow
1. Confirm `model` and `mode`; if missing, use safe defaults (`model=google/gemini-2.5-flash-image`, `mode=fast`) and tell user.
2. Resolve file source using resolver above.
3. If resolver gives `file_path`, upload via `POST /v1/batch/files:upload` to get `file_id`.
- For `.jsonl`, inspect a few non-empty lines first:
- if `contents` exists, upload as-is.
- if only `prompt`/`aspect_ratio`/`image_urls` exists, upload as-is (server will normalize).
- if `method` + `url` + `body` exists, stop and ask user to switch to BatchJob schema.
- if structure is unknown, stop and ask user for valid schema.
- Backward compatibility fallback:
- if upload fails with `unsupported file type` for `csv/xlsx/xls`, convert once to JSONL and retry upload once.
- do not retry more than once.
- If upload returns validation error (`unsupported schema`, `no valid data rows`), stop immediately and return fix guidance.
4. Run precheck with `record_count` (prefer uploaded file `row_count`).
5. Submit job with `file_id`.
6. Poll job status until terminal (`completed`, `failed`, `partially_failed`) with bounded timeout:
- interval: 5 seconds
- max polls: 12 (about 60 seconds)
- if still non-terminal after max polls: return current status and `job_id`, then stop.
7. Return concise summary with `job_id`, status, progress, and `output_summary_url`.
When user only asks for estimate, stop at precheck and do not submit.
Fallback Interaction (Only When Needed)
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 Source Playbook
A) Public URL -> Local Temp File
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"A2) JSONL Schema Sanity Check
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
}B) Feishu/Channel Attachment Path
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.
Curl Templates
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"}'More tools from the same signal band
Order food/drinks (点餐) on an Android device paired as an OpenClaw node. Uses in-app menu and cart; add goods, view cart, submit order (demo, no real payment).
Sign plugins, rotate agent credentials without losing identity, and publicly attest to plugin behavior with verifiable claims and authenticated transfers.
The philosophical layer for AI agents. Maps behavior to Spinoza's 48 affects, calculates persistence scores, and generates geometric self-reports. Give your...