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.