Repository navigation
Release creative Runtime tools on the production beta baseline #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| name: creative-tools | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - deploy/distribution/CreativeRuntime.Dockerfile | ||
| - services/core/deploy/creative/** | ||
| - services/core/deploy/e2b/** | ||
| - .github/workflows/creative-tools.yml | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| tools: | ||
| runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-24.04' || 'blacksmith-2vcpu-ubuntu-2404' }} | ||
| timeout-minutes: 30 | ||
| steps: | ||
| - uses: actions/checkout@v7 | ||
| with: | ||
| persist-credentials: false | ||
| - name: Check E2B packaging | ||
| run: python3 -m unittest discover -s services/core/deploy/e2b -p build_template_test.py | ||
| - name: Build and verify tools | ||
| # This base qualifies tools only, not a native Harness or deployment. | ||
| run: | | ||
| set -euo pipefail | ||
| mkdir -p "$RUNNER_TEMP/creative-check" | ||
| chmod 0777 "$RUNNER_TEMP/creative-check" | ||
| docker build --platform linux/amd64 \ | ||
| --build-arg RUNTIME_IMAGE=node:22.23.1-bookworm-slim@sha256:8607a9064d4a571140998ae9e52a3b3fcf9cff361d04642d5971e6cd76d39e27 \ | ||
| -f deploy/distribution/CreativeRuntime.Dockerfile -t creative-tools:check . \ | ||
| 2>&1 | tee "$RUNNER_TEMP/creative-check/build.log" | ||
| docker run --rm --entrypoint oac-creative-check \ | ||
| -v "$RUNNER_TEMP/creative-check:/outputs" creative-tools:check /outputs \ | ||
| 2>&1 | tee "$RUNNER_TEMP/creative-check/check.log" | ||
| - uses: actions/upload-artifact@v6 | ||
| if: always() | ||
| with: | ||
| name: creative-tools-smoke | ||
| path: ${{ runner.temp }}/creative-check | ||
| if-no-files-found: error |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Build from a qualified immutable Runtime image; use the repository root context. | ||
| ARG RUNTIME_IMAGE | ||
| FROM ${RUNTIME_IMAGE} | ||
| USER root | ||
| COPY services/core/deploy/creative /opt/oac-creative | ||
| RUN sh /opt/oac-creative/install.sh | ||
| ENV OAC_RUNTIME_TOOL_ENV_FILE=/opt/oac-creative/tool-env.json \ | ||
| PLAYWRIGHT_BROWSERS_PATH=/opt/oac-creative/browsers | ||
| USER 1000:1000 | ||
| RUN node /opt/oac-creative/check.mjs | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| # Creative Runtime tools | ||
|
|
||
| Use this image for browser-based visual Skills. It adds Python with venv support, curl, ZIP tools, FFmpeg/ffprobe, Noto Latin/CJK/emoji fonts and a lockfile-pinned Playwright Chromium to a qualified Debian Bookworm Runtime. Skill-specific npm/Python packages remain project dependencies; this image does not choose their versions or install every Skill. | ||
|
|
||
| Build from the repository root with a qualified Linux amd64 Runtime image pinned by its registry manifest digest: | ||
|
|
||
| ```sh | ||
| docker build --platform linux/amd64 \ | ||
| --build-arg RUNTIME_IMAGE=registry.example/runtime@sha256:QUALIFIED_MANIFEST_DIGEST \ | ||
| -f deploy/distribution/CreativeRuntime.Dockerfile -t your-creative-runtime . | ||
| docker run --rm --entrypoint oac-creative-check your-creative-runtime | ||
| ``` | ||
|
|
||
| For a local build, use a unique source-revision tag and verify its configuration ID before building. A bare `sha256:` configuration ID is not a registry image reference for Dockerfile `FROM`. | ||
|
|
||
| `OAC_RUNTIME_TOOL_ENV_FILE` points to the Runtime-owned tool environment containing browser paths for Playwright, HyperFrames and Puppeteer. The image owns this file; Session preparation reads it using the existing explicit tool-environment contract. If an operator needs additional tool variables, create one combined private file and select it instead. Never put credentials into the image. | ||
|
|
||
| Run `oac-creative-check /workspace/outputs/creative-check` inside the prepared execution Environment to produce a screenshot and a one-second H.264 video. The command verifies browser startup, CJK font selection, FFmpeg and ffprobe. These are tool checks; qualify each Skill with its real scripts and inspect the resulting film separately. Browser processes run without Chromium's inner sandbox; the outer Runtime container or E2B VM remains the isolation boundary. | ||
|
|
||
| The E2B builder detects `/opt/oac-creative/install.sh` in the qualified image and runs its `--system-only` mode after extracting the Runtime payload. This restores Debian libraries and fonts that the `/opt` archive cannot carry, while reusing the same pinned browser and npm files. Use the existing [E2B build command](../e2b/README.md). The output receipt includes `creative_tools`. Build completion does not activate a deployment: select and qualify the immutable template through the existing Sandbox deployment workflow before directing user Sessions to it. | ||
|
|
||
| Browser/npm versions are pinned in `package-lock.json`. Debian packages follow the configured Bookworm security repositories; record the image digest and template build for release provenance. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #!/usr/bin/env node | ||
| import { mkdir, readFile } from 'node:fs/promises'; | ||
| import { spawnSync } from 'node:child_process'; | ||
| import { resolve } from 'node:path'; | ||
|
|
||
| const toolEnv = JSON.parse(await readFile('/opt/oac-creative/tool-env.json', 'utf8')); | ||
| Object.assign(process.env, toolEnv); | ||
| const { chromium } = await import('playwright'); | ||
| const output = process.argv[2]; | ||
| if (output && !output.startsWith('/')) throw new Error('Use an absolute output directory'); | ||
| const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] }); | ||
| try { | ||
| const page = await browser.newPage({ viewport: { width: 640, height: 360 } }); | ||
| await page.setContent('<html lang="zh-CN"><meta charset="utf-8"><style>body{font-family:"Noto Sans CJK SC",sans-serif;background:#172033;color:white}h1{font-size:40px}</style><h1>制作环境 Ready</h1><canvas width="100" height="100"></canvas><script>const c=document.querySelector("canvas");c.getContext("2d").fillRect(5,5,90,90)</script>'); | ||
| await page.evaluate(() => document.fonts.ready); | ||
| if (output) { | ||
| await mkdir(output, { recursive: true }); | ||
| await page.screenshot({ path: resolve(output, 'creative-check.png') }); | ||
| } | ||
| } finally { await browser.close(); } | ||
| const run = (command, args) => { | ||
| const result = spawnSync(command, args, { encoding: 'utf8' }); | ||
| if (result.status !== 0) throw new Error(`${command} check failed:\n${result.stderr?.slice(-8000) ?? result.error?.message ?? 'unknown process failure'}`); | ||
| return result.stdout; | ||
| }; | ||
| run('ffmpeg', ['-version']); | ||
| run('ffprobe', ['-version']); | ||
| if (!run('fc-match', ['-f', '%{family}', ':lang=zh-cn']).includes('Noto')) throw new Error('CJK font unavailable'); | ||
| if (output) { | ||
| run('ffmpeg', ['-nostdin', '-y', '-loop', '1', '-i', resolve(output, 'creative-check.png'), '-t', '1', '-r', '24', '-c:v', 'libx264', '-pix_fmt', 'yuv420p', resolve(output, 'creative-check.mp4')]); | ||
| const media = JSON.parse(run('ffprobe', ['-v', 'error', '-show_streams', '-of', 'json', resolve(output, 'creative-check.mp4')])); | ||
| if (!media.streams.some(s => s.codec_name === 'h264' && s.width === 640 && s.height === 360)) throw new Error('Video verification failed'); | ||
| } | ||
| console.log(JSON.stringify({ ready: true, browser: chromium.executablePath(), output: output ?? null })); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { chromium } from 'playwright'; | ||
| import { writeFileSync } from 'node:fs'; | ||
| // Harnesses consume explicit tool variables, not the daemon's ambient environment. | ||
| const browser = chromium.executablePath(); | ||
| writeFileSync('/opt/oac-creative/tool-env.json', JSON.stringify({ | ||
| PLAYWRIGHT_BROWSERS_PATH: '/opt/oac-creative/browsers', | ||
| HYPERFRAMES_BROWSER_PATH: browser, | ||
| PUPPETEER_EXECUTABLE_PATH: browser, | ||
| }) + '\n'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| #!/bin/sh | ||
| set -eu | ||
| # Reused after the /opt payload is extracted into the E2B base image. | ||
| apt-get update | ||
| apt-get install -y --no-install-recommends ca-certificates curl unzip zip xz-utils \ | ||
| python3 python3-pip python3-venv git ripgrep ffmpeg fontconfig \ | ||
| fonts-noto-core fonts-noto-cjk fonts-noto-color-emoji fonts-liberation | ||
| cd /opt/oac-creative | ||
| if [ "${1:-}" != "--system-only" ]; then | ||
| npm ci --omit=dev --ignore-scripts --no-audit --no-fund | ||
| PLAYWRIGHT_BROWSERS_PATH=/opt/oac-creative/browsers node node_modules/playwright/cli.js install chromium | ||
| fi | ||
| node node_modules/playwright/cli.js install-deps chromium | ||
| rm -rf /var/lib/apt/lists/* | ||
| fc-cache -f | ||
| PLAYWRIGHT_BROWSERS_PATH=/opt/oac-creative/browsers node configure.mjs | ||
| ln -sf /opt/oac-creative/check.mjs /usr/local/bin/oac-creative-check | ||
| chmod -R a+rX /opt/oac-creative | ||
| chmod 0755 /opt/oac-creative/check.mjs | ||
| chown 1000:1000 tool-env.json | ||
| chmod 0600 tool-env.json |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| { | ||
| "name": "oac-creative-tools", | ||
| "private": true, | ||
| "version": "1.0.0", | ||
| "dependencies": { "playwright": "1.61.1" } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PLAYWRIGHT_BROWSERS_PATHis also written to/opt/oac-creative/tool-env.jsonbyconfigure.mjs, so direct image processes inherit one copy while prepared Sessions consume another. If either path changes independently, browser behavior diverges by launch path; remove the duplicate image-level value and let consumers read the Runtime-owned tool environment.AGENTS.md reference: AGENTS.md:L53-L55
Useful? React with 👍 / 👎.