mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
Bake the imagegen script into a Daytona snapshot so the agent can just run `imagegen <prompt> <output>` instead of manually calling the Gemini API with curl/jq. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
71 lines
2.3 KiB
Text
71 lines
2.3 KiB
Text
FROM ubuntu:22.04
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl jq git ca-certificates \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
RUN printf '%s\n' \
|
|
'#!/usr/bin/env bash' \
|
|
'set -euo pipefail' \
|
|
'' \
|
|
'usage() {' \
|
|
' echo "Usage: imagegen <prompt> [output.png]" >&2' \
|
|
' echo "" >&2' \
|
|
' echo "Generate an image from a text prompt using Gemini." >&2' \
|
|
' echo "Output defaults to '"'"'output.png'"'"' if not specified." >&2' \
|
|
' exit 1' \
|
|
'}' \
|
|
'' \
|
|
'if [[ $# -lt 1 ]] || [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then' \
|
|
' usage' \
|
|
'fi' \
|
|
'' \
|
|
'if [[ -z "${GEMINI_API_KEY:-}" ]]; then' \
|
|
' echo "Error: GEMINI_API_KEY not set" >&2' \
|
|
' exit 1' \
|
|
'fi' \
|
|
'' \
|
|
'PROMPT="$1"' \
|
|
'OUTPUT="${2:-output.png}"' \
|
|
'MODEL="${IMAGEGEN_MODEL:-gemini-2.5-flash-image}"' \
|
|
'API_URL="https://generativelanguage.googleapis.com/v1beta/models/${MODEL}:generateContent?key=${GEMINI_API_KEY}"' \
|
|
'' \
|
|
'echo "Generating image for: ${PROMPT}" >&2' \
|
|
'echo "Model: ${MODEL}" >&2' \
|
|
'' \
|
|
'RESPONSE=$(curl -s --fail-with-body -X POST "$API_URL" \' \
|
|
' -H "Content-Type: application/json" \' \
|
|
' -d "$(jq -n --arg prompt "$PROMPT" '"'"'{' \
|
|
' contents: [{ parts: [{ text: $prompt }] }],' \
|
|
' generationConfig: { responseModalities: ["TEXT", "IMAGE"] }' \
|
|
' }'"'"')")' \
|
|
'' \
|
|
'ERROR=$(echo "$RESPONSE" | jq -r '"'"'.error.message // empty'"'"')' \
|
|
'if [[ -n "$ERROR" ]]; then' \
|
|
' echo "API error: $ERROR" >&2' \
|
|
' exit 1' \
|
|
'fi' \
|
|
'' \
|
|
'IMAGE_DATA=$(echo "$RESPONSE" | jq -r '"'"'' \
|
|
' .candidates[0].content.parts[]' \
|
|
' | select(.inlineData)' \
|
|
' | .inlineData.data' \
|
|
''"'"' | head -1)' \
|
|
'' \
|
|
'if [[ -z "$IMAGE_DATA" ]]; then' \
|
|
' TEXT=$(echo "$RESPONSE" | jq -r '"'"'.candidates[0].content.parts[] | select(.text) | .text // empty'"'"')' \
|
|
' if [[ -n "$TEXT" ]]; then' \
|
|
' echo "Model response (no image): $TEXT" >&2' \
|
|
' else' \
|
|
' echo "No image in response. Raw:" >&2' \
|
|
' echo "$RESPONSE" | jq . >&2' \
|
|
' fi' \
|
|
' exit 1' \
|
|
'fi' \
|
|
'' \
|
|
'echo "$IMAGE_DATA" | base64 -d > "$OUTPUT"' \
|
|
'echo "Saved to ${OUTPUT}" >&2' \
|
|
> /usr/local/bin/imagegen && chmod +x /usr/local/bin/imagegen
|
|
|
|
RUN useradd -m -s /bin/bash daytona
|
|
USER daytona
|
|
WORKDIR /home/daytona
|