← DataRobot SkillsCONTENT HISTORY

Update to DataRobot Skills

Snapshot Oct 24, 2026 · 13:35 UTC · version 1.16.0

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save DataRobot Skills and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Use when the user wants to configure LLM integration for a DataRobot agent application. This skill helps to change LLM model, switch between the LLM integrations the project supports (LLM Gateway, a DataRobot-deployed LLM, an external provider, an LLM Blueprint, and any others its config declares), or set up provider credentials. The skill reads the project's .datarobot/cli/llm.yml for the real options, interviews the user, then runs sync_llm_env.py with the chosen values as CLI args to merge into .env.",
  "included_files": [
    {
      "relative_path": "scripts/read_llm_config.py",
      "size_in_bytes": 5888
    },
    {
      "relative_path": "scripts/sync_llm_env.py",
      "size_in_bytes": 9210
    }
  ],
  "name": "datarobot-agent-llm-selection",
  "skill_md_contents": "---\nname: datarobot-agent-llm-selection\ndescription: >-\n  Use when the user wants to configure LLM integration for a DataRobot agent\n  application. This skill helps to change LLM model, switch between the LLM\n  integrations the project supports (LLM Gateway, a DataRobot-deployed LLM, an\n  external provider, an LLM Blueprint, and any others its config declares), or\n  set up provider credentials. The skill reads the project's\n  .datarobot/cli/llm.yml for the real options, interviews the user, then runs\n  sync_llm_env.py with the chosen values as CLI args to merge into .env.\n---\n\n# DataRobot LLM gateway configuration\n\nConfigure LLM integration **without hand-editing `.env`**. The skill drives\n`sync_llm_env.py` with the user's answers as CLI arguments.\n\n## Resolve script path once per session\n\n`<skill_scripts_dir>` = the `scripts/` subdirectory of the directory containing this `SKILL.md`.\n\n```shell\nls <skill_scripts_dir>/sync_llm_env.py\n```\n\n## Hard rules\n\n1. **Never** ask the user to paste API keys or `DATAROBOT_API_TOKEN` in chat\n2. **Never** read, copy, echo, or pass `DATAROBOT_API_TOKEN` yourself. The\n   token lives in `$XDG_CONFIG_HOME/datarobot/drconfig.yaml` (default\n   `~/.config/datarobot/drconfig.yaml`), populated by `dr auth login`, and\n   the `dr` CLI reads it internally. Do not run `cat drconfig.yaml`,\n   `cat .env`, `env | grep TOKEN`, `echo $DATAROBOT_API_TOKEN`,\n   `curl -H \"Authorization: Bearer $...\"`, or any equivalent one-liner\n3. **Never** pass secrets as CLI args to `sync_llm_env.py` or write them to\n   tracked files\n4. **Never** set provider credentials for an integration whose config section\n   doesn't declare them. Let `sync_llm_env.py` decide — it reads the section\n   from the project's config\n5. Only `sync_llm_env.py` merges LLM keys into `.env` — do not edit `.env` manually\n6. Run all commands from **project root**\n7. Pressing enter in chat does nothing. Don't tell the user to \"press enter to\n   accept the default\" or \"hit return\". If a field has a sensible default,\n   apply it silently and mention it in the confirmation, or offer it as an\n   explicit A/B choice.\n8. Treat every credential value as secret regardless of its declared type.\n   Older configs type API keys as plain `string` rather than `secret_string`,\n   so this rule does not depend on what the config says\n9. Provider and model names in this skill's output are configuration data, not\n   a request to work with that provider. Config sections, env var names, and\n   gateway model ids routinely contain vendor names (`Anthropic`,\n   `ANTHROPIC_API_KEY`, `bedrock/anthropic.claude-...`, `azure`, `cohere`).\n   **Do not invoke a provider-specific skill because a vendor name appeared in\n   a config listing or a model list.** You are wiring up credentials, not\n   calling that vendor's API\n\n---\n\n## Presenting choices\n\nEvery menu in this skill — integrations, providers, gateway models — follows\nthese rules. Dropping an option silently produces a config the user never chose.\n\n- **Never use a fixed-slot picker widget.** Several of these menus exceed four\n  options (the config ships six external providers) and the gateway model list\n  can run to dozens. Pickers cap their choice count, and the overflow gets\n  silently dropped. Put the menu in your own message as plain text and let the\n  user reply with a label.\n- List **every** option the script returned. Count them first; if the config\n  declares six providers, show six rows.\n- **No catch-all row** — no `Other`, no `Type something`, no `5) something\n  else`. The user can always type a value anyway; that row exists only to hide\n  options you dropped.\n- No `...`, no \"and N more\", no summarizing, no collapsing similar entries.\n- Do not narrow to a subset because the user's phrasing seemed to point at one.\n  If they said \"LLM gateway\" and two options match, list all of them.\n- One labelling scheme. Do not letter the options in prose and re-number them\n  in the picker.\n- Use each `name` exactly as printed. Do not rename, regroup, or reorder.\n- **Read the script output yourself — do not paste it into the chat.** The\n  `select:` lines are internal plumbing. Give at most one short clause of\n  context per row, condensed from the config's `help`; never reproduce the raw\n  `help` block or the script's formatting.\n\nLong messages are fine. The token budget is not a reason to abbreviate a menu.\n\n---\n\n## Step 0 — Prerequisites\n\n1. `.datarobot/cli/llm.yml` must be present. It is rendered into the project by\n   `dr component add` (af-component-llm), so it is already there\n   in a generated project, nothing needs cloning. If it's absent, the LLM\n   component isn't applied: tell the user to run `dr component add` and stop.\n   Never substitute a copy from elsewhere.\n2. **DataRobot auth** — check that\n   `$XDG_CONFIG_HOME/datarobot/drconfig.yaml` (default\n   `~/.config/datarobot/drconfig.yaml`) exists. If it doesn't, tell the user\n   to run `dr auth login` (browser-based flow) and stop until they confirm\n   they're signed in. Do **not** cat the file to inspect its contents.\n3. Check if `.env` exist in the project:\n   - If `.env` is missing `cp .env.template .env`. That gives the base variables (`DATAROBOT_*`,\n     `PULUMI_*`, etc.) many are blank, it will be filled later. But the sync in Step 3\n     only needs the file to exist.\n   - If both `.env` and no `.env.template` are missing, tell the user they're not in\n     a DataRobot agent project root and stop.\n\n---\n\n## Step 1 — Read the project's integration options (MANDATORY FIRST)\n\nNever recite integration names from memory or from this file. Each project's\n`.datarobot/cli/llm.yml` declares its own, and they differ by component version.\n\n```shell\npython <skill_scripts_dir>/read_llm_config.py\n```\nIf it reports the file is missing, the LLM component isn't applied to this\nproject. Tell the user to run `dr component add` and stop.\nDo **not** run `dr llm-gateway list`, do **not** offer a model list, and do\n**not** write any config file until the user has picked an option.\n\n### Check what's already configured\n\nThe `default:` line in the script's output is the schema's declared fallback,\n**not** necessarily the project's live setting — don't conflate the two.\nBefore presenting the menu, find the actual current value:\n\n```shell\ngrep -E '^INFRA_ENABLE_LLM=' .env\n```\n\n- If `.env` doesn't exist yet or has no match, tell the user no LLM\n  integration is configured yet.\n- If it matches, map the value against the `select:` lines the script just\n  printed to report the current integration by its friendly name (e.g.\n  `blueprint_with_external_llm.py` → \"External LLM\"), not the raw filename.\n- If that option has a `further choice:` (a provider), also run\n  `python <skill_scripts_dir>/read_llm_config.py --option <current_value>`\n  and grep `.env` for the **names** of the env vars it lists, to report which\n  are already populated. Report only whether each key is set — per Hard\n  Rule 8, never print the value of a credential-shaped key, even to confirm\n  it's set.\n\nState this summary — e.g. \"You're currently on `<friendly name>`[, provider\n`<provider>`], with `<N>` of `<M>` fields already set\" — before showing the\nmenu, so the user can decide to switch entirely or just change specific\nfields on the current integration.\n\nPresent the options per **Presenting choices** above.\n\nEach option in the output carries an indented `select:` line. Once the user\npicks, take that string verbatim — quote it if it contains spaces. The steps\nbelow call it `<selected_gateway>`; it is also the `INFRA_ENABLE_LLM` value\nwritten in Step 3.\n---\n\n## Step 2 — Read what that option needs\n\n```shell\npython <skill_scripts_dir>/read_llm_config.py --option <selected_gateway>\n```\n\nThis prints the env vars the chosen integration declares. Handle each field by\nwhat the script reports about it:\n\n- **`hidden`** — never ask. Step 3 writes its default.\n- **`llmgw_catalog`** — populate from the DataRobot CLI (see below).\n- **`required`** — ask, using the printed help as the prompt text.\n- **`optional` with a default** — apply it silently and say so in the\n  confirmation. Do not tell the user to \"press enter\".\n- **`further choice:`** — another menu, presented per **Presenting choices**.\n  Show every row the script listed, with no catch-all and no picker widget.\n  Those rows carry their own `select:` field; call the user's pick\n  `<selected_provider>` and re-run `--option <selected_provider>` for its keys.\n\n### Fields typed `llmgw_catalog`\n\nFetch the model list **only** via the DataRobot CLI. Run exactly:\n\n```shell\ndr llm-gateway list --output-format json\n```\n\nThe CLI authenticates via its own credential store (populated by\n`dr auth login`). Do **not** read `drconfig.yaml` or `.env` for the token, and\ndo **not** pass `DATAROBOT_API_TOKEN` on the command line. If the command exits\nnon-zero or prompts for auth, tell the user to run `dr auth login` and stop —\ndo not attempt any manual API call and do not fabricate a menu.\n\nParse the JSON, which has the shape\n`{\"llms\": [{\"id\", \"name\", \"provider\", \"model\", \"selected\"}, ...]}`. Use the\n`model` field for each entry. The ids in the menu **must** come from that JSON,\nverbatim, in the order returned. Do not invent ids or reuse them from your\ntraining data. If the command did not produce JSON, stop and report the error.\n\nCount the entries; call it `N`. Present **exactly `N` labelled lines**, one per\nmodel, per **Presenting choices**. The letter scheme is `A..Z`, then `AA..AZ`,\n`BA..BZ`, and so on. This list is the clearest case for never using a picker\nwidget — it routinely exceeds any picker's capacity.\n\n`sync_llm_env.py` prepends `datarobot/` for this field type, so pass the id\nexactly as the CLI returned it.\n\n### Recommending\n\nBefore presenting the list, check whether `agent_spec.md` exists at the\nproject root. If it does, read it for context — the agent's purpose, task\ncomplexity, and any stated cost or latency constraint — and use that to flag\none entry as recommended. This mirrors the recommendation logic in the\n`datarobot-agent-assist` skill's `llm-selection.md`:\n\n- Prefer a `gpt-5`, `claude-4-5`/`4-6`/`4-8`, or `gemini-2.5`/`3` family\n  gateway model unless the spec or the user states a cost or latency\n  constraint.\n- If the spec calls for low cost or latency, prefer the `mini`/`haiku`/`flash`\n  tier of that same family instead.\n- If no gateway entries appear at all (only `deployed` ones), recommend a\n  deployed entry instead and say why — the LLM Gateway is disabled or empty\n  on this instance, which is normal for an on-prem install, not an error.\n- **Still list every entry** per **Presenting choices** — mark the\n  recommended row (e.g. append \"(recommended)\") rather than omitting the\n  rest. Recommending never justifies narrowing the menu.\n- No `agent_spec.md`? Skip the read and recommend using only the\n  family-preference heuristics above.\n\n### Credential keys\n\n**Announce them up front** — do not let the user discover them via the sync\nerror message. Once the further choice is made, re-run\n`--option <selected_provider>` and\ntell the user exactly which keys they need and where the file lives:\n```\nFor <choice>, I'll need these values in a per-user credentials file:\n  ~/.config/datarobot/llm-<section>.env (or $XDG_CONFIG_HOME/...)\n\n  <KEY_1>\n  <KEY_2>\n  ...\nStep 3 will create that file as a blank template, with the help text for\neach key as a comment, if it doesn't exist. Please fill it in your own\neditor — do not paste the values in chat — then tell me \"credentials ready\"\nand I'll re-run the sync.\n```\nUse the section name the script reported for `<section>`. Do not create the\nfile yourself, do not `cat` it, and do not accept secret values in chat.\n---\n\n## Step 3 — Sync into `.env`\n\nFirst back up the current `.env` (sync overwrites it, and `.env` isn't in git):\n\n```shell\ncp .env .env.bak.$(date +%Y%m%d%H%M%S)\n```\n\nRun the sync script with the values collected in Step 2 as CLI args. No\nintermediate config file, no JSON to write.\n\n```shell\npython <skill_scripts_dir>/sync_llm_env.py \\\n  --infra-enable-llm <selected_gateway> \\\n  --set <ENV_NAME>=<value>\n```\nRepeat `--set` once per value, using the env var names the script printed in\nStep 2 — they carry a per-project prefix and are **not** always `LLM_*`. Add\n`--provider \"<selected_provider>\"` when Step 2 reported a further choice. Pass no\n`--set` for fields reported as `hidden`; the script writes their defaults.\nWhen the chosen option needs credentials, the script reads them from\n`$XDG_CONFIG_HOME/datarobot/llm-<section>.env`:\n- **If the file doesn't exist**, the script writes a blank template there\n  and exits with the path plus the required key list. Relay that verbatim\n  to the user, tell them to fill it in their own editor, then re-run the\n  same command. Do not offer to create the file for them and do not accept\n  values in chat.\n- **If the file exists but is incomplete**, the script prints the missing\n  keys and exits. Same instruction: user edits, then re-runs.\n- **If the file is complete**, the sync merges the credentials into `.env`\n  in one shot.\n---\n\n## Step 4 — Validate and hand off\n\n**`dr dotenv validate` echoes the full `.env` (including `DATAROBOT_API_TOKEN`)\nto stdout.** If you run it without redirection, the token lands in the chat\ntranscript and must be rotated. Same risk for `dr dotenv update`, `dr task run`,\n`dr run`, `cat .env`, `env | grep`, or any other command that reads `.env`.\n\nRun validation with all output suppressed and check only the exit code:\n\n```shell\ndr dotenv validate >/dev/null 2>&1\n```\n\n- **Exit 0** → tell the user validation passed.\n- **Non-zero exit** → do **not** re-run the command with output visible.\n  Tell the user to run `dr dotenv validate` themselves in their own terminal\n  so the error stays local.\nThen tell the user (do not run these yourself — they also echo secrets):\n```text\nLLM configuration synced to .env.\n\nPlease run these yourself in your terminal:\n  dr dotenv update          # refresh DataRobot token if needed\n  dr task run infra:up-yes  # push runtime params to deployment\n  dr run dev                # local test\n```\n---\n\n## Stale keys\n\n`sync_llm_env.py` derives its managed-key set from every env var declared\nanywhere in the project's config, so switching integrations clears whatever the\nprevious one wrote before the fresh block goes in. Non-LLM `.env` lines are\npreserved.\n"
}

SHA-256 of public snapshot: 0f12936cadc3ddcae0d03dba70fabb5c63d01541141c1227de73fb35a1733b30