Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions .github/workflows/update-model-catalog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Update model catalog

on:
schedule:
# Daily at 05:17 UTC; off the top of the hour to dodge the cron rush.
- cron: '17 5 * * *'
workflow_dispatch:

permissions:
contents: write
pull-requests: write

concurrency:
group: update-model-catalog
cancel-in-progress: false

env:
UPDATE_BRANCH: bot/update-model-catalog
CATALOG_FILE: packages/ai/src/models.generated.ts

jobs:
regenerate:
name: Regenerate and open PR
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.event.repository.default_branch }}

- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: npm

# npm ci runs every workspace's install scripts, and some need the same
# native libraries CI installs (node-canvas builds against cairo/pango).
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev

- name: Install dependencies
run: npm ci

- name: Regenerate model catalog
working-directory: packages/ai
run: npm run generate-models

- name: Guard against gutted providers
# generate-models exits 0 even when a source fetch fails, and most
# failed sources fall back to an empty list rather than the committed
# snapshot. A large drop in total models means a source silently
# failed, so refuse to open a PR from that state.
run: |
old=$(git show "HEAD:$CATALOG_FILE" | grep -c 'satisfies Model')
new=$(grep -c 'satisfies Model' "$CATALOG_FILE")
echo "Committed snapshot: $old models; regenerated: $new models"
if [ "$new" -lt $(( old * 9 / 10 )) ]; then
echo "::error::Regenerated catalog dropped from $old to $new models; a provider fetch likely failed."
exit 1
fi

- name: Detect changes
id: diff
run: |
if git diff --quiet -- "$CATALOG_FILE"; then
echo "Catalog unchanged; nothing to do."
echo "changed=false" >> "$GITHUB_OUTPUT"
else
git diff --stat -- "$CATALOG_FILE"
echo "changed=true" >> "$GITHUB_OUTPUT"
fi

- name: Create or update pull request
if: steps.diff.outputs.changed == 'true'
env:
GH_TOKEN: ${{ github.token }}
# GITHUB_TOKEN-created PRs need a maintainer to close/reopen them
# before merge so pull_request CI runs.
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

old=$(git show "HEAD:$CATALOG_FILE" | grep -c 'satisfies Model')
new=$(grep -c 'satisfies Model' "$CATALOG_FILE")
body=$(printf 'Automated daily refresh of `%s` from the live provider catalogs (models.dev, OpenRouter, Vercel AI Gateway, Prime Inference).\n\nModel count: %s -> %s. Review the diff for pricing changes, renames, and removals before merging.\n\nCI does not run automatically on PRs opened by the workflow token. Close and reopen this PR to trigger it.' "$CATALOG_FILE" "$old" "$new")

git switch -c "$UPDATE_BRANCH"
git add "$CATALOG_FILE"
git commit -m "chore(ai): refresh the generated model catalog from live provider catalogs"
git push -f origin "$UPDATE_BRANCH"

open_pr=$(gh pr list --head "$UPDATE_BRANCH" --base main --state open --json number --jq '.[0].number // empty')
if [ -z "$open_pr" ]; then
gh pr create \
--base main \
--head "$UPDATE_BRANCH" \
--title "chore(ai): refresh the generated model catalog from live provider catalogs" \
--body "$body"
else
gh pr edit "$open_pr" --body "$body"
echo "Updated pull request #$open_pr with the refreshed catalog."
fi
Comment thread
sethkarten marked this conversation as resolved.
Loading