Loading...
Loading...
Upload an image/GIF/video to the pylot assets backend and return a stable public URL, optionally attaching it to a chat conversation. Use whenever you need to embed visual evidence in a PR, issue, or report, or to make an image appear in a conversation thread.
npx skill4agent add fellowship-dev/dogfooded-skills evidence-upload$PYLOT_GATEWAY_URL$PYLOT_DISPATCH_TOKEN--conversation <conversation-id>--alt "<text>"| Type | MIME types | Max size |
|---|---|---|
| Images | | 25 MB |
| Video | | 25 MB |
/assets/presign# Variables you must set before running:
# FILE=/path/to/screenshot.png
# CONTENT_TYPE=image/png # must match allowlist
# REPO=org/repo-name # scopes the org fence
BYTES=$(wc -c < "$FILE")
# 1. Presign — returns asset_id + a short-lived S3 upload URL
PRESIGN=$(curl -sS -X POST "$PYLOT_GATEWAY_URL/assets/presign" \
-H "Authorization: Bearer $PYLOT_DISPATCH_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"repo\":\"$REPO\",\"content_type\":\"$CONTENT_TYPE\",\"size\":$BYTES}")
ASSET_ID=$(echo "$PRESIGN" | python3 -c "import sys,json; print(json.load(sys.stdin)['asset_id'])")
UPLOAD_URL=$(echo "$PRESIGN" | python3 -c "import sys,json; print(json.load(sys.stdin)['upload_url'])")
# 2. Direct PUT to S3 (no auth header — the presigned URL carries credentials)
curl -sS -X PUT "$UPLOAD_URL" \
--data-binary @"$FILE" \
-H "Content-Type: $CONTENT_TYPE"
# 3. Publish → stable public URL (camo-proxied, safe to embed in GitHub)
PUBLIC_URL=$(curl -sS -X PATCH "$PYLOT_GATEWAY_URL/assets/$ASSET_ID" \
-H "Authorization: Bearer $PYLOT_DISPATCH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"visibility":"public"}' \
| python3 -c "import sys,json; print(json.load(sys.stdin)['public_url'])")
# 4. Embed in PR / issue / report body:
echo ""
# Optional — revoke public access when no longer needed:
# curl -sS -X PATCH "$PYLOT_GATEWAY_URL/assets/$ASSET_ID" \
# -H "Authorization: Bearer $PYLOT_DISPATCH_TOKEN" \
# -H "Content-Type: application/json" \
# -d '{"visibility":"org"}'--conversation--conversation <conversation-id>--alt "<text>"# Extra variables from the invocation args:
# CONVERSATION_ID=<conversation-id> # from --conversation
# ALT="short image description" # from --alt (optional; omitted → server stores null)
BODY=$(CONVERSATION_ID="$CONVERSATION_ID" ALT="${ALT:-}" python3 -c "
import json, os
b = {'visibility': 'public', 'conversation_id': os.environ['CONVERSATION_ID']}
if os.environ.get('ALT'):
b['alt'] = os.environ['ALT']
print(json.dumps(b))")
RESPONSE=$(curl -sS -X PATCH "$PYLOT_GATEWAY_URL/assets/$ASSET_ID" \
-H "Authorization: Bearer $PYLOT_DISPATCH_TOKEN" \
-H "Content-Type: application/json" \
-d "$BODY")
PUBLIC_URL=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['public_url'])")
MESSAGE_ID=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('conversation_message_id',''))")
ATTACHED=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('attached',''))"){"type":"image","asset_id","alt","mime_type"}attached to conversation <id> — message <MESSAGE_ID> (attached: <ATTACHED>)conversation_message_idattachedTrueFalse$REPO--conversationerrorconversation_id{"visibility":"public"}conversation_not_found$PYLOT_GATEWAY_URLconversation_org_mismatch$REPOasset_not_uploadedpublic_url