.github/workflows/refresh_model_profiles.yml YAML 160 lines View on github.com → Search inside
1# Refreshes model profile data for in-monorepo partner integrations by2# pulling the latest metadata from models.dev via the `langchain-profiles` CLI.3#4# Creates a pull request with any changes. Runs daily (all providers) and can5# be triggered manually from the Actions UI with an optional provider filter.6# Uses a fixed branch so each run supersedes any stale PR from a previous run.78name: "🔄 Refresh Model Profiles"910on:11  schedule:12    - cron: "0 8 * * *" # daily at 08:00 UTC13  workflow_dispatch:14    inputs:15      provider:16        type: choice17        description: "Provider package to refresh (select from dropdown)"18        default: all19        # models.dev provider IDs — must match the `provider` keys in20        # ALL_PROVIDERS below. When adding a package, update both lists.21        options:22          - all23          - anthropic24          - deepseek25          - fireworks-ai26          - groq27          - huggingface28          - mistral29          - openai30          - openrouter31          - perplexity32          - xai33      providers-override:34        type: string35        required: false36        description: >-37          Optional comma-separated provider IDs override (e.g. openai,anthropic).38          Takes precedence over the dropdown. Accepts models.dev IDs; package39          aliases fireworks and mistralai are also accepted.4041permissions:42  contents: write43  pull-requests: write4445jobs:46  resolve-providers:47    name: resolve providers48    if: github.repository_owner == 'langchain-ai'49    runs-on: ubuntu-latest50    outputs:51      providers: ${{ steps.resolve.outputs.providers }}52      pr-title: ${{ steps.resolve.outputs.pr-title }}53      pr-body: ${{ steps.resolve.outputs.pr-body }}54    steps:55      - name: "🎯 Resolve provider filter"56        id: resolve57        env:58          # Scheduled runs have no inputs — default to all providers.59          PROVIDER: ${{ github.event_name == 'workflow_dispatch' && inputs.provider || 'all' }}60          # Bracket access required: bare `inputs.providers-override` is parsed as subtraction.61          PROVIDERS_OVERRIDE: ${{ github.event_name == 'workflow_dispatch' && inputs['providers-override'] || '' }}62        run: |63          set -euo pipefail6465          ALL_PROVIDERS='[66            {"provider":"anthropic",    "data_dir":"libs/partners/anthropic/langchain_anthropic/data"},67            {"provider":"deepseek",     "data_dir":"libs/partners/deepseek/langchain_deepseek/data"},68            {"provider":"fireworks-ai", "data_dir":"libs/partners/fireworks/langchain_fireworks/data"},69            {"provider":"groq",         "data_dir":"libs/partners/groq/langchain_groq/data"},70            {"provider":"huggingface",  "data_dir":"libs/partners/huggingface/langchain_huggingface/data"},71            {"provider":"mistral",      "data_dir":"libs/partners/mistralai/langchain_mistralai/data"},72            {"provider":"openai",       "data_dir":"libs/partners/openai/langchain_openai/data"},73            {"provider":"openrouter",   "data_dir":"libs/partners/openrouter/langchain_openrouter/data"},74            {"provider":"perplexity",   "data_dir":"libs/partners/perplexity/langchain_perplexity/data"},75            {"provider":"xai",          "data_dir":"libs/partners/xai/langchain_xai/data"}76          ]'7778          normalize_provider() {79            case "$1" in80              fireworks) echo "fireworks-ai" ;;81              mistralai) echo "mistral" ;;82              *) echo "$1" ;;83            esac84          }8586          selected=()87          # Prefer free-text override when non-empty; otherwise use dropdown.88          if [ -n "${PROVIDERS_OVERRIDE//[[:space:]]/}" ]; then89            while IFS= read -r raw; do90              [ -z "${raw}" ] && continue91              selected+=("$(normalize_provider "${raw}")")92            done < <(93              echo "${PROVIDERS_OVERRIDE}" \94                | tr ',' '\n' \95                | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' \96                | grep -v '^$' || true97            )98          elif [ "${PROVIDER}" != "all" ]; then99            selected+=("$(normalize_provider "${PROVIDER}")")100          fi101102          if [ ${#selected[@]} -eq 0 ]; then103            filtered="$(echo "${ALL_PROVIDERS}" | jq -c .)"104            label="all in-monorepo partner integrations"105            title="chore(model-profiles): refresh model profile data"106          else107            ids_json="$(printf '%s\n' "${selected[@]}" | jq -R . | jq -s -c .)"108            unknown="$(echo "${ALL_PROVIDERS}" | jq -r --argjson ids "${ids_json}" '109              ($ids - map(.provider)) | join(", ")110            ')"111            if [ -n "${unknown}" ]; then112              known="$(echo "${ALL_PROVIDERS}" | jq -r 'map(.provider) | join(", ")')"113              echo "::error::Unknown provider ID(s): ${unknown}. Known: ${known}"114              exit 1115            fi116117            filtered="$(echo "${ALL_PROVIDERS}" | jq -c --argjson ids "${ids_json}" '118              map(select(.provider as $p | ($ids | index($p)) != null))119            ')"120            names="$(echo "${filtered}" | jq -r 'map(.provider) | join(", ")')"121            label="${names}"122            if [ "$(echo "${filtered}" | jq 'length')" -eq 1 ]; then123              title="chore(model-profiles): refresh ${names} model profile data"124            else125              title="chore(model-profiles): refresh model profile data (${names})"126            fi127          fi128129          count="$(echo "${filtered}" | jq 'length')"130          if [ "${count}" -eq 0 ]; then131            echo "::error::No providers matched the filter"132            exit 1133          fi134135          {136            echo "providers=${filtered}"137            echo "pr-title=${title}"138            echo "pr-body<<EOF_BODY"139            echo "Automated refresh of model profile data for ${label} via \`langchain-profiles refresh\`."140            echo141            echo "🤖 Generated by the [\`refresh_model_profiles\` workflow](https://github.com/langchain-ai/langchain/blob/master/.github/workflows/refresh_model_profiles.yml)."142            echo "EOF_BODY"143          } >> "${GITHUB_OUTPUT}"144145          echo "### Providers to refresh" >> "${GITHUB_STEP_SUMMARY}"146          echo "${filtered}" | jq -r '.[].provider' | sed 's/^/- /' >> "${GITHUB_STEP_SUMMARY}"147148  refresh-profiles:149    needs: resolve-providers150    uses: ./.github/workflows/_refresh_model_profiles.yml151    with:152      providers: ${{ needs.resolve-providers.outputs.providers }}153      cli-path: libs/model-profiles154      add-paths: libs/partners/**/data/_profiles.py155      pr-title: ${{ needs.resolve-providers.outputs.pr-title }}156      pr-body: ${{ needs.resolve-providers.outputs.pr-body }}157    secrets:158      MODEL_PROFILE_BOT_CLIENT_ID: ${{ secrets.MODEL_PROFILE_BOT_CLIENT_ID }}159      MODEL_PROFILE_BOT_PRIVATE_KEY: ${{ secrets.MODEL_PROFILE_BOT_PRIVATE_KEY }}

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.