Skip to content

docs(fern): custom Python/C API doc generator#1582

Open
ramakrishnap-nv wants to merge 45 commits into
mainfrom
docs-fern-native-api
Open

docs(fern): custom Python/C API doc generator#1582
ramakrishnap-nv wants to merge 45 commits into
mainfrom
docs-fern-native-api

Conversation

@ramakrishnap-nv

@ramakrishnap-nv ramakrishnap-nv commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Replaces the abandoned Fern `libraries:` native generation approach with a custom AST + Cython regex generator that properly handles NumPy docstrings, Cython enums, and `all`-based public API filtering.

Summary

  • Custom `extract_python_api.py`: AST parser for `.py` files, regex scanner for `.pyx` files, `all`-based public API filtering, `order` list for controlling symbol sequence, functions suppressed from `*_wrapper.pyx` files
  • MDX embed/symbol markers migrated from HTML `` to JSX `{/* */}` format so Fern can parse the pages
  • `all` added to 7 `init.py` files for clean public API surface
  • `VType`, `CType`, `sense`, `SolutionStatus` docstrings rewritten as NumPy `Attributes` sections so member descriptions render correctly
  • Symbol ordering matches existing RST docs (WaypointMatrix → Vehicle Routing → Assignment → utils/enums inline)
  • Auto-generated `fern/openapi/cuopt_spec.yaml` excluded from `verify-hardcoded-version` pre-commit hook

🤖 Generated with Claude Code

ramakrishnap-nv and others added 27 commits July 9, 2026 14:16
- fern/convert_docs.py: Python script that converts all 62 Sphinx/RST
  docs to Fern MDX, handles pandoc 2.9 note/warning divs → Fern
  callout components, resolves literalinclude → embedded code blocks,
  rewrites image paths to flat fern/docs/images/, strips Sphinx-only
  directives (toctree, install-selector, autodoc, breathe).
- fern/docs.yml: full navigation tree auto-generated from RST toctrees,
  with NVIDIA green accent colors and API Reference section.
- fern/fern.config.json: org=nvidia-cuopt, version=5.67.1.
- fern/docs/pages/**: 62 converted MDX pages.
- fern/docs/images/**: all doc images copied flat.
- .github/workflows/fern-docs.yml: CI that re-converts RST→MDX on push
  and runs fern check; publishes on docs-fern-migration branch merges.
- C/C++ Doxygen reference stubbed pending Fern C++ library support.

fern check: 0 errors, 2 warnings (auth redirect + minor color contrast).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fern/generators.yml: register OpenAPI spec (openapi/cuopt_spec.yaml)
  so fern check and fern generate --docs can serve the REST API reference
- fern/openapi/cuopt_spec.yaml: committed spec generated from FastAPI app
  without GPU (10 endpoints, 23 validated examples)
- fern/docs.yml: replace stub open-api page with a proper "api: REST API"
  nav entry that Fern renders as an interactive API reference
- fern/extract_python_api.py: AST-based Python docstring extractor (no
  imports, no GPU) generating MDX for routing, LP/QP, and MIP APIs;
  mirrors the classes/functions listed in the Sphinx autoclass:: directives
- fern/convert_docs.py: call OpenAPI generation + Python extraction from
  the main convert script so one command rebuilds everything
- .github/workflows/fern-docs.yml: add Python deps install step for
  OpenAPI spec generation; watch python/ source paths for changes

fern check: 0 errors, 8 warnings (7 are pre-existing OpenAPI example
mismatches in the FastAPI source; 1 is WCAG contrast auto-adjusted by Fern).

C/C++ Doxygen reference still stubbed pending Fern C++ library support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The custom .. install-selector:: Sphinx directive is now fully supported
in Fern by reusing the existing vanilla JS + CSS widget unchanged:

- fern/docs/scripts/install-selector.{js,css}: copied from Sphinx _static/
- fern/docs/scripts/cuopt-install-version.js: generated at build time by
  convert_docs.py from cuopt_server version (replaces the Sphinx conf.py
  build-time injection of window.CUOPT_INSTALL_VERSION)
- fern/docs.yml: css/js entries load the widget and version script on
  every page so the selector is available wherever the div is placed
- fern/convert_docs.py: preprocessor now emits
  <div id="cuopt-install-selector" data-default-iface="..."> via RST
  raw:: html instead of a plain-text note stub; version script generation
  added alongside the OpenAPI spec generation

Result: install.mdx and all 4 quick-start pages (python/c/server/cli)
render the full interactive install selector with correct version numbers
and interface pre-selection, identical to the Sphinx site.

fern check: 0 errors, 8 warnings (unchanged).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ersion

- Fix <Note> inside list items: un-indent opening tag to break out of
  list item context (MDX can't parse JSX inside list items when closing
  tag is at column 0)
- Convert .. dropdown:: RST directives to <Accordion> MDX components
  in preprocessor (was becoming <div class="dropdown"> which broke
  fenced code blocks inside)
- Add postprocessor fallback converting <div class="dropdown"> to
  <Accordion> for any that slip through pandoc
- Add libraries: section in docs.yml and DOCS_YML_HEADER for Fern
  C++ (cuopt-c-api) and Python (cuopt-python-api) library docs
- Add Doxyfile.fern to cpp/ (Fern's input.path for C++ parsing)
- Include generated Fern Python library docs (static/python-docs)
  as "Python Distance Engine" folder in API Reference nav section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MDX's JSX parser is stricter than CommonMark and fails on patterns that
are valid in plain Markdown. All 62+ pages now pass the MDX parser.

Fixes applied in convert_docs.py post-processor and extract_python_api.py:
- Angle-bracket autolinks: <https://...> and <email@...> → proper links
- Comparison operators: `<=` in text → `&lt;=` (MDX parses `<` as JSX)
- Curly-brace math notation: {<=, =, >=} → \{...\}
- Placeholder tags in code blocks: <CUOPT_IMAGE>, <ip> → HTML entities
- Shell redirects in code blocks: `</dev/null` → `< /dev/null`

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fern's server-side acorn processor rejects { } even inside fenced code
blocks, causing 500 errors on convex-features.mdx and milp-features.mdx.

- RST pre-processor (step 13): convert {<=, =, >=} math notation to
  (<=, =, >=) parenthesis form before pandoc — eliminates all { } from
  generated MDX
- Post-processor: simplify _escape_lt_outside_code now that { } are
  handled at the RST level
- Fix angle-bracket autolinks and email addresses → proper MD links
- All 62 MDX pages pass both MDX parse and Fern's acorn validation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…enAPI fixes

- Python API: prefix classes with 'class', methods/functions with 'def';
  use <hr /> separators between entries for visual scanning
- C API: extract_c_api.py now generates real content from headers (211 symbols);
  typedef entries labeled with 'typedef'; functions show bare prototype (no
  'function' prefix — matches cppreference/Doxygen convention); <hr /> separators
- Nav: index pages inside sections renamed to 'Overview' to eliminate duplicate
  section-name / page-name entries in the left nav
- REST API Reference moved under Server → Server API → Server API Overview
- OpenAPI spec post-processing: relax IdModel additionalProperties, fix
  health-endpoint examples (add error_result), fix incumbents examples
  (null cost/bound); prevents fern docs dev from exiting with code 1
- NVIDIA cuOpt logo SVGs added (dark/light variants)
- MutationObserver-based install selector widget for Next.js SPA timing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Converts the Sphinx/RST documentation to the Fern docs platform on the
docs-fern-migration branch.  Key changes across this session:

Conversion pipeline (fern/convert_docs.py, extract_*.py):
- Fix brace corruption: remove step 13 ({}→() broad replacement) and add
  prose-only { escaping that skips fenced code blocks and inline code spans
- Fix duplicate page headings: strip pandoc H1 BEFORE prepending frontmatter
  so the ^# regex anchors at the start of pandoc output, not after ---
- Fix inspect.cleandoc vs textwrap.dedent for Python docstring parsing so
  Parameters/Returns/Raises sections render correctly
- Fix .. dropdown:: dedent (textwrap.dedent instead of hardcoded 3-space strip)
  so list items inside Accordion blocks are flat, not nested
- Remove explicit H1 from extract_python_api.py and extract_c_api.py output
  (frontmatter title: is the heading; duplicate H1 caused double rendering)

Nav / docs.yml:
- Add _inject_nav_after, _rename_page, _remove_page helpers so curated nav
  fixes survive regeneration: REST API Reference after Server CLI, Settings
  pages under Python API, duplicate section/page names resolved, Swagger stub
  removed
- Split navigation into docs-v26-08.yml (required by Fern when versions is set)
- Add version switcher with all archived versions (26.06–25.05) pointing to
  archive.docs.nvidia.com via JS redirect pages

Install selector widget (fern/docs/scripts/install-selector.js):
- Full rewrite with lazy resolveVersion() and polling loop (150 ms, ~10 s)
  to survive Next.js async script injection race; pushState/replaceState hooks
  set up unconditionally

Python source (python/cuopt/cuopt/linear_programming/io/parser.py):
- Add NumPy-style docstring to toDict so it appears in the Python API reference

CI (.github/workflows/fern-docs.yml):
- Add cpp/**/*.h and cpp/**/*.hpp to path triggers (C API extractor reads headers)

build.sh:
- Replace old Sphinx/Doxygen docs target with Fern pipeline:
  checks for pandoc/node/jq, auto-installs pinned fern-api, runs
  convert_docs.py + fern check, prints fern docs dev command for preview

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add fern/requirements-docs.txt (fastapi, pydantic, pyyaml) as the single
  source of truth for Python docs dependencies; both build.sh and CI now
  install from it instead of inlining package names
- Update dependencies.yaml docs group: replace old Sphinx/Doxygen packages
  with Fern toolchain deps (jq, nodejs, pandoc, pyyaml, fastapi, pydantic)
  so conda environments include what ./build.sh docs actually needs
- build.sh: add npm presence check alongside node (npm is separate on some
  distros), with install hint pointing to nodejs.org and conda

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ./build.sh docs now runs convert_docs.py + fern check then launches
  fern docs dev (localhost:3000 preview) instead of just printing the command
- Add --publish-docs flag to publish to Fern cloud (nvidia-cuopt.docs.buildwithfern.com)
  via fern generate --docs; requires FERN_TOKEN env var, checked before running
- Add --publish-docs to VALIDARGS and help text

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- On every run: upload generated fern/docs.yml, docs-v*.yml, docs/pages/,
  and openapi/ as a GitHub Actions artifact (14-day retention) so reviewers
  can download and inspect exactly what will be published
- On pull_request: run fern generate --docs --preview to publish a temporary
  Fern preview URL that doesn't affect the live site; requires FERN_TOKEN
  secret, skipped silently if absent

Note: Fern has no native static HTML export — it is a Next.js SPA served via
Fern cloud. The artifact above contains the MDX source; the preview URL gives
a fully rendered browser view for sharing during PR review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New non-blocking link-check job runs after convert-and-check, concurrently
  with publish (continue-on-error: true so broken external links don't block
  the live site update — check the job summary for failures)
- Skips fern/docs/pages/versions/ (JS redirect stubs, no real links)
- fern/.lycheeignore excludes hosts that reliably cause false positives in CI:
  localhost, YouTube (429), LinkedIn (bot block), NGC catalog (auth required),
  Azure Maps sample (401), raw.githubusercontent.com (429 bursts)
- --accept 429 treats rate-limit responses as passing (not a dead link)
- Uploads lychee-report.md as a 14-day artifact on every run

Note: fern check validates config schema only; it does not check URLs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers prerequisites, ./build.sh docs local preview, manual publish with
FERN_TOKEN, and a table of what each CI trigger does — addresses the gap
Andrew pointed out ("samples in the readme").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-links

- Add `global-theme: nvidia` to docs.yml (mandatory for NVIDIA Fern branding)
- Add GitHub navbar link to docs.yml header
- Fix accentPrimary light color to match NVIDIA green (#76B900)
- CI: split PR preview into two stages so FERN_TOKEN is never exposed to
  fork PRs; stage 2 runs via workflow_run in base-branch context
- CI: add `fern docs broken-links` step for internal link checking
- CI: stage 1 saves PR metadata artifact so stage 2 can post preview comment
- README: document fern login requirement, how to get FERN_TOKEN, custom
  domain requirement, and two-stage PR preview security model

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MDX pages are now the source of truth. Removes:
- fern/convert_docs.py, extract_python_api.py, extract_c_api.py
- fern/requirements-docs.txt (pandoc, pyyaml, fastapi, pydantic)
- All conversion steps from build.sh and CI
- RST/C++/Python path triggers from CI (no longer affect docs)
- lychee link-check job (not needed for hand-edited MDX)
- pandoc/pyyaml/fastapi/pydantic from dependencies.yaml docs group

CI now: fern check + fern docs broken-links + PR preview + publish.
build.sh docs now: install fern CLI → fern check → fern docs dev.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OpenAPI spec, Python API reference, and C API reference are derived from
code and regenerated by fern/generate_api_docs.py on every docs build.
RST→MDX conversion is still gone; hand-edited MDX pages are not touched.

- Restore fern/extract_python_api.py and fern/extract_c_api.py
- Add fern/generate_api_docs.py (orchestrates the three dynamic outputs)
- Restore fern/requirements-docs.txt (fastapi, pydantic, pyyaml)
- build.sh docs: run generate_api_docs.py before fern check
- CI: install Python deps, run generate_api_docs.py, then fern check
- Re-add C++/Python source paths to CI triggers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ci/build_docs.sh: replace Sphinx build with Fern pipeline
  (conda env already provides jq, nodejs, pyyaml, fastapi, pydantic via
  rapids-dependency-file-generator; Fern CLI installed via npm at pinned version)
  Generates API docs, runs fern check, then publishes (preview on PR,
  production on branch/nightly)
- build.sh docs: skip pip install when packages already present (conda);
  fall back to pip only when importing fails
- build.yaml / pr.yaml: remove Sphinx html artifact upload; switch to
  cpu node type (no GPU needed for docs)
- Remove .github/workflows/fern-docs.yml (superseded by existing docs-build jobs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds explicit trigger to AGENTS.md so CI/workflow changes clearly map to
skills/cuopt-developer/ — surfacing the "prefer extending existing scripts"
rule before new workflow files or pip installs are created.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Python API: keep AST walking (no imports needed) but pipe docstrings
through numpydoc.docscrape.NumpyDocString, giving properly structured
Parameters / Returns / Raises / Examples sections in the generated MDX.

C API: replace fragile regex header parser with Doxygen XML pipeline.
Doxyfile targets the two public headers; XML is parsed with ElementTree
and rendered to MDX. Picks up 211 symbols vs ~80 before, handles @param,
@return, @brief, and enum values correctly.

Add numpydoc to requirements-docs.txt and dependencies.yaml docs group.
Add doxygen to dependencies.yaml docs group.
Gitignore cpp/build_split/ and fern/.doxygen-xml/ build directories.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tom parsers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Python API: replace hardcoded file paths with PAGE_SOURCES config — each
entry lists directories to scan non-recursively. New .py files added to a
configured directory appear in the docs automatically without editing the
script.

C API: replace RST parser with fern/c_api_config.yaml for section
organization. Doxygen XML is still the symbol source; the YAML controls
section groupings and prose. Symbols not in the config auto-appear in
an "Uncategorized" section on the designated catchall page so new header
additions are never silently dropped. Added previously uncategorized
symbols (hyper diving/heuristic params, scaling constants, presolve
constants, deprecated quad create functions).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copies example source files from docs/cuopt/source/ into
fern/docs/pages/*/examples/ so they live alongside the MDX pages
that reference them. The old docs/ tree is left intact for now.

Adds fern/embed_examples.py which embeds example files as fenced
code blocks into the *-examples.mdx pages using idempotent
<!-- embed: examples/file --> / <!-- /embed --> markers. First run
upgrades bare link stubs; subsequent runs refresh code content
within the markers without disturbing surrounding prose.

Rewrites the C API example pages (convex-examples.mdx,
mip-examples.mdx) to use clean standalone link patterns and removes
the repetitive Sphinx-era "It is necessary to have the path..." boilerplate.

embed_examples.py is called from generate_api_docs.py on every build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove:
- fern/.lycheeignore (lychee CI job was deleted)
- cpp/Doxyfile.fern and fern/Doxyfile.fern (remnants of abandoned
  fern docs md generate --local approach, superseded by fern/Doxyfile)
- fern/static/python-docs/ (auto-generated by fern docs md generate;
  replaced by extract_python_api.py)
- libraries: block from fern/docs.yml (referenced the deleted files)

Add distance_engine/ to the routing PAGE_SOURCES in extract_python_api.py
so WaypointMatrix is covered in the generated routing-api.mdx.
Remove the folder: ./static/python-docs nav entry from docs-v26-08.yml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move all Fern docs build steps (Node check, Fern CLI install, API doc
generation, fern check, publish/preview) out of build.sh into a dedicated
fern/build_docs.sh. build.sh now delegates to that script with a single call.

Also removes fern/requirements-docs.txt since the conda environment is always
activated before building, making the pip fallback unnecessary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MDX skeleton files (convex-c-api.mdx, mip-c-api.mdx) are now the source
of truth for page structure. Each symbol has a <!-- symbol: NAME --> marker
in its chosen location; the script fills in Doxygen content between markers.

If a symbol exists in the headers but has no marker in any skeleton, the
build errors with a list of unplaced symbols. This forces developers to
consciously place every new API symbol in the docs rather than silently
accumulating it in an uncategorized section.

Drops fern/c_api_config.yaml — structure now lives in the MDX files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- extract_python_api.py: add .pyx regex parser, __all__-based filtering,
  cross-file dedup, ordering via `order` list in PAGE_SOURCES, suppress
  headings for *_wrapper.pyx (enums-only, no functions), PascalCase enum
  member fix
- extract_c_api.py: migrate symbol markers from <!-- --> to {/* */} JSX
  comment format; accept legacy HTML form during migration
- embed_examples.py: same marker migration to {/* */}; remove dead
  `changed` variable assignments
- Add __all__ to 7 __init__.py files for clean public API surface
- Rewrite VType/CType/sense/SolutionStatus docstrings as NumPy Attributes
  sections so member descriptions render correctly
- PAGE_SOURCES ordering matches existing RST docs (WaypointMatrix first,
  then Vehicle Routing, Assignment, utils/enums inline)
- Exclude fern/openapi/cuopt_spec.yaml from verify-hardcoded-version hook
  (file is auto-generated from VERSION)
- Remove leftover fern/static/python-api/ (abandoned libraries: approach)
  and untracked .pyi stubs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ramakrishnap-nv
ramakrishnap-nv requested review from a team as code owners July 16, 2026 22:01
@ramakrishnap-nv
ramakrishnap-nv removed the request for review from a team July 16, 2026 22:01
@ramakrishnap-nv ramakrishnap-nv self-assigned this Jul 16, 2026
@ramakrishnap-nv
ramakrishnap-nv changed the base branch from docs-fern-migration to main July 16, 2026 22:02
@ramakrishnap-nv ramakrishnap-nv added doc Improvements or additions to documentation non-breaking Introduces a non-breaking change labels Jul 16, 2026
@ramakrishnap-nv ramakrishnap-nv added this to the 26.08 milestone Jul 16, 2026
- Add suppression comment for hardcoded version in docs.yml versions list
- Exclude auto-generated cuopt-install-version.js from verify-hardcoded-version
- Add missing copyright header to generate_api_docs.py
- Fix pydocstyle D407 in two example files (Note: → **Note:**)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

CI Test Summary

✅ 1 passed · 4 skipped · 8 cancelled / not completed

ramakrishnap-nv and others added 11 commits July 16, 2026 17:16
- fern/README.md: quick-start guide covering structure, local preview,
  generated vs hand-edited content, and how to add Python/C API symbols,
  examples, and nav entries
- skills/cuopt-developer/references/fern_docs.md: developer reference
  for maintaining Fern docs (symbol ordering, wrapper pyx rules, JSX
  markers, nav management, pre-commit notes)
- skills/cuopt-developer/SKILL.md: pointer to fern_docs.md reference
- fern/docs/pages/**/*.mdx: trailing-whitespace cleanup (whitespace only)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Delete docs/cuopt/ (201 files: 64 RST, 66 images, examples, conf.py, Makefile)
- Delete ci/test_doc_examples.sh and its call in test_wheel_cuopt_server.sh
- Delete ci/utils/update_doc_versions.py (updated versions1.json in deleted tree)
- Remove Sphinx package list from conda/environments/all_cuda-*.yaml (4 files)
- Remove docs file-key from dependencies.yaml (included full cuopt package set
  plus the docs dep group, used only for the Sphinx conda env)
- Remove docs-build CI jobs from pr.yaml and build.yaml; remove build_docs
  changed-file group and its exclusions from other trigger groups
- Update CONTRIBUTING.md gRPC section to point at fern/docs/pages/cuopt-grpc/
- Remove DOCS_BUILD_DIR from build.sh BUILD_DIRS; drop RST sed patches and
  update_doc_versions.py call from ci/release/update-version.sh

Fern (fern/) is now the sole documentation system.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update DOCS_ROOT from docs/cuopt/source to fern/docs/pages so the example
test suite runs against the Fern docs examples instead of the deleted RST tree.
Restore the call in ci/test_wheel_cuopt_server.sh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- .pre-commit-config.yaml: remove update-versions hook (called deleted
  ci/utils/update_doc_versions.py); remove two stale verify-hardcoded-version
  exclusion patterns for deleted docs/cuopt/ files
- .coderabbit.yaml: update docs suggestion from docs/cuopt/source/*.rst
  to fern/docs/pages/**/*.mdx

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ci/utils/update_fern_install_version.py: regenerates
  fern/docs/scripts/cuopt-install-version.js from VERSION file; replaces
  the portion of generate_api_docs.py that required cuopt_server importable
- ci/utils/update_fern_versions.py: adds a new version entry to fern/docs.yml
  version switcher on release, replacing the deleted update_doc_versions.py
  (which updated docs/cuopt/source/versions1.json)
- .pre-commit-config.yaml: add update-fern-install-version hook triggered
  by VERSION changes, replacing the removed update-versions hook
- ci/release/update-version.sh: call both new scripts on version bump

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…d_docs.sh

fern/build_docs.sh gains a --preview flag (runs fern generate --docs --preview)
for CI PR builds. ci/build_docs.sh now calls fern/build_docs.sh --preview or
--publish-docs instead of duplicating the Fern CLI install, generate_api_docs.py
invocation, and fern check steps inline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
build.sh gains --preview flag (passed through to fern/build_docs.sh).
ci/build_docs.sh now calls ./build.sh docs --preview or --publish-docs
instead of invoking fern/build_docs.sh directly, consistent with how
other ci/*.sh scripts delegate to build.sh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The full maintenance guide (local preview, adding symbols, adding examples,
nav, CI) is already in fern/README.md. Replace the stale multi-section block
with a single pointer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All tools (node, npm, jq, numpydoc, doxygen, Fern CLI) come from the
docs conda env or are installed automatically by build.sh. Remove any
separate install instructions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Took all main changes (grpc, mip, pdlp, routing deferred API, codecov, etc.)
- Restored docs-build CI job using CPU node + Fern triggers (not old Sphinx/GPU config)
- Updated build_docs changed-files group to ** + exclusions pattern (matching RAPIDS convention)
- Ported NIM operator guide files to fern/docs/pages/cuopt-server/nim-operator/guide/
  and added them to verify-hardcoded-version exclusions
- Fixed broken &ipython YAML anchor in dependencies.yaml (anchor was in removed docs block)
- Regenerated conda environment files via rapids-dependency-file-generator

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

Fern documentation migration

Layer / File(s) Summary
Documentation platform and build pipeline
.github/workflows/*, build.sh, ci/*, dependencies.yaml, fern/*, .pre-commit-config.yaml
Sphinx documentation paths and builds are replaced with Fern configuration, generation, preview/publication modes, version updates, and updated CI dependencies.
Generated API and installation tooling
fern/extract_*.py, fern/generate_api_docs.py, fern/embed_examples.py, fern/docs/scripts/*, python/cuopt/cuopt/*/__init__.py
OpenAPI, Python API, C API, examples, installation commands, and public Python exports are generated or explicitly configured for Fern.
C and Python documentation content
fern/docs/pages/cuopt-c/*, fern/docs/pages/cuopt-python/*, fern/docs-v26-08.yml
C API, Python API, optimization settings, examples, routing references, and navigation are added as MDX pages and runnable examples.
Service, CLI, gRPC, and deployment documentation
fern/docs/pages/cuopt-cli/*, fern/docs/pages/cuopt-grpc/*, fern/docs/pages/cuopt-server/*, fern/openapi/*
CLI, gRPC remote execution, REST server, NIM Operator deployment, OpenAPI, FAQs, release notes, requirements, resources, and archived-version redirects are documented.
Legacy Sphinx content removal and contributor guidance
docs/cuopt/*, README.md, CONTRIBUTING.md, AGENTS.md, skills/cuopt-developer/*
Legacy Sphinx files and pages are removed, while contributor and developer guidance points to Fern documentation workflows.

Estimated code review effort: 5 (Critical) | ~120 minutes

Suggested labels: improvement

Suggested reviewers: msarahan, iroy30

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 49.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main Fern documentation generator work, including Python and C API generation.
Description check ✅ Passed The description matches the changeset and describes the custom doc generators, API filtering, and doc formatting updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs-fern-native-api

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
dependencies.yaml (1)

6-22: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Keep files.docs or update the docs build consumer

ci/build_docs.sh:26 still calls rapids-dependency-file-generator --file-key docs, so removing this target breaks docs environment generation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@dependencies.yaml` around lines 6 - 22, Preserve the files.docs target in the
dependency configuration so ci/build_docs.sh can continue resolving the docs
environment with the docs file key; alternatively, update that consumer and all
related references to use an existing target, but keep docs environment
generation functional.
fern/docs/pages/index.mdx (1)

1-4: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not publish placeholder-only documentation pages.

Both routes contain only frontmatter and would render without user-facing content.

  • fern/docs/pages/index.mdx#L1-L4: add landing-page content or confirm another configured homepage replaces it.
  • fern/docs/pages/license.mdx#L1-L4: restore the license text or link to the authoritative license page.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/index.mdx` around lines 1 - 4, Replace the placeholder-only
page at fern/docs/pages/index.mdx:1-4 with landing-page content, or confirm and
configure another homepage to replace it. Also update
fern/docs/pages/license.mdx:1-4 by restoring the license text or linking to the
authoritative license page; both affected pages must contain meaningful
user-facing content.
🟠 Major comments (26)
ci/utils/update_fern_install_version.py-16-33 (1)

16-33: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add regression tests for both VERSION transformers.

These new scripts rewrite tracked Fern artifacts but have no coverage for normal and duplicate-version behavior.

  • ci/utils/update_fern_install_version.py#L16-L33: test the generated {conda, pip} JavaScript values.
  • ci/utils/update_fern_versions.py#L21-L59: test insertion, latest-entry demotion, and idempotent duplicate handling.

As per coding guidelines, “Add unit tests for code contributions.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ci/utils/update_fern_install_version.py` around lines 16 - 33, The VERSION
transformer scripts lack regression coverage. Add unit tests for
ci/utils/update_fern_install_version.py lines 16-33 verifying generated conda
and pip JavaScript values, and for ci/utils/update_fern_versions.py lines 21-59
covering version insertion, demotion of the latest entry, and idempotent
duplicate handling.

Source: Coding guidelines

python/cuopt/cuopt/linear_programming/solution/__init__.py-4-6 (1)

4-6: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Bind every name listed in __all__.

Line [6] exports PDLPWarmStartData, but Line [4] imports only Solution. Consumers resolving __all__—including wildcard imports or API extraction—can fail with a missing attribute. Import PDLPWarmStartData from .solution, or remove it from __all__.

Proposed fix
-from .solution import Solution
+from .solution import PDLPWarmStartData, Solution
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cuopt/cuopt/linear_programming/solution/__init__.py` around lines 4 -
6, Update the solution package exports so every name in __all__ is bound: import
PDLPWarmStartData alongside Solution from .solution, or remove PDLPWarmStartData
from __all__ if it is not intended to be public.
fern/docs/pages/cuopt-grpc/index.mdx-11-11 (1)

11-11: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Include custom clients in the gRPC description.

Line 5 explicitly supports custom programs, but this sentence says gRPC is only for bundled native clients. Clarify that gRPC supports both native APIs and custom clients implementing CuOptRemoteService.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-grpc/index.mdx` at line 11, Update the gRPC description
sentence to state that gRPC supports both NVIDIA cuOpt’s native APIs and custom
clients implementing CuOptRemoteService, while preserving the distinction from
the HTTP/JSON REST self-hosted server.
fern/docs/pages/milp-features.mdx-67-73 (1)

67-73: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Correct the MILP time-limit semantics.

This page says the default solve ends when “a solution is found” and that time_limit applies only inside the LP solver. A feasible MIP solution can be found before optimality, and this contradicts the optimal-solution wording in fern/docs/pages/mip-settings.mdx Line 20. Document the full MILP solve semantics accurately.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/milp-features.mdx` around lines 67 - 73, Update the “Time
Limit” section in milp-features.mdx to state that, by default, the solver runs
until it proves an optimal solution or determines the problem is infeasible or
unbounded; finding a feasible solution alone is not sufficient. Clarify that
time_limit bounds the full MILP solve operation, including solver-side work
needed for optimization, while excluding network transfer, input validation, and
other external operations.
fern/docs/pages/cuopt-server/client-api/sh-cli-api.mdx-5-5 (1)

5-5: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Provide the API reference content or its canonical link.

This page is published as an API reference but only tells readers to install the package; it exposes neither client methods nor a link to their reference documentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/client-api/sh-cli-api.mdx` at line 5, Update the
sh-cli API reference page content associated with the Note to include the
cuopt-sh-client API methods and usage details, or replace the placeholder with
the canonical link to the package’s reference documentation. Ensure the
published page provides direct API reference content rather than only
installation guidance.
fern/docs/pages/cuopt-server/client-api/sh-cli-build.mdx-17-29 (1)

17-29: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add the promised request examples.

The page describes commands and response examples but includes none. Add a server command plus working curl examples for inline JSON and file payloads, including the expected response shape.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/client-api/sh-cli-build.mdx` around lines 17 -
29, Add the missing cuOpt server startup command and executable curl examples in
the sections following the requestBody description, covering both inline JSON
and file-based payloads. Include representative JSON input and the expected
success response shape, and ensure the file example uses the configured
data/result directories and matches the documented /cuopt/request endpoint.
fern/docs/pages/cuopt-grpc/quick-start.mdx-23-47 (1)

23-47: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore the executable setup commands.

These sections promise binary verification, bare-metal/Docker server startup, and client environment setup, but contain no commands. Users cannot complete the quick start.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-grpc/quick-start.mdx` around lines 23 - 47, Restore the
missing executable command examples in the quick-start sections: add commands to
verify the installed server binary, launch the bare-metal gRPC server with the
documented default port and override, run the Docker entrypoint and
explicit-binary modes using the selected CUOPT_IMAGE, and configure the client
endpoint environment. Keep the commands consistent with the surrounding
CUOPT_SERVER_TYPE, port, GPU, and TLS documentation.
fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx-39-41 (1)

39-41: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Correct the persistent-storage prerequisite.

This says storage is required, but fern/docs/pages/cuopt-server/nim-operator/configuration.mdx states that storage is optional when requests use the default HTTP transfer mode. Clarify when persistent storage is actually needed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx` around lines 39
- 41, Update the “Storage Provisioner” section in the prerequisites
documentation to clarify that persistent storage is optional when requests use
the default HTTP transfer mode, and required only for configurations that depend
on persistent storage. Align the wording with the behavior documented in the
configuration page.
fern/docs/pages/cuopt-server/nim-operator/index.mdx-9-14 (1)

9-14: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not promise unsupported cuOpt service scaling.

This page says the operator handles scaling, while fern/docs/pages/cuopt-server/nim-operator/configuration.mdx states that the cuOpt service supports only one pod and does not support scaling. Clarify that the operator manages lifecycle operations, but horizontal scaling of the cuOpt service is currently unsupported.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/nim-operator/index.mdx` around lines 9 - 14,
Update the “Automated lifecycle management” bullet in the NIM Operator overview
to avoid claiming cuOpt service scaling; describe lifecycle management as
handling operations such as updates and health checks, and explicitly state that
horizontal scaling of the cuOpt service is currently unsupported.
fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx-85-94 (1)

85-94: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not expose NGC API keys in verification instructions.

  • fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx#L85-L94: replace echo $NGC_API_KEY with a non-disclosing check such as test -n "$NGC_API_KEY" && echo "NGC_API_KEY is set".
  • fern/docs/pages/faq.mdx#L25-L29: document secure storage in a secret manager and do not advise users to casually store or regenerate credentials without explaining safe handling.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx` around lines 85
- 94, Update the verification checklist in
fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx lines 85-94 to check
whether NGC_API_KEY is set without printing its value. Update
fern/docs/pages/faq.mdx lines 25-29 to document secure storage in a secret
manager and avoid casually recommending credential storage or regeneration
without safe-handling guidance.
fern/docs/pages/cuopt-server/examples/routing-examples.mdx-13-18 (1)

13-18: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Restore the operational command, code, and output blocks dropped during the migration.

These sections contain headings or promises followed by empty content, so users cannot execute the deployment, configuration, CLI, smoke-test, health-check, or troubleshooting workflows.

  • fern/docs/pages/cuopt-server/examples/routing-examples.mdx#L13-L18, L27-L50, L57-L72: restore response, HTTPS, and CLI examples.
  • fern/docs/pages/cuopt-server/nim-operator/deployment.mdx#L7-L75, L82-L102: restore deployment, verification, testing, cleanup, and troubleshooting commands.
  • fern/docs/pages/cuopt-server/nim-operator/configuration.mdx#L18-L45, L48-L80: provide concrete resource, networking, probe, monitoring, and full-configuration examples.
  • fern/docs/pages/cuopt-server/nim-operator/index.mdx#L28-L44: restore executable quick-start steps and documentation links.
  • fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx#L25-L68, L74-L93: restore GPU Operator, NIM Operator, and credential setup commands.
  • fern/docs/pages/cuopt-server/quick-start.mdx#L44-L60: restore the server-start, curl, and expected-response examples.
  • fern/docs/pages/faq.mdx#L127-L163: restore local/remote health-check and certificate-inspection commands.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/routing-examples.mdx` around lines 13 -
18, Restore the missing operational content across all affected documentation
sections: in fern/docs/pages/cuopt-server/examples/routing-examples.mdx ranges
13-18, 27-50, and 57-72, add the response, HTTPS, and CLI examples; in
fern/docs/pages/cuopt-server/nim-operator/deployment.mdx ranges 7-75 and 82-102,
restore deployment, verification, testing, cleanup, and troubleshooting
commands; in fern/docs/pages/cuopt-server/nim-operator/configuration.mdx ranges
18-45 and 48-80, add concrete resource, networking, probe, monitoring, and
full-configuration examples; in
fern/docs/pages/cuopt-server/nim-operator/index.mdx range 28-44, restore
executable quick-start steps and links; in
fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx ranges 25-68 and
74-93, restore GPU Operator, NIM Operator, and credential setup commands; in
fern/docs/pages/cuopt-server/quick-start.mdx range 44-60, restore server-start,
curl, and expected-response examples; and in fern/docs/pages/faq.mdx range
127-163, restore local and remote health-check plus certificate-inspection
commands. Replace every empty promised section with complete, executable
documentation and corresponding output where applicable.
fern/docs/pages/cuopt-cli/quick-start.mdx-11-15 (1)

11-15: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Complete the runnable command and output sections before publishing the pages.

The migration leaves prose that promises commands or output while the corresponding MDX content is empty, making these workflows non-actionable.

  • fern/docs/pages/cuopt-cli/quick-start.mdx#L11-L15: add the actual cuopt_cli --help command and expected result.
  • fern/docs/pages/cuopt-grpc/advanced.mdx#L46-L78: add runnable plain-TLS, mTLS, and private-CA commands.
  • fern/docs/pages/cuopt-grpc/advanced.mdx#L92-L105: add Docker invocation and client environment examples.
  • fern/docs/pages/cuopt-cli/cli-examples.mdx#L20-L35: add representative output blocks or remove the claims that output follows.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-cli/quick-start.mdx` around lines 11 - 15, Add the
missing actionable MDX content at all four sites: in
fern/docs/pages/cuopt-cli/quick-start.mdx lines 11-15, include a runnable
cuopt_cli --help command and representative expected output; in
fern/docs/pages/cuopt-grpc/advanced.mdx lines 46-78, add runnable plain-TLS,
mTLS, and private-CA commands; in fern/docs/pages/cuopt-grpc/advanced.mdx lines
92-105, add Docker invocation and client environment examples; and in
fern/docs/pages/cuopt-cli/cli-examples.mdx lines 20-35, add representative
output blocks or remove claims that output follows.
fern/build_docs.sh-44-49 (1)

44-49: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not publish after silently skipping API generation.

If Python is unavailable, the script continues through validation and publication with stale generated pages. Treat the configured Python interpreter as required and exit nonzero instead of warning and continuing.

Proposed fix
 PY=${PYTHON:-python3}
-if command -v "${PY}" &>/dev/null; then
-    "${PY}" "${REPODIR}/fern/generate_api_docs.py"
-else
-    echo "  [WARN] Python not found; skipping API doc generation."
- fi
+if ! command -v "${PY}" &>/dev/null; then
+    echo "ERROR: Python is required for Fern API doc generation."
+    exit 1
+fi
+"${PY}" "${REPODIR}/fern/generate_api_docs.py"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/build_docs.sh` around lines 44 - 49, Update the Python availability
check in build_docs.sh to treat the configured interpreter variable PY as
required: when command -v "${PY}" fails, emit an error and exit nonzero instead
of warning and continuing. Preserve the existing API documentation generation
command when the interpreter is available.
fern/docs-v26-08.yml-60-93 (1)

60-93: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore the auto-generated Python API markers.

update_python_api_navigation() returns without updating when its exact BEGIN/END markers are absent. Future generated API pages will therefore not appear in navigation. Add the documented markers around the generator-owned entries.

Based on the generator contract in fern/extract_python_api.py:730-795 and fern/README.md:69-71.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs-v26-08.yml` around lines 60 - 93, In the navigation configuration
around the generator-owned Python API entries for Routing, Convex Optimization,
and MIP, restore the exact documented BEGIN and END markers expected by
update_python_api_navigation(). Place each marker around the entries maintained
by the generator, matching the contract in extract_python_api.py and the
documented marker format without changing unrelated navigation content.
fern/docs/pages/cuopt-c/convex/examples/mps_file_example.c-125-149 (1)

125-149: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not assume every successful solve has a primal solution. Infeasible and unbounded results are valid termination outcomes, but both examples proceed into objective/primal retrieval.

  • fern/docs/pages/cuopt-c/convex/examples/mps_file_example.c#L125-L149: gate objective allocation and primal retrieval by termination status.
  • fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c#L118-L140: apply the same gating used by the MILP file example.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-c/convex/examples/mps_file_example.c` around lines 125
- 149, Gate objective-value retrieval, allocation, and primal-solution retrieval
on a termination status that guarantees a primal solution, matching the existing
MILP file example behavior. Apply this change in mps_file_example.c around
cuOptGetObjectiveValue and cuOptGetPrimalSolution, and in lp_file_example.c
around the corresponding retrieval flow; preserve termination reporting and
avoid accessing solution values for infeasible or unbounded outcomes.
fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c-139-140 (1)

139-140: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle solution-buffer allocation failures consistently. Some examples pass NULL to cuOpt; the others return success after allocation failure.

  • fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c#L139-L140: check solution_values and set CUOPT_OUT_OF_MEMORY.
  • fern/docs/pages/cuopt-c/convex/examples/mps_file_example.c#L148-L149: check solution_values and set CUOPT_OUT_OF_MEMORY.
  • fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c#L167-L170: set status = CUOPT_OUT_OF_MEMORY before cleanup.
  • fern/docs/pages/cuopt-c/convex/examples/rotated_socp_example.c#L163-L166: set the allocation failure status.
  • fern/docs/pages/cuopt-c/convex/examples/simple_lp_example.c#L190-L193: set the allocation failure status.
  • fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c#L183-L186: set the allocation failure status.
  • fern/docs/pages/cuopt-c/mip/examples/simple_milp_example.c#L170-L173: set the allocation failure status.
  • fern/docs/pages/cuopt-c/convex/convex-examples.mdx#L1076-L1079: fix fern/docs/pages/cuopt-c/convex/examples/simple_socp_example.c, then regenerate the embed.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c` around lines 139 -
140, Handle solution_values allocation failures consistently: in
fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c:139-140 and
fern/docs/pages/cuopt-c/convex/examples/mps_file_example.c:148-149, check the
allocation before calling cuOptGetPrimalSolution and set status to
CUOPT_OUT_OF_MEMORY; in
fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c:167-170,
fern/docs/pages/cuopt-c/convex/examples/rotated_socp_example.c:163-166,
fern/docs/pages/cuopt-c/convex/examples/simple_lp_example.c:190-193,
fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c:183-186, and
fern/docs/pages/cuopt-c/mip/examples/simple_milp_example.c:170-173, set the
allocation-failure status before cleanup; apply the same fix to
simple_socp_example.c and regenerate its embed in
fern/docs/pages/cuopt-c/convex/convex-examples.mdx:1076-1079.
fern/docs/pages/convex-features.mdx-61-63 (1)

61-63: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore the missing equations and convert the leftover RST syntax
fern/docs/pages/convex-features.mdx:61-63, 81, 113-115, 121 leaves the objective, quadratic-constraint, and cone definitions incomplete; the raw .note: and :c markup will render incorrectly in Fern MDX.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/convex-features.mdx` around lines 61 - 63, Restore the
missing mathematical equations for the cuOpt quadratic objective, quadratic
constraints, and cone definitions, preserving the documented notation for Q and
H. Convert the remaining RST directives such as “.note:” and “:c” into valid
Fern MDX/Markdown syntax so they render correctly, while keeping the surrounding
explanations unchanged.
fern/generate_api_docs.py-105-109 (1)

105-109: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Fail the build when OpenAPI generation fails.

This swallows import, schema-generation, and write failures, then main() continues and reports success. That can publish the previous OpenAPI spec and install version instead of the current server contract. Print the guidance, then re-raise so the docs build exits nonzero.

Proposed fix
     except Exception as e:
         print(f"  [WARN] Could not generate OpenAPI spec: {e}")
         print(
             "         Ensure cuopt_server is installed: pip install -e python/cuopt_server --no-deps"
         )
+        raise
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/generate_api_docs.py` around lines 105 - 109, Update the OpenAPI
generation exception handler in main() to retain the existing warning and
installation guidance, then re-raise the caught exception instead of swallowing
it. Ensure import, schema-generation, and write failures propagate so the
documentation build exits nonzero and cannot report success.
fern/docs/pages/cuopt-python/convex/convex-api.mdx-488-497 (1)

488-497: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not HTML-escape operators inside fenced Python examples.

The generated snippets contain &lt;=, so copied examples are invalid Python. Preserve raw <= within code fences and regenerate the page.

Example correction
->>> problem.addConstraint(2*x - 3*y &lt;= 10, name="Constr1")
+>>> problem.addConstraint(2*x - 3*y <= 10, name="Constr1")

Also applies to: 564-572, 591-598

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-python/convex/convex-api.mdx` around lines 488 - 497,
Update the fenced Python examples in the convex API documentation, including the
snippets around problem.addConstraint, to use raw comparison operators such as
<= instead of HTML entities like &lt;=. Apply the same correction to the
additionally referenced examples and regenerate the page so copied snippets
remain valid Python.
fern/docs/pages/cuopt-python/convex/convex-api.mdx-943-947 (1)

943-947: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Stop the .pyx signature scan at the function header.
get_solver_setting() is rendered with its body and the following cpdef get_solver_parameter_names() because the scanner keeps appending lines until it sees a colon anywhere. Trim the collected signature to the declaration only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-python/convex/convex-api.mdx` around lines 943 - 947,
Update the scanner that collects the get_solver_setting declaration so it stops
at the function header’s colon rather than continuing through the body and
following cpdef declaration. Trim the collected text to the header only while
preserving the existing signature rendering behavior for other declarations.
fern/docs/pages/cuopt-python/routing/routing-api.mdx-1514-1546 (1)

1514-1546: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the BatchSolve return contract in the routing docs.
BatchSolve returns only the solutions list, so fern/docs/pages/cuopt-python/routing/routing-api.mdx#L1514-L1546 should stop documenting (solutions, solve_time) and remove the tuple unpacking example. The batch examples already match this list-based contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-python/routing/routing-api.mdx` around lines 1514 -
1546, Update BatchSolve documentation in
fern/docs/pages/cuopt-python/routing/routing-api.mdx lines 1514-1546 to describe
and demonstrate that it returns only the solutions list; remove the tuple return
wording and change the example to avoid unpacking solve_time. The sibling
examples in fern/docs/pages/cuopt-python/routing/examples/tsp_batch_example.py
lines 38-47 and fern/docs/pages/cuopt-python/routing/routing-examples.mdx lines
244-288 already match the list-based contract and require no direct changes.
fern/embed_examples.py-101-122 (1)

101-122: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject unterminated generated-content markers before rewriting files.

Both refresh loops reach EOF, increment past it, and write the rebuilt prefix, silently deleting everything after an unmatched opening marker.

  • fern/embed_examples.py#L101-L122: verify a closing embed marker was found; otherwise raise with the MDX path and opening line.
  • fern/extract_c_api.py#L499-L520: perform the same validation before rendering or writing the skeleton.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/embed_examples.py` around lines 101 - 122, Validate that the refresh
loop in fern/embed_examples.py around the existing embed-marker handling
actually finds _CLOSE_NEW or _CLOSE_LEGACY before incrementing past EOF or
rewriting; otherwise raise an error containing the MDX path and opening-marker
line. Apply the same unterminated-marker validation in the skeleton refresh loop
in fern/extract_c_api.py around lines 499-520, before rendering or writing
output.
fern/embed_examples.py-134-141 (1)

134-141: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Complete the contracts for new public Python functions.

Add return annotations and meaningful parameter/return/raise documentation, or make genuinely internal helpers private.

  • fern/embed_examples.py#L134-L141: annotate and document embed_all.
  • fern/extract_c_api.py#L232-L246: document parse_headers return value and raised failures.
  • fern/extract_c_api.py#L536-L571: annotate and document generate_pages.
  • fern/extract_python_api.py#L589-L609: add a return annotation and complete write_api_page documentation.
  • fern/extract_python_api.py#L757-L782: document generated_pages and behavior for update_python_api_navigation.
  • fern/extract_python_api.py#L790-L830: annotate and document generate_pages.

As per coding guidelines, “Require type hints on new public Python functions and classes” and “Document new public Python APIs with meaningful docstring content covering parameters, returns, and raises.”
As per path instructions, focus on type hints and docstring content for new public Python APIs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/embed_examples.py` around lines 134 - 141, Complete the public API
contracts at fern/embed_examples.py:134-141 by adding a return annotation and
meaningful docstring for embed_all; at fern/extract_c_api.py:232-246 document
parse_headers’ return value and raised failures, and at
fern/extract_c_api.py:536-571 add type annotations and parameter/return/raise
documentation for generate_pages; at fern/extract_python_api.py:589-609 add
write_api_page’s return annotation and complete documentation, at
fern/extract_python_api.py:757-782 document generated_pages and
update_python_api_navigation’s behavior, and at
fern/extract_python_api.py:790-830 add type annotations and meaningful
parameter/return/raise documentation for generate_pages.

Sources: Coding guidelines, Path instructions

fern/extract_c_api.py-541-562 (1)

541-562: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Fail when skeleton markers reference removed symbols.

Validation only checks symbols - all_placed. A removed or renamed C API therefore remains published as “documentation not found in headers.” Also reject all_placed - symbols before rewriting pages.

Proposed validation
     if missing:
         ...
         sys.exit(1)
+
+    stale = sorted(name for name in all_placed if name not in symbols)
+    if stale:
+        print(
+            "\nERROR: MDX skeleton markers reference symbols absent from the headers:\n"
+            + "\n".join(f"  - {name}" for name in stale),
+            file=sys.stderr,
+        )
+        sys.exit(1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/extract_c_api.py` around lines 541 - 562, Update the validation around
all_placed, symbols, and missing to also compute and reject marker names present
in all_placed but absent from symbols, excluding the same internal symbols and
prefixes as appropriate. Emit a clear error listing these stale markers and exit
before any page rewriting, while preserving the existing missing-symbol
validation.
fern/extract_python_api.py-617-661 (1)

617-661: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fail closed when use_init_all=True.

A missing, dynamic, or unparsable __all__ returns None, which disables filtering and exposes every discovered symbol. Raise an actionable error when filtering was explicitly requested.

Proposed fix
-    allowed_symbols: set[str] | None = (
-        _read_init_all(src_dir) if use_init_all else None
-    )
+    allowed_symbols: set[str] | None = None
+    if use_init_all:
+        allowed_symbols = _read_init_all(src_dir)
+        if allowed_symbols is None:
+            raise ValueError(
+                f"{src_dir}/__init__.py must define a literal __all__"
+            )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/extract_python_api.py` around lines 617 - 661, The _scan_dir path must
fail closed when use_init_all=True but _read_init_all cannot obtain a valid
__all__. Detect a None result after calling _read_init_all and raise an
actionable error identifying the directory and required __init__.py __all__
configuration; preserve the current optional filtering behavior when
use_init_all is false or a valid set is returned.
fern/docs/pages/cuopt-python/routing/examples/smoke_test_example.sh-37-49 (1)

37-49: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Assign the declared task locations to the model.
task_locations is unused here, so the solver falls back to the default location 0 instead of serving [1, 2, 3]. Call dm.set_order_locations(task_locations) before solving.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-python/routing/examples/smoke_test_example.sh` around
lines 37 - 49, Update the routing.DataModel setup to apply the declared
task_locations by calling dm.set_order_locations(task_locations) after adding
the matrices and before solving, ensuring tasks at locations 1, 2, and 3 are
served.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 25fee7d7-9cae-40c0-abfa-63890bfc944b

📥 Commits

Reviewing files that changed from the base of the PR and between 088dfec and 9688363.

⛔ Files ignored due to path filters (76)
  • docs/cuopt/source/cuopt-grpc/examples/remote_lp_demo.mps is excluded by !**/*.mps
  • docs/cuopt/source/cuopt-server/examples/lp/examples/sample.mps is excluded by !**/*.mps
  • docs/cuopt/source/cuopt-server/images/aws1.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/aws2.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/aws3.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/aws4.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/azure1.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/azure2.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/azure3.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/azure4.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/azure5.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/azure6.png is excluded by !**/*.png
  • docs/cuopt/source/cuopt-server/images/cuOpt-self-hosted.png is excluded by !**/*.png
  • docs/cuopt/source/images/aws1.png is excluded by !**/*.png
  • docs/cuopt/source/images/aws2.png is excluded by !**/*.png
  • docs/cuopt/source/images/aws3.png is excluded by !**/*.png
  • docs/cuopt/source/images/aws4.png is excluded by !**/*.png
  • docs/cuopt/source/images/azure1.png is excluded by !**/*.png
  • docs/cuopt/source/images/azure2.png is excluded by !**/*.png
  • docs/cuopt/source/images/azure3.png is excluded by !**/*.png
  • docs/cuopt/source/images/azure4.png is excluded by !**/*.png
  • docs/cuopt/source/images/azure5.png is excluded by !**/*.png
  • docs/cuopt/source/images/azure6.png is excluded by !**/*.png
  • docs/cuopt/source/images/cuOpt-self-hosted.png is excluded by !**/*.png
  • fern/docs/images/add_role.png is excluded by !**/*.png
  • fern/docs/images/aws1.png is excluded by !**/*.png
  • fern/docs/images/aws2.png is excluded by !**/*.png
  • fern/docs/images/aws3.png is excluded by !**/*.png
  • fern/docs/images/aws4.png is excluded by !**/*.png
  • fern/docs/images/azure1.png is excluded by !**/*.png
  • fern/docs/images/azure2.png is excluded by !**/*.png
  • fern/docs/images/azure3.png is excluded by !**/*.png
  • fern/docs/images/azure4.png is excluded by !**/*.png
  • fern/docs/images/azure5.png is excluded by !**/*.png
  • fern/docs/images/azure6.png is excluded by !**/*.png
  • fern/docs/images/cloud_functions.png is excluded by !**/*.png
  • fern/docs/images/cost_matrix.png is excluded by !**/*.png
  • fern/docs/images/cuOpt-managed.png is excluded by !**/*.png
  • fern/docs/images/cuOpt-self-hosted.png is excluded by !**/*.png
  • fern/docs/images/cuOpt_Collections_Image.png is excluded by !**/*.png
  • fern/docs/images/cuOpt_Stack.png is excluded by !**/*.png
  • fern/docs/images/cuopt_feature_diag.jpg is excluded by !**/*.jpg
  • fern/docs/images/cuopt_landing_page.png is excluded by !**/*.png
  • fern/docs/images/faq-01.png is excluded by !**/*.png
  • fern/docs/images/generate-personal-key.png is excluded by !**/*.png
  • fern/docs/images/genms_cuopt.png is excluded by !**/*.png
  • fern/docs/images/grpc-job-states.png is excluded by !**/*.png
  • fern/docs/images/grpc-process-model.png is excluded by !**/*.png
  • fern/docs/images/image1.png is excluded by !**/*.png
  • fern/docs/images/image2.png is excluded by !**/*.png
  • fern/docs/images/image3.png is excluded by !**/*.png
  • fern/docs/images/image4.png is excluded by !**/*.png
  • fern/docs/images/image5.png is excluded by !**/*.png
  • fern/docs/images/invite_user.png is excluded by !**/*.png
  • fern/docs/images/ms_cuopt.png is excluded by !**/*.png
  • fern/docs/images/nav-cloud-functions.png is excluded by !**/*.png
  • fern/docs/images/nav-landing-page.png is excluded by !**/*.png
  • fern/docs/images/nvidia-cuopt-logo-dark.svg is excluded by !**/*.svg
  • fern/docs/images/nvidia-cuopt-logo-light.svg is excluded by !**/*.svg
  • fern/docs/images/options_cuopt.png is excluded by !**/*.png
  • fern/docs/images/organization.png is excluded by !**/*.png
  • fern/docs/images/overview_cuopt.png is excluded by !**/*.png
  • fern/docs/images/route_map.png is excluded by !**/*.png
  • fern/docs/images/service_key_creation.png is excluded by !**/*.png
  • fern/docs/images/service_keys.png is excluded by !**/*.png
  • fern/docs/images/sh-cuOpt-stack.png is excluded by !**/*.png
  • fern/docs/images/shared_functions.png is excluded by !**/*.png
  • fern/docs/images/soft_stack.png is excluded by !**/*.png
  • fern/docs/images/users.png is excluded by !**/*.png
  • fern/docs/images/waypoint_graph.png is excluded by !**/*.png
  • fern/docs/pages/cuopt-c/convex/examples/qp_sample.mps is excluded by !**/*.mps
  • fern/docs/pages/cuopt-c/convex/examples/sample.lp is excluded by !**/*.lp
  • fern/docs/pages/cuopt-c/convex/examples/sample.mps is excluded by !**/*.mps
  • fern/docs/pages/cuopt-c/convex/examples/socp_sample.mps is excluded by !**/*.mps
  • fern/docs/pages/cuopt-c/mip/examples/mip_sample.mps is excluded by !**/*.mps
  • fern/docs/pages/cuopt-python/convex/examples/sample.mps is excluded by !**/*.mps
📒 Files selected for processing (247)
  • .coderabbit.yaml
  • .github/workflows/build.yaml
  • .github/workflows/pr.yaml
  • .gitignore
  • .pre-commit-config.yaml
  • AGENTS.md
  • CONTRIBUTING.md
  • README.md
  • build.sh
  • ci/build_docs.sh
  • ci/release/update-version.sh
  • ci/test_doc_examples.sh
  • ci/test_wheel_cuopt_server.sh
  • ci/utils/update_doc_versions.py
  • ci/utils/update_fern_install_version.py
  • ci/utils/update_fern_versions.py
  • conda/environments/all_cuda-129_arch-aarch64.yaml
  • conda/environments/all_cuda-129_arch-x86_64.yaml
  • conda/environments/all_cuda-133_arch-aarch64.yaml
  • conda/environments/all_cuda-133_arch-x86_64.yaml
  • dependencies.yaml
  • docs/cuopt/.editorconfig
  • docs/cuopt/Makefile
  • docs/cuopt/README.md
  • docs/cuopt/make.bat
  • docs/cuopt/source/_static/install-selector.js
  • docs/cuopt/source/_static/swagger-nvidia.css
  • docs/cuopt/source/conf.py
  • docs/cuopt/source/convex-features.rst
  • docs/cuopt/source/convex-settings.rst
  • docs/cuopt/source/cuopt-c/convex/convex-c-api.rst
  • docs/cuopt/source/cuopt-c/convex/convex-examples.rst
  • docs/cuopt/source/cuopt-c/convex/index.rst
  • docs/cuopt/source/cuopt-c/index.rst
  • docs/cuopt/source/cuopt-c/mip/index.rst
  • docs/cuopt/source/cuopt-c/mip/mip-c-api.rst
  • docs/cuopt/source/cuopt-c/mip/mip-examples.rst
  • docs/cuopt/source/cuopt-cli/cli-examples.rst
  • docs/cuopt/source/cuopt-cli/examples/lp/examples/basic_lp_example.sh
  • docs/cuopt/source/cuopt-cli/examples/lp/examples/solver_parameters_example.sh
  • docs/cuopt/source/cuopt-cli/examples/milp/examples/basic_milp_example.sh
  • docs/cuopt/source/cuopt-cli/index.rst
  • docs/cuopt/source/cuopt-cli/quick-start.rst
  • docs/cuopt/source/cuopt-grpc/advanced.rst
  • docs/cuopt/source/cuopt-grpc/api.rst
  • docs/cuopt/source/cuopt-grpc/examples.rst
  • docs/cuopt/source/cuopt-grpc/examples/remote_lp_demo.py
  • docs/cuopt/source/cuopt-grpc/index.rst
  • docs/cuopt/source/cuopt-grpc/quick-start.rst
  • docs/cuopt/source/cuopt-python/convex/convex-api.rst
  • docs/cuopt/source/cuopt-python/convex/convex-examples.rst
  • docs/cuopt/source/cuopt-python/convex/index.rst
  • docs/cuopt/source/cuopt-python/index.rst
  • docs/cuopt/source/cuopt-python/mip/index.rst
  • docs/cuopt/source/cuopt-python/mip/mip-api.rst
  • docs/cuopt/source/cuopt-python/mip/mip-examples.rst
  • docs/cuopt/source/cuopt-python/quick-start.rst
  • docs/cuopt/source/cuopt-python/routing/index.rst
  • docs/cuopt/source/cuopt-python/routing/routing-api.rst
  • docs/cuopt/source/cuopt-python/routing/routing-examples.rst
  • docs/cuopt/source/cuopt-server/client-api/index.rst
  • docs/cuopt/source/cuopt-server/client-api/sh-cli-api.rst
  • docs/cuopt/source/cuopt-server/client-api/sh-cli-build.rst
  • docs/cuopt/source/cuopt-server/csp-guides/csp-aws.rst
  • docs/cuopt/source/cuopt-server/csp-guides/csp-azure.rst
  • docs/cuopt/source/cuopt-server/csp-guides/index.rst
  • docs/cuopt/source/cuopt-server/examples/index.rst
  • docs/cuopt/source/cuopt-server/examples/lp-examples.rst
  • docs/cuopt/source/cuopt-server/examples/lp/examples/basic_lp_example.py
  • docs/cuopt/source/cuopt-server/examples/lp/examples/basic_lp_example.sh
  • docs/cuopt/source/cuopt-server/examples/lp/examples/batch_mode_example.sh
  • docs/cuopt/source/cuopt-server/examples/lp/examples/lp_datamodel_example.py
  • docs/cuopt/source/cuopt-server/examples/lp/examples/mps_datamodel_example.py
  • docs/cuopt/source/cuopt-server/examples/lp/examples/mps_file_example.py
  • docs/cuopt/source/cuopt-server/examples/lp/examples/warmstart_example.py
  • docs/cuopt/source/cuopt-server/examples/lp/examples/warmstart_example.sh
  • docs/cuopt/source/cuopt-server/examples/milp-examples.rst
  • docs/cuopt/source/cuopt-server/examples/milp/examples/abort_job_example.py
  • docs/cuopt/source/cuopt-server/examples/milp/examples/abort_job_example.sh
  • docs/cuopt/source/cuopt-server/examples/milp/examples/basic_milp_example.py
  • docs/cuopt/source/cuopt-server/examples/milp/examples/basic_milp_example.sh
  • docs/cuopt/source/cuopt-server/examples/milp/examples/incumbent_callback_example.py
  • docs/cuopt/source/cuopt-server/examples/routing-examples.rst
  • docs/cuopt/source/cuopt-server/examples/routing/examples/basic_routing_example.py
  • docs/cuopt/source/cuopt-server/examples/routing/examples/basic_routing_example.sh
  • docs/cuopt/source/cuopt-server/examples/routing/examples/initial_solution_example.py
  • docs/cuopt/source/cuopt-server/examples/routing/examples/initial_solution_example.sh
  • docs/cuopt/source/cuopt-server/index.rst
  • docs/cuopt/source/cuopt-server/nim-operator/configuration.rst
  • docs/cuopt/source/cuopt-server/nim-operator/deployment.rst
  • docs/cuopt/source/cuopt-server/nim-operator/guide/cuopt-nimservice-full.yaml
  • docs/cuopt/source/cuopt-server/nim-operator/guide/cuopt-nimservice.yaml
  • docs/cuopt/source/cuopt-server/nim-operator/guide/deploy.sh
  • docs/cuopt/source/cuopt-server/nim-operator/guide/namespace.yaml
  • docs/cuopt/source/cuopt-server/nim-operator/index.rst
  • docs/cuopt/source/cuopt-server/nim-operator/prerequisites.rst
  • docs/cuopt/source/cuopt-server/quick-start.rst
  • docs/cuopt/source/cuopt-server/server-api/index.rst
  • docs/cuopt/source/faq.rst
  • docs/cuopt/source/hidden/limitations.rst
  • docs/cuopt/source/hidden/mps-api.rst
  • docs/cuopt/source/hidden/mps-overview.rst
  • docs/cuopt/source/hidden/parser_example.rst
  • docs/cuopt/source/index.rst
  • docs/cuopt/source/install.rst
  • docs/cuopt/source/introduction.rst
  • docs/cuopt/source/license.rst
  • docs/cuopt/source/milp-features.rst
  • docs/cuopt/source/mip-settings.rst
  • docs/cuopt/source/open-api.rst
  • docs/cuopt/source/release-notes.md
  • docs/cuopt/source/resources.rst
  • docs/cuopt/source/routing-features.rst
  • docs/cuopt/source/system-requirements.rst
  • docs/cuopt/source/thirdparty_modeling_languages/index.rst
  • docs/cuopt/source/transition.rst
  • docs/cuopt/source/versions1.json
  • fern/Doxyfile
  • fern/README.md
  • fern/build_docs.sh
  • fern/docs-v25-05.yml
  • fern/docs-v25-08.yml
  • fern/docs-v25-12.yml
  • fern/docs-v26-02.yml
  • fern/docs-v26-04.yml
  • fern/docs-v26-06.yml
  • fern/docs-v26-08.yml
  • fern/docs.yml
  • fern/docs/pages/convex-features.mdx
  • fern/docs/pages/convex-settings.mdx
  • fern/docs/pages/cuopt-c-api-reference.mdx
  • fern/docs/pages/cuopt-c/convex/convex-c-api.mdx
  • fern/docs/pages/cuopt-c/convex/convex-examples.mdx
  • fern/docs/pages/cuopt-c/convex/examples/Makefile
  • fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c
  • fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c
  • fern/docs/pages/cuopt-c/convex/examples/mps_file_example.c
  • fern/docs/pages/cuopt-c/convex/examples/rotated_socp_example.c
  • fern/docs/pages/cuopt-c/convex/examples/simple_lp_example.c
  • fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c
  • fern/docs/pages/cuopt-c/convex/examples/simple_socp_example.c
  • fern/docs/pages/cuopt-c/convex/index.mdx
  • fern/docs/pages/cuopt-c/index.mdx
  • fern/docs/pages/cuopt-c/mip/examples/Makefile
  • fern/docs/pages/cuopt-c/mip/examples/milp_mps_example.c
  • fern/docs/pages/cuopt-c/mip/examples/simple_milp_example.c
  • fern/docs/pages/cuopt-c/mip/index.mdx
  • fern/docs/pages/cuopt-c/mip/mip-c-api.mdx
  • fern/docs/pages/cuopt-c/mip/mip-examples.mdx
  • fern/docs/pages/cuopt-c/quick-start.mdx
  • fern/docs/pages/cuopt-cli/cli-examples.mdx
  • fern/docs/pages/cuopt-cli/index.mdx
  • fern/docs/pages/cuopt-cli/quick-start.mdx
  • fern/docs/pages/cuopt-grpc/advanced.mdx
  • fern/docs/pages/cuopt-grpc/api.mdx
  • fern/docs/pages/cuopt-grpc/examples.mdx
  • fern/docs/pages/cuopt-grpc/grpc-server-architecture.mdx
  • fern/docs/pages/cuopt-grpc/index.mdx
  • fern/docs/pages/cuopt-grpc/quick-start.mdx
  • fern/docs/pages/cuopt-python/convex/convex-api.mdx
  • fern/docs/pages/cuopt-python/convex/convex-examples.mdx
  • fern/docs/pages/cuopt-python/convex/examples/expressions_constraints_example.py
  • fern/docs/pages/cuopt-python/convex/examples/general_quadratic_example.py
  • fern/docs/pages/cuopt-python/convex/examples/mps_example.py
  • fern/docs/pages/cuopt-python/convex/examples/pdlp_warmstart_example.py
  • fern/docs/pages/cuopt-python/convex/examples/production_planning_example.py
  • fern/docs/pages/cuopt-python/convex/examples/qp_matrix_example.py
  • fern/docs/pages/cuopt-python/convex/examples/rotated_socp_example.py
  • fern/docs/pages/cuopt-python/convex/examples/simple_lp_example.py
  • fern/docs/pages/cuopt-python/convex/examples/simple_qp_example.py
  • fern/docs/pages/cuopt-python/convex/examples/simple_socp_example.py
  • fern/docs/pages/cuopt-python/convex/examples/solution_example.py
  • fern/docs/pages/cuopt-python/convex/index.mdx
  • fern/docs/pages/cuopt-python/index.mdx
  • fern/docs/pages/cuopt-python/mip/examples/incumbent_solutions_example.py
  • fern/docs/pages/cuopt-python/mip/examples/semi_continuous_example.py
  • fern/docs/pages/cuopt-python/mip/examples/simple_milp_example.py
  • fern/docs/pages/cuopt-python/mip/index.mdx
  • fern/docs/pages/cuopt-python/mip/mip-api.mdx
  • fern/docs/pages/cuopt-python/mip/mip-examples.mdx
  • fern/docs/pages/cuopt-python/quick-start.mdx
  • fern/docs/pages/cuopt-python/routing/examples/intra_factory_example.py
  • fern/docs/pages/cuopt-python/routing/examples/smoke_test_example.sh
  • fern/docs/pages/cuopt-python/routing/examples/tsp_batch_example.py
  • fern/docs/pages/cuopt-python/routing/index.mdx
  • fern/docs/pages/cuopt-python/routing/routing-api.mdx
  • fern/docs/pages/cuopt-python/routing/routing-examples.mdx
  • fern/docs/pages/cuopt-server/client-api/index.mdx
  • fern/docs/pages/cuopt-server/client-api/sh-cli-api.mdx
  • fern/docs/pages/cuopt-server/client-api/sh-cli-build.mdx
  • fern/docs/pages/cuopt-server/csp-guides/csp-aws.mdx
  • fern/docs/pages/cuopt-server/csp-guides/csp-azure.mdx
  • fern/docs/pages/cuopt-server/csp-guides/index.mdx
  • fern/docs/pages/cuopt-server/examples/index.mdx
  • fern/docs/pages/cuopt-server/examples/lp-examples.mdx
  • fern/docs/pages/cuopt-server/examples/milp-examples.mdx
  • fern/docs/pages/cuopt-server/examples/routing-examples.mdx
  • fern/docs/pages/cuopt-server/index.mdx
  • fern/docs/pages/cuopt-server/nim-operator/configuration.mdx
  • fern/docs/pages/cuopt-server/nim-operator/deployment.mdx
  • fern/docs/pages/cuopt-server/nim-operator/index.mdx
  • fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx
  • fern/docs/pages/cuopt-server/quick-start.mdx
  • fern/docs/pages/cuopt-server/server-api/index.mdx
  • fern/docs/pages/cuopt-server/server-api/server-cli.mdx
  • fern/docs/pages/faq.mdx
  • fern/docs/pages/index.mdx
  • fern/docs/pages/install.mdx
  • fern/docs/pages/introduction.mdx
  • fern/docs/pages/license.mdx
  • fern/docs/pages/milp-features.mdx
  • fern/docs/pages/mip-settings.mdx
  • fern/docs/pages/open-api.mdx
  • fern/docs/pages/release-notes.mdx
  • fern/docs/pages/resources.mdx
  • fern/docs/pages/routing-features.mdx
  • fern/docs/pages/system-requirements.mdx
  • fern/docs/pages/thirdparty_modeling_languages/index.mdx
  • fern/docs/pages/transition.mdx
  • fern/docs/pages/versions/v25-05.mdx
  • fern/docs/pages/versions/v25-08.mdx
  • fern/docs/pages/versions/v25-12.mdx
  • fern/docs/pages/versions/v26-02.mdx
  • fern/docs/pages/versions/v26-04.mdx
  • fern/docs/pages/versions/v26-06.mdx
  • fern/docs/scripts/cuopt-install-version.js
  • fern/docs/scripts/install-selector.css
  • fern/docs/scripts/install-selector.js
  • fern/embed_examples.py
  • fern/extract_c_api.py
  • fern/extract_python_api.py
  • fern/fern.config.json
  • fern/generate_api_docs.py
  • fern/generators.yml
  • fern/openapi/cuopt_spec.yaml
  • python/cuopt/cuopt/distance_engine/__init__.py
  • python/cuopt/cuopt/linear_programming/__init__.py
  • python/cuopt/cuopt/linear_programming/data_model/__init__.py
  • python/cuopt/cuopt/linear_programming/io/__init__.py
  • python/cuopt/cuopt/linear_programming/io/parser.py
  • python/cuopt/cuopt/linear_programming/problem.py
  • python/cuopt/cuopt/linear_programming/solution/__init__.py
  • python/cuopt/cuopt/linear_programming/solver/__init__.py
  • python/cuopt/cuopt/routing/__init__.py
  • python/cuopt/cuopt/routing/assignment.py
  • skills/cuopt-developer/SKILL.md
  • skills/cuopt-developer/references/fern_docs.md
💤 Files with no reviewable changes (102)
  • docs/cuopt/source/cuopt-python/mip/mip-api.rst
  • docs/cuopt/source/thirdparty_modeling_languages/index.rst
  • docs/cuopt/source/cuopt-grpc/examples/remote_lp_demo.py
  • docs/cuopt/source/cuopt-server/examples/lp/examples/batch_mode_example.sh
  • docs/cuopt/source/cuopt-server/nim-operator/deployment.rst
  • docs/cuopt/source/license.rst
  • docs/cuopt/source/cuopt-server/quick-start.rst
  • docs/cuopt/source/convex-settings.rst
  • docs/cuopt/source/cuopt-server/examples/milp/examples/abort_job_example.py
  • docs/cuopt/source/hidden/mps-overview.rst
  • docs/cuopt/source/cuopt-server/client-api/index.rst
  • docs/cuopt/source/cuopt-c/convex/index.rst
  • docs/cuopt/source/convex-features.rst
  • docs/cuopt/source/milp-features.rst
  • docs/cuopt/source/hidden/limitations.rst
  • docs/cuopt/source/cuopt-c/convex/convex-examples.rst
  • docs/cuopt/source/cuopt-python/quick-start.rst
  • docs/cuopt/source/cuopt-server/server-api/index.rst
  • docs/cuopt/source/cuopt-server/index.rst
  • docs/cuopt/source/cuopt-grpc/examples.rst
  • docs/cuopt/source/cuopt-c/mip/index.rst
  • docs/cuopt/source/cuopt-server/nim-operator/index.rst
  • docs/cuopt/source/cuopt-server/examples/lp/examples/basic_lp_example.sh
  • docs/cuopt/source/transition.rst
  • docs/cuopt/source/cuopt-server/client-api/sh-cli-build.rst
  • docs/cuopt/Makefile
  • docs/cuopt/source/cuopt-server/examples/routing/examples/basic_routing_example.sh
  • docs/cuopt/source/cuopt-c/index.rst
  • docs/cuopt/source/cuopt-python/mip/index.rst
  • conda/environments/all_cuda-129_arch-aarch64.yaml
  • docs/cuopt/source/cuopt-server/examples/milp/examples/basic_milp_example.sh
  • docs/cuopt/source/cuopt-cli/examples/lp/examples/basic_lp_example.sh
  • docs/cuopt/source/cuopt-server/examples/lp-examples.rst
  • docs/cuopt/source/routing-features.rst
  • docs/cuopt/source/system-requirements.rst
  • docs/cuopt/source/cuopt-c/mip/mip-c-api.rst
  • docs/cuopt/README.md
  • docs/cuopt/source/cuopt-cli/quick-start.rst
  • docs/cuopt/source/cuopt-grpc/api.rst
  • docs/cuopt/source/cuopt-server/examples/milp/examples/abort_job_example.sh
  • docs/cuopt/source/introduction.rst
  • docs/cuopt/source/cuopt-c/convex/convex-c-api.rst
  • docs/cuopt/source/cuopt-server/nim-operator/prerequisites.rst
  • docs/cuopt/source/cuopt-cli/examples/milp/examples/basic_milp_example.sh
  • docs/cuopt/source/cuopt-server/csp-guides/csp-aws.rst
  • docs/cuopt/source/cuopt-server/nim-operator/configuration.rst
  • docs/cuopt/source/faq.rst
  • docs/cuopt/source/_static/swagger-nvidia.css
  • docs/cuopt/source/cuopt-server/csp-guides/index.rst
  • docs/cuopt/source/cuopt-server/csp-guides/csp-azure.rst
  • docs/cuopt/source/cuopt-python/convex/index.rst
  • docs/cuopt/source/cuopt-python/routing/index.rst
  • docs/cuopt/source/cuopt-cli/index.rst
  • docs/cuopt/make.bat
  • docs/cuopt/source/release-notes.md
  • docs/cuopt/source/resources.rst
  • docs/cuopt/source/index.rst
  • docs/cuopt/source/cuopt-server/examples/lp/examples/warmstart_example.py
  • docs/cuopt/source/cuopt-python/index.rst
  • docs/cuopt/source/cuopt-server/nim-operator/guide/cuopt-nimservice.yaml
  • docs/cuopt/source/cuopt-python/convex/convex-examples.rst
  • docs/cuopt/source/open-api.rst
  • conda/environments/all_cuda-129_arch-x86_64.yaml
  • docs/cuopt/source/cuopt-cli/examples/lp/examples/solver_parameters_example.sh
  • docs/cuopt/source/cuopt-server/examples/routing-examples.rst
  • docs/cuopt/source/hidden/parser_example.rst
  • docs/cuopt/source/cuopt-python/convex/convex-api.rst
  • docs/cuopt/source/cuopt-server/examples/routing/examples/basic_routing_example.py
  • docs/cuopt/source/cuopt-python/mip/mip-examples.rst
  • docs/cuopt/source/cuopt-grpc/quick-start.rst
  • docs/cuopt/source/cuopt-server/examples/index.rst
  • docs/cuopt/source/versions1.json
  • docs/cuopt/source/cuopt-server/examples/lp/examples/warmstart_example.sh
  • docs/cuopt/source/_static/install-selector.js
  • docs/cuopt/source/cuopt-grpc/advanced.rst
  • docs/cuopt/source/cuopt-server/nim-operator/guide/cuopt-nimservice-full.yaml
  • docs/cuopt/source/cuopt-server/examples/milp/examples/basic_milp_example.py
  • docs/cuopt/source/cuopt-server/examples/lp/examples/mps_file_example.py
  • docs/cuopt/source/cuopt-python/routing/routing-examples.rst
  • docs/cuopt/source/cuopt-server/examples/lp/examples/basic_lp_example.py
  • docs/cuopt/source/cuopt-cli/cli-examples.rst
  • docs/cuopt/source/cuopt-server/examples/milp/examples/incumbent_callback_example.py
  • docs/cuopt/source/cuopt-grpc/index.rst
  • docs/cuopt/source/cuopt-server/examples/lp/examples/lp_datamodel_example.py
  • docs/cuopt/source/cuopt-server/client-api/sh-cli-api.rst
  • docs/cuopt/source/install.rst
  • docs/cuopt/source/cuopt-server/examples/milp-examples.rst
  • docs/cuopt/source/hidden/mps-api.rst
  • docs/cuopt/source/mip-settings.rst
  • docs/cuopt/source/conf.py
  • .github/workflows/build.yaml
  • conda/environments/all_cuda-133_arch-aarch64.yaml
  • docs/cuopt/source/cuopt-server/examples/routing/examples/initial_solution_example.py
  • docs/cuopt/source/cuopt-c/mip/mip-examples.rst
  • docs/cuopt/.editorconfig
  • conda/environments/all_cuda-133_arch-x86_64.yaml
  • docs/cuopt/source/cuopt-server/examples/lp/examples/mps_datamodel_example.py
  • docs/cuopt/source/cuopt-python/routing/routing-api.rst
  • docs/cuopt/source/cuopt-server/examples/routing/examples/initial_solution_example.sh
  • docs/cuopt/source/cuopt-server/nim-operator/guide/namespace.yaml
  • ci/utils/update_doc_versions.py
  • docs/cuopt/source/cuopt-server/nim-operator/guide/deploy.sh

- Restore build_docs condition to conda-cpp-build and conda-python-build if:
  clauses so docs-only PRs trigger the prerequisite conda builds (ci/build_docs.sh
  downloads their artifacts via rapids-download-from-github)
- Restore docs-build needs: [conda-python-build] dependency in pr.yaml
- Restore docs-build job in build.yaml (CPU node, no file_to_upload, no GPU)
- Restore docs-build to build-summary needs list in build.yaml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/pr.yaml (1)

432-432: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Avoid inheriting all secrets into the PR-controlled docs build.

secrets: inherit exposes every available repository/organization secret to the reusable workflow executing ci/build_docs.sh. Pass only the specific secret(s) required for Fern preview publication and document them. As per path instructions, newly referenced secrets and environment variables must be documented.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr.yaml at line 432, Update the reusable workflow
invocation around the docs build and ci/build_docs.sh to remove secrets:
inherit, pass only the Fern preview publication secret(s) through the workflow’s
explicit secrets mapping, and document each newly referenced secret and
environment variable as required by the repository path instructions.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr.yaml:
- Line 425: Update the docs-build job’s needs configuration to include
conda-cpp-build and conda-python-build alongside changed-files, and ensure both
producer jobs execute when documentation changes require them. Preserve the
artifact downloads in ci/build_docs.sh; only remove that requirement if the
workflow is intentionally changed to avoid those artifacts.

In `@fern/docs/pages/cuopt-server/nim-operator/guide/cuopt-nimservice-full.yaml`:
- Around line 44-50: Update the ingress configuration in the cuopt NimService
manifest so the host and TLS secret are explicit deployment inputs rather than
fixed values. Template or clearly document the required substitutions for the
TLS host and secretName, ensuring users provide a hostname they own and a
pre-created certificate secret before deployment.

In `@fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh`:
- Around line 129-148: Scope the registry and API-key secrets in the deploy flow
to cuOpt-specific names, update all NIMService references to those names, and
avoid deleting existing shared secrets. In the uninstall cleanup block, remove
only secrets created and owned by this deployment, including the renamed
cuOpt-scoped secrets; update
fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh lines 129-148 and
229-231 accordingly.
- Around line 156-160: The custom-namespace deployment path in the deploy script
does not apply the CUOPT_IMAGE_TAG selected by --tag. Update the sed pipeline
near the kubectl apply command to substitute the manifest’s image tag with
CUOPT_IMAGE_TAG while preserving namespace substitution, so tagged deployments
use the requested image.
- Line 17: Update the shell options near the start of the deployment script to
enable nounset alongside errexit by adding set -u before prerequisite checks,
ensuring an unset NGC_API_KEY fails fast even when --skip-prerequisites is used.

---

Outside diff comments:
In @.github/workflows/pr.yaml:
- Line 432: Update the reusable workflow invocation around the docs build and
ci/build_docs.sh to remove secrets: inherit, pass only the Fern preview
publication secret(s) through the workflow’s explicit secrets mapping, and
document each newly referenced secret and environment variable as required by
the repository path instructions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a876e52b-2dfe-4755-8243-bef42fdb41b4

📥 Commits

Reviewing files that changed from the base of the PR and between 9688363 and 208528f.

📒 Files selected for processing (16)
  • .github/workflows/pr.yaml
  • .pre-commit-config.yaml
  • conda/environments/all_cuda-129_arch-aarch64.yaml
  • conda/environments/all_cuda-129_arch-x86_64.yaml
  • conda/environments/all_cuda-133_arch-aarch64.yaml
  • conda/environments/all_cuda-133_arch-x86_64.yaml
  • dependencies.yaml
  • fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c
  • fern/docs/pages/cuopt-c/convex/examples/rotated_socp_example.c
  • fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c
  • fern/docs/pages/cuopt-c/convex/examples/simple_socp_example.c
  • fern/docs/pages/cuopt-server/nim-operator/guide/cuopt-nimservice-full.yaml
  • fern/docs/pages/cuopt-server/nim-operator/guide/cuopt-nimservice.yaml
  • fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh
  • fern/docs/pages/cuopt-server/nim-operator/guide/namespace.yaml
  • skills/cuopt-developer/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • fern/docs/pages/cuopt-c/convex/examples/simple_socp_example.c
  • .pre-commit-config.yaml
  • fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c
  • fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c
  • fern/docs/pages/cuopt-c/convex/examples/rotated_socp_example.c
  • dependencies.yaml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/pr.yaml (1)

432-432: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Avoid inheriting all secrets into the PR-controlled docs build.

secrets: inherit exposes every available repository/organization secret to the reusable workflow executing ci/build_docs.sh. Pass only the specific secret(s) required for Fern preview publication and document them. As per path instructions, newly referenced secrets and environment variables must be documented.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr.yaml at line 432, Update the reusable workflow
invocation around the docs build and ci/build_docs.sh to remove secrets:
inherit, pass only the Fern preview publication secret(s) through the workflow’s
explicit secrets mapping, and document each newly referenced secret and
environment variable as required by the repository path instructions.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr.yaml:
- Line 425: Update the docs-build job’s needs configuration to include
conda-cpp-build and conda-python-build alongside changed-files, and ensure both
producer jobs execute when documentation changes require them. Preserve the
artifact downloads in ci/build_docs.sh; only remove that requirement if the
workflow is intentionally changed to avoid those artifacts.

In `@fern/docs/pages/cuopt-server/nim-operator/guide/cuopt-nimservice-full.yaml`:
- Around line 44-50: Update the ingress configuration in the cuopt NimService
manifest so the host and TLS secret are explicit deployment inputs rather than
fixed values. Template or clearly document the required substitutions for the
TLS host and secretName, ensuring users provide a hostname they own and a
pre-created certificate secret before deployment.

In `@fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh`:
- Around line 129-148: Scope the registry and API-key secrets in the deploy flow
to cuOpt-specific names, update all NIMService references to those names, and
avoid deleting existing shared secrets. In the uninstall cleanup block, remove
only secrets created and owned by this deployment, including the renamed
cuOpt-scoped secrets; update
fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh lines 129-148 and
229-231 accordingly.
- Around line 156-160: The custom-namespace deployment path in the deploy script
does not apply the CUOPT_IMAGE_TAG selected by --tag. Update the sed pipeline
near the kubectl apply command to substitute the manifest’s image tag with
CUOPT_IMAGE_TAG while preserving namespace substitution, so tagged deployments
use the requested image.
- Line 17: Update the shell options near the start of the deployment script to
enable nounset alongside errexit by adding set -u before prerequisite checks,
ensuring an unset NGC_API_KEY fails fast even when --skip-prerequisites is used.

---

Outside diff comments:
In @.github/workflows/pr.yaml:
- Line 432: Update the reusable workflow invocation around the docs build and
ci/build_docs.sh to remove secrets: inherit, pass only the Fern preview
publication secret(s) through the workflow’s explicit secrets mapping, and
document each newly referenced secret and environment variable as required by
the repository path instructions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a876e52b-2dfe-4755-8243-bef42fdb41b4

📥 Commits

Reviewing files that changed from the base of the PR and between 9688363 and 208528f.

📒 Files selected for processing (16)
  • .github/workflows/pr.yaml
  • .pre-commit-config.yaml
  • conda/environments/all_cuda-129_arch-aarch64.yaml
  • conda/environments/all_cuda-129_arch-x86_64.yaml
  • conda/environments/all_cuda-133_arch-aarch64.yaml
  • conda/environments/all_cuda-133_arch-x86_64.yaml
  • dependencies.yaml
  • fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c
  • fern/docs/pages/cuopt-c/convex/examples/rotated_socp_example.c
  • fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c
  • fern/docs/pages/cuopt-c/convex/examples/simple_socp_example.c
  • fern/docs/pages/cuopt-server/nim-operator/guide/cuopt-nimservice-full.yaml
  • fern/docs/pages/cuopt-server/nim-operator/guide/cuopt-nimservice.yaml
  • fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh
  • fern/docs/pages/cuopt-server/nim-operator/guide/namespace.yaml
  • skills/cuopt-developer/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • fern/docs/pages/cuopt-c/convex/examples/simple_socp_example.c
  • .pre-commit-config.yaml
  • fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c
  • fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c
  • fern/docs/pages/cuopt-c/convex/examples/rotated_socp_example.c
  • dependencies.yaml
🛑 Comments failed to post (5)
.github/workflows/pr.yaml (1)

425-425: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Preserve the artifact dependency for docs-build.

ci/build_docs.sh, Lines 19-22, immediately downloads artifacts produced by conda-cpp-build and conda-python-build. With only changed-files in needs, this job can start before those artifacts exist—or run when their producers were skipped. Restore both dependencies and ensure they run for documentation changes, or remove the artifact requirement.

Proposed dependency change
-    needs: [changed-files]
+    needs: [changed-files, conda-cpp-build, conda-python-build]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    needs: [changed-files, conda-cpp-build, conda-python-build]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr.yaml at line 425, Update the docs-build job’s needs
configuration to include conda-cpp-build and conda-python-build alongside
changed-files, and ensure both producer jobs execute when documentation changes
require them. Preserve the artifact downloads in ci/build_docs.sh; only remove
that requirement if the workflow is intentionally changed to avoid those
artifacts.
fern/docs/pages/cuopt-server/nim-operator/guide/cuopt-nimservice-full.yaml (1)

44-50: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make ingress host and TLS secret explicit deployment inputs.

This “production-ready” manifest hard-codes cuopt.example.com and references a TLS secret it does not create. Applying it unchanged cannot make the service reachable under a user-owned hostname or serve its certificate. Document required substitutions or template these values.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/nim-operator/guide/cuopt-nimservice-full.yaml`
around lines 44 - 50, Update the ingress configuration in the cuopt NimService
manifest so the host and TLS secret are explicit deployment inputs rather than
fixed values. Template or clearly document the required substitutions for the
TLS host and secretName, ensuring users provide a hostname they own and a
pre-created certificate secret before deployment.
fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh (3)

17-17: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh'

echo "== lines around 17 =="
sed -n '1,40p' "$file" | nl -ba

echo
echo "== NGC_API_KEY references =="
grep -n 'NGC_API_KEY\|skip-prerequisites\|set -e\|set -u' "$file" || true

echo
echo "== relevant middle section =="
sed -n '120,170p' "$file" | nl -ba

Repository: NVIDIA/cuopt

Length of output: 212


🏁 Script executed:

#!/bin/bash
file='fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh'

echo "== lines around 17 =="
awk 'NR>=1 && NR<=40 { printf "%4d  %s\n", NR, $0 }' "$file"

echo
echo "== NGC_API_KEY / prerequisite flow =="
grep -n 'NGC_API_KEY\|skip-prerequisites\|set -e\|set -u' "$file" || true

echo
echo "== lines 120-170 =="
awk 'NR>=120 && NR<=170 { printf "%4d  %s\n", NR, $0 }' "$file"

Repository: NVIDIA/cuopt

Length of output: 3844


🏁 Script executed:

#!/bin/bash
file='fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh'

echo "== lines 240-320 =="
awk 'NR>=240 && NR<=320 { printf "%4d  %s\n", NR, $0 }' "$file"

echo
echo "== create_secrets call sites =="
grep -n 'create_secrets' "$file" || true

Repository: NVIDIA/cuopt

Length of output: 1488


Enable nounset before skipping prereq checks. With --skip-prerequisites, an unset NGC_API_KEY falls through into kubectl create secret and produces empty credentials. set -u makes the script fail fast instead of creating broken secrets.

Proposed fix
-set -e
+set -eu
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

set -eu
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh` at line 17, Update
the shell options near the start of the deployment script to enable nounset
alongside errexit by adding set -u before prerequisite checks, ensuring an unset
NGC_API_KEY fails fast even when --skip-prerequisites is used.

Source: Learnings


129-148: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not destroy potentially shared NGC secrets. The script assumes it owns generic ngc-secret and ngc-api-secret; deploying or uninstalling can break another NIM workload in the same namespace.

  • fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh#L129-L148: use cuOpt-scoped secret names and update the NIMService references, or preserve pre-existing secrets.
  • fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh#L229-L231: delete only secrets created and owned by this deployment.
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 137-137: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)

📍 Affects 1 file
  • fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh#L129-L148 (this comment)
  • fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh#L229-L231
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh` around lines 129 -
148, Scope the registry and API-key secrets in the deploy flow to cuOpt-specific
names, update all NIMService references to those names, and avoid deleting
existing shared secrets. In the uninstall cleanup block, remove only secrets
created and owned by this deployment, including the renamed cuOpt-scoped
secrets; update fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh lines
129-148 and 229-231 accordingly.

156-160: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Apply the requested image tag to the manifest.

--tag only changes CUOPT_IMAGE_TAG; this pipeline substitutes only namespace, so deployments always use the manifest’s original image tag. Substitute the tag too, or remove the unsupported option.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/nim-operator/guide/deploy.sh` around lines 156 -
160, The custom-namespace deployment path in the deploy script does not apply
the CUOPT_IMAGE_TAG selected by --tag. Update the sed pipeline near the kubectl
apply command to substitute the manifest’s image tag with CUOPT_IMAGE_TAG while
preserving namespace substitution, so tagged deployments use the requested
image.

ramakrishnap-nv and others added 4 commits July 17, 2026 14:11
Changes to ci/build_docs.sh should not trigger test_cpp, test_python_conda,
or test_python_wheels. Replace the old !docs/** exclusion (Sphinx tree, now
deleted) with !fern/** in test_cpp and test_python_conda so Fern-only changes
don't trigger those test suites.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
Three issues found during deletion audit:

1. Example files for server, CLI, and gRPC were deleted with the Sphinx tree
   but not ported to the fern tree. The MDX pages link to them and
   ci/test_doc_examples.sh discovers them by path. Restored 23 files from
   git history at e75dfff^ into fern/docs/pages/{cuopt-server,cuopt-cli,
   cuopt-grpc}/examples/. Also updated stale 2025 copyright headers to
   2025-2026 (auto-fixed by verify-copyright hook).

2. The 'docs' file-key block was removed from dependencies.yaml, breaking
   ci/build_docs.sh which calls rapids-dependency-file-generator --file-key
   docs. Restored with the Fern-appropriate includes (cuda_version,
   depends_on_libcuopt, depends_on_cuopt, docs, py_version).

3. pydocstyle was checking fern/ example scripts (previously covered by the
   docs/ exclusion). Added fern/ to the pydocstyle exclude list in
   .pre-commit-config.yaml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
…endent

The Fern docs extractors work without cuopt installed:
- extract_python_api.py reads .py/.pyx source via AST (no imports)
- extract_c_api.py reads Doxygen XML (no imports)
- OpenAPI spec is committed to fern/openapi/cuopt_spec.yaml; cuopt_server
  import in generate_api_docs.py is try/except-guarded

Changes:
- ci/build_docs.sh: remove rapids-download-from-github calls for conda_cpp
  and conda_python artifacts; remove --prepend-channel flags
- dependencies.yaml: simplify files.docs to only include docs + py_version
  (no depends_on_libcuopt, depends_on_cuopt, depends_on_cuopt_server)
- pr.yaml: docs-build needs [changed-files] only (not conda-python-build);
  remove build_docs condition from conda-cpp-build and conda-python-build
- build.yaml: docs-build has no needs (runs independently of python-build)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
generate_api_docs.py imports cuopt_server (via sys.path) to regenerate
fern/openapi/cuopt_spec.yaml. cuopt_server depends on cuopt -> libcuopt,
so the docs build needs the conda artifacts from conda-cpp-build and
conda-python-build.

Restores:
- ci/build_docs.sh: artifact download for conda_cpp and conda_python channels
- dependencies.yaml: depends_on_libcuopt + depends_on_cuopt in files.docs
- pr.yaml: build_docs condition on conda-cpp-build and conda-python-build;
  docs-build needs [conda-python-build, changed-files]
- build.yaml: docs-build needs [python-build]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (8)
fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py (1)

24-25: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add required annotations and contract documentation to all new public Python functions.

  • fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py#L24-L25: annotate main() -> None and document its behavior/errors.
  • fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py#L46-L69: annotate repoll and main, documenting parameters, returns, and errors.
  • fern/docs/pages/cuopt-server/examples/milp/examples/incumbent_callback_example.py#L35-L36: annotate main() -> None and document its behavior/errors.
  • fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py#L46-L69: annotate repoll and main, documenting parameters, returns, and errors.
  • fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py#L30-L31: annotate main() -> None and document its behavior/errors.

As per coding guidelines, new public Python functions require type hints and meaningful parameter, return, and raise documentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py`
around lines 24 - 25, Update main in
fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py (lines
24-25) and incumbent_callback_example.py (lines 35-36), plus
initial_solution_example.py (lines 30-31), with explicit -> None annotations and
docstrings describing behavior and raised errors. Update repoll and main in
basic_milp_example.py (lines 46-69) and basic_routing_example.py (lines 46-69)
with complete type annotations and meaningful documentation for parameters,
return values, and raised errors.

Source: Coding guidelines

fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py (1)

43-72: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Delete saved solutions in a finally block.

Because the initial solutions are retained server-side, any exception during upload, solving, printing, or later processing skips lines 70–71 and leaks saved solutions. Track successfully created IDs and clean them up in finally.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py`
around lines 43 - 72, Wrap the initial-solution upload, reuse solve, and
subsequent processing in a try/finally block, tracking each successfully created
request ID as it becomes available. Move cleanup into finally and delete only
the IDs that were successfully created, including handling partial failures
during upload or solving.
fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.sh (1)

30-50: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate reqId before reusing or deleting it.

If the solve fails or the response lacks an ID, jq can produce an empty value or null; the script then sends invalid follow-up requests and reports success. Add set -euo pipefail and reject empty/null IDs before line 40.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.sh`
around lines 30 - 50, Harden the script around the reqId extraction by enabling
set -euo pipefail near the start, then validate reqId before the Step 2 reuse
and Step 3 deletion commands. Reject both empty and null values so follow-up
cuopt_sh calls do not run or report success without a valid identifier.
fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py (1)

53-60: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the response key as the polling completion signal.

Both polling helpers require reqId and response, but the documented completed responses contain only response.

  • fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py#L53-L60: break when "response" is present.
  • fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py#L54-L61: break when "response" is present.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py`
around lines 53 - 60, The polling completion checks in the MILP example’s repoll
loop and the routing example’s corresponding repoll loop currently require both
“reqId” and “response”; update both
sites—fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py
lines 53-60 and
fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py
lines 54-61—to break whenever the repolled solution contains “response”, while
preserving the existing polling flow.
fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.sh (1)

28-34: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not report success when aborting fails.

A failed cuopt_sh command is followed by the success message and a zero exit status. Add set -euo pipefail or check the command status before printing confirmation.

Based on learnings, this repository prefers set -u in Bash scripts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.sh`
around lines 28 - 34, Update the abort-job script to enable Bash unset-variable
protection with set -u and ensure the success message is printed only when
cuopt_sh completes successfully, preserving the command’s failure status instead
of reporting a false success.

Source: Learnings

fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.sh (1)

28-34: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate routing-command failures.

When cuopt_sh fails, cleanup succeeds and the script exits 0. Add set -euo pipefail before invoking the CLI.

Based on learnings, this repository prefers set -u in Bash scripts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.sh`
around lines 28 - 34, Add strict Bash error handling before the cuopt_sh
invocation in the routing example, using the repository-preferred set -u while
also ensuring command and pipeline failures propagate so cleanup cannot mask a
failed routing command. Keep the existing cuopt_sh and cleanup behavior
unchanged.

Source: Learnings

fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.sh (1)

50-59: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Fail the example when cuopt_sh fails.

If the server request fails, rm -f data.json becomes the successful final command and hides the failure. Add set -euo pipefail before invoking the CLI.

Based on learnings, this repository prefers set -u in Bash scripts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.sh`
around lines 50 - 59, Add `set -u` before the `cuopt_sh` invocation in the
example script so unset variables fail early, and ensure the CLI failure remains
the script’s exit status rather than being masked by cleanup. Preserve the
existing `cuopt_sh` command and cleanup behavior.

Source: Learnings

fern/docs/pages/cuopt-cli/examples/milp/examples/basic_milp_example.sh (1)

43-47: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate cuopt_cli failures.

If the solver is unavailable or returns an error, the script continues to rm -f and exits successfully. Add set -euo pipefail near the top, or explicitly check the solver status before cleanup.

Based on learnings, this repository prefers set -u in Bash scripts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-cli/examples/milp/examples/basic_milp_example.sh`
around lines 43 - 47, Add `set -u` near the top of basic_milp_example.sh and
explicitly check the cuopt_cli invocation’s exit status so solver failures
propagate as a nonzero script exit while still allowing cleanup to run as
intended.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py`:
- Around line 24-25: The objective coefficient for VAR1 is positive in both LP
examples; update the coefficient array in
fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py lines 24-25 and the JSON
coefficients in
fern/docs/pages/cuopt-server/examples/lp/examples/basic_lp_example.sh lines
32-35 to use -0.2 while preserving VAR2's 0.1 value.

In `@fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.py`:
- Around line 14-16: Align the warm-start documentation with the solver_config
value used in the example: update the docstring near the warm-start instructions
to describe the same `presolve` representation configured in the example’s
solver_config. Keep the code behavior unchanged unless the documented form is
the intended API value.

In `@fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.sh`:
- Line 44: Update the maximize field in the warmstart example payload to use the
JSON boolean false instead of the string "False", matching the solver payload
contract and other MILP examples.

---

Outside diff comments:
In `@fern/docs/pages/cuopt-cli/examples/milp/examples/basic_milp_example.sh`:
- Around line 43-47: Add `set -u` near the top of basic_milp_example.sh and
explicitly check the cuopt_cli invocation’s exit status so solver failures
propagate as a nonzero script exit while still allowing cleanup to run as
intended.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py`:
- Around line 24-25: Update main in
fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py (lines
24-25) and incumbent_callback_example.py (lines 35-36), plus
initial_solution_example.py (lines 30-31), with explicit -> None annotations and
docstrings describing behavior and raised errors. Update repoll and main in
basic_milp_example.py (lines 46-69) and basic_routing_example.py (lines 46-69)
with complete type annotations and meaningful documentation for parameters,
return values, and raised errors.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.sh`:
- Around line 28-34: Update the abort-job script to enable Bash unset-variable
protection with set -u and ensure the success message is printed only when
cuopt_sh completes successfully, preserving the command’s failure status instead
of reporting a false success.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py`:
- Around line 53-60: The polling completion checks in the MILP example’s repoll
loop and the routing example’s corresponding repoll loop currently require both
“reqId” and “response”; update both
sites—fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py
lines 53-60 and
fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py
lines 54-61—to break whenever the repolled solution contains “response”, while
preserving the existing polling flow.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.sh`:
- Around line 50-59: Add `set -u` before the `cuopt_sh` invocation in the
example script so unset variables fail early, and ensure the CLI failure remains
the script’s exit status rather than being masked by cleanup. Preserve the
existing `cuopt_sh` command and cleanup behavior.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.sh`:
- Around line 28-34: Add strict Bash error handling before the cuopt_sh
invocation in the routing example, using the repository-preferred set -u while
also ensuring command and pipeline failures propagate so cleanup cannot mask a
failed routing command. Keep the existing cuopt_sh and cleanup behavior
unchanged.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py`:
- Around line 43-72: Wrap the initial-solution upload, reuse solve, and
subsequent processing in a try/finally block, tracking each successfully created
request ID as it becomes available. Move cleanup into finally and delete only
the IDs that were successfully created, including handling partial failures
during upload or solving.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.sh`:
- Around line 30-50: Harden the script around the reqId extraction by enabling
set -euo pipefail near the start, then validate reqId before the Step 2 reuse
and Step 3 deletion commands. Reject both empty and null values so follow-up
cuopt_sh calls do not run or report success without a valid identifier.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4a1e1444-2bf5-474f-8987-baea2b6e8065

📥 Commits

Reviewing files that changed from the base of the PR and between 9fcb430 and 1b6f487.

⛔ Files ignored due to path filters (2)
  • fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.mps is excluded by !**/*.mps
  • fern/docs/pages/cuopt-server/examples/lp/examples/sample.mps is excluded by !**/*.mps
📒 Files selected for processing (23)
  • .pre-commit-config.yaml
  • dependencies.yaml
  • fern/docs/pages/cuopt-cli/examples/lp/examples/basic_lp_example.sh
  • fern/docs/pages/cuopt-cli/examples/lp/examples/solver_parameters_example.sh
  • fern/docs/pages/cuopt-cli/examples/milp/examples/basic_milp_example.sh
  • fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/basic_lp_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/basic_lp_example.sh
  • fern/docs/pages/cuopt-server/examples/lp/examples/batch_mode_example.sh
  • fern/docs/pages/cuopt-server/examples/lp/examples/lp_datamodel_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/mps_datamodel_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/mps_file_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.sh
  • fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py
  • fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.sh
  • fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py
  • fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.sh
  • fern/docs/pages/cuopt-server/examples/milp/examples/incumbent_callback_example.py
  • fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py
  • fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.sh
  • fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py
  • fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • .pre-commit-config.yaml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (8)
fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py (1)

24-25: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add required annotations and contract documentation to all new public Python functions.

  • fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py#L24-L25: annotate main() -> None and document its behavior/errors.
  • fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py#L46-L69: annotate repoll and main, documenting parameters, returns, and errors.
  • fern/docs/pages/cuopt-server/examples/milp/examples/incumbent_callback_example.py#L35-L36: annotate main() -> None and document its behavior/errors.
  • fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py#L46-L69: annotate repoll and main, documenting parameters, returns, and errors.
  • fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py#L30-L31: annotate main() -> None and document its behavior/errors.

As per coding guidelines, new public Python functions require type hints and meaningful parameter, return, and raise documentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py`
around lines 24 - 25, Update main in
fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py (lines
24-25) and incumbent_callback_example.py (lines 35-36), plus
initial_solution_example.py (lines 30-31), with explicit -> None annotations and
docstrings describing behavior and raised errors. Update repoll and main in
basic_milp_example.py (lines 46-69) and basic_routing_example.py (lines 46-69)
with complete type annotations and meaningful documentation for parameters,
return values, and raised errors.

Source: Coding guidelines

fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py (1)

43-72: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Delete saved solutions in a finally block.

Because the initial solutions are retained server-side, any exception during upload, solving, printing, or later processing skips lines 70–71 and leaks saved solutions. Track successfully created IDs and clean them up in finally.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py`
around lines 43 - 72, Wrap the initial-solution upload, reuse solve, and
subsequent processing in a try/finally block, tracking each successfully created
request ID as it becomes available. Move cleanup into finally and delete only
the IDs that were successfully created, including handling partial failures
during upload or solving.
fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.sh (1)

30-50: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate reqId before reusing or deleting it.

If the solve fails or the response lacks an ID, jq can produce an empty value or null; the script then sends invalid follow-up requests and reports success. Add set -euo pipefail and reject empty/null IDs before line 40.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.sh`
around lines 30 - 50, Harden the script around the reqId extraction by enabling
set -euo pipefail near the start, then validate reqId before the Step 2 reuse
and Step 3 deletion commands. Reject both empty and null values so follow-up
cuopt_sh calls do not run or report success without a valid identifier.
fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py (1)

53-60: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the response key as the polling completion signal.

Both polling helpers require reqId and response, but the documented completed responses contain only response.

  • fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py#L53-L60: break when "response" is present.
  • fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py#L54-L61: break when "response" is present.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py`
around lines 53 - 60, The polling completion checks in the MILP example’s repoll
loop and the routing example’s corresponding repoll loop currently require both
“reqId” and “response”; update both
sites—fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py
lines 53-60 and
fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py
lines 54-61—to break whenever the repolled solution contains “response”, while
preserving the existing polling flow.
fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.sh (1)

28-34: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not report success when aborting fails.

A failed cuopt_sh command is followed by the success message and a zero exit status. Add set -euo pipefail or check the command status before printing confirmation.

Based on learnings, this repository prefers set -u in Bash scripts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.sh`
around lines 28 - 34, Update the abort-job script to enable Bash unset-variable
protection with set -u and ensure the success message is printed only when
cuopt_sh completes successfully, preserving the command’s failure status instead
of reporting a false success.

Source: Learnings

fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.sh (1)

28-34: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate routing-command failures.

When cuopt_sh fails, cleanup succeeds and the script exits 0. Add set -euo pipefail before invoking the CLI.

Based on learnings, this repository prefers set -u in Bash scripts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.sh`
around lines 28 - 34, Add strict Bash error handling before the cuopt_sh
invocation in the routing example, using the repository-preferred set -u while
also ensuring command and pipeline failures propagate so cleanup cannot mask a
failed routing command. Keep the existing cuopt_sh and cleanup behavior
unchanged.

Source: Learnings

fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.sh (1)

50-59: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Fail the example when cuopt_sh fails.

If the server request fails, rm -f data.json becomes the successful final command and hides the failure. Add set -euo pipefail before invoking the CLI.

Based on learnings, this repository prefers set -u in Bash scripts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.sh`
around lines 50 - 59, Add `set -u` before the `cuopt_sh` invocation in the
example script so unset variables fail early, and ensure the CLI failure remains
the script’s exit status rather than being masked by cleanup. Preserve the
existing `cuopt_sh` command and cleanup behavior.

Source: Learnings

fern/docs/pages/cuopt-cli/examples/milp/examples/basic_milp_example.sh (1)

43-47: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate cuopt_cli failures.

If the solver is unavailable or returns an error, the script continues to rm -f and exits successfully. Add set -euo pipefail near the top, or explicitly check the solver status before cleanup.

Based on learnings, this repository prefers set -u in Bash scripts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-cli/examples/milp/examples/basic_milp_example.sh`
around lines 43 - 47, Add `set -u` near the top of basic_milp_example.sh and
explicitly check the cuopt_cli invocation’s exit status so solver failures
propagate as a nonzero script exit while still allowing cleanup to run as
intended.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py`:
- Around line 24-25: The objective coefficient for VAR1 is positive in both LP
examples; update the coefficient array in
fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py lines 24-25 and the JSON
coefficients in
fern/docs/pages/cuopt-server/examples/lp/examples/basic_lp_example.sh lines
32-35 to use -0.2 while preserving VAR2's 0.1 value.

In `@fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.py`:
- Around line 14-16: Align the warm-start documentation with the solver_config
value used in the example: update the docstring near the warm-start instructions
to describe the same `presolve` representation configured in the example’s
solver_config. Keep the code behavior unchanged unless the documented form is
the intended API value.

In `@fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.sh`:
- Line 44: Update the maximize field in the warmstart example payload to use the
JSON boolean false instead of the string "False", matching the solver payload
contract and other MILP examples.

---

Outside diff comments:
In `@fern/docs/pages/cuopt-cli/examples/milp/examples/basic_milp_example.sh`:
- Around line 43-47: Add `set -u` near the top of basic_milp_example.sh and
explicitly check the cuopt_cli invocation’s exit status so solver failures
propagate as a nonzero script exit while still allowing cleanup to run as
intended.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py`:
- Around line 24-25: Update main in
fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py (lines
24-25) and incumbent_callback_example.py (lines 35-36), plus
initial_solution_example.py (lines 30-31), with explicit -> None annotations and
docstrings describing behavior and raised errors. Update repoll and main in
basic_milp_example.py (lines 46-69) and basic_routing_example.py (lines 46-69)
with complete type annotations and meaningful documentation for parameters,
return values, and raised errors.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.sh`:
- Around line 28-34: Update the abort-job script to enable Bash unset-variable
protection with set -u and ensure the success message is printed only when
cuopt_sh completes successfully, preserving the command’s failure status instead
of reporting a false success.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py`:
- Around line 53-60: The polling completion checks in the MILP example’s repoll
loop and the routing example’s corresponding repoll loop currently require both
“reqId” and “response”; update both
sites—fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py
lines 53-60 and
fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py
lines 54-61—to break whenever the repolled solution contains “response”, while
preserving the existing polling flow.

In `@fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.sh`:
- Around line 50-59: Add `set -u` before the `cuopt_sh` invocation in the
example script so unset variables fail early, and ensure the CLI failure remains
the script’s exit status rather than being masked by cleanup. Preserve the
existing `cuopt_sh` command and cleanup behavior.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.sh`:
- Around line 28-34: Add strict Bash error handling before the cuopt_sh
invocation in the routing example, using the repository-preferred set -u while
also ensuring command and pipeline failures propagate so cleanup cannot mask a
failed routing command. Keep the existing cuopt_sh and cleanup behavior
unchanged.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py`:
- Around line 43-72: Wrap the initial-solution upload, reuse solve, and
subsequent processing in a try/finally block, tracking each successfully created
request ID as it becomes available. Move cleanup into finally and delete only
the IDs that were successfully created, including handling partial failures
during upload or solving.

In
`@fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.sh`:
- Around line 30-50: Harden the script around the reqId extraction by enabling
set -euo pipefail near the start, then validate reqId before the Step 2 reuse
and Step 3 deletion commands. Reject both empty and null values so follow-up
cuopt_sh calls do not run or report success without a valid identifier.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4a1e1444-2bf5-474f-8987-baea2b6e8065

📥 Commits

Reviewing files that changed from the base of the PR and between 9fcb430 and 1b6f487.

⛔ Files ignored due to path filters (2)
  • fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.mps is excluded by !**/*.mps
  • fern/docs/pages/cuopt-server/examples/lp/examples/sample.mps is excluded by !**/*.mps
📒 Files selected for processing (23)
  • .pre-commit-config.yaml
  • dependencies.yaml
  • fern/docs/pages/cuopt-cli/examples/lp/examples/basic_lp_example.sh
  • fern/docs/pages/cuopt-cli/examples/lp/examples/solver_parameters_example.sh
  • fern/docs/pages/cuopt-cli/examples/milp/examples/basic_milp_example.sh
  • fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/basic_lp_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/basic_lp_example.sh
  • fern/docs/pages/cuopt-server/examples/lp/examples/batch_mode_example.sh
  • fern/docs/pages/cuopt-server/examples/lp/examples/lp_datamodel_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/mps_datamodel_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/mps_file_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.py
  • fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.sh
  • fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.py
  • fern/docs/pages/cuopt-server/examples/milp/examples/abort_job_example.sh
  • fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.py
  • fern/docs/pages/cuopt-server/examples/milp/examples/basic_milp_example.sh
  • fern/docs/pages/cuopt-server/examples/milp/examples/incumbent_callback_example.py
  • fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.py
  • fern/docs/pages/cuopt-server/examples/routing/examples/basic_routing_example.sh
  • fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.py
  • fern/docs/pages/cuopt-server/examples/routing/examples/initial_solution_example.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • .pre-commit-config.yaml
🛑 Comments failed to post (3)
fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py (1)

24-25: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Objective coefficient sign error for VAR1 across two example files. Both files describe the same LP problem (minimize -0.2*VAR1 + 0.1*VAR2) but use positive 0.2 for VAR1's objective coefficient. All other examples in this PR (MPS files, LP files, Python server examples) correctly use -0.2. With the wrong sign, the solver minimizes 0.2*x1 + 0.1*x2, yielding x=[0,0] and objective=0 instead of the expected -0.36.

  • fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py#L24-L25: change c = np.array([0.2, 0.1], dtype=np.float64) to c = np.array([-0.2, 0.1], dtype=np.float64).
  • fern/docs/pages/cuopt-server/examples/lp/examples/basic_lp_example.sh#L32-L35: change "coefficients": [0.2, 0.1] to "coefficients": [-0.2, 0.1].
📍 Affects 2 files
  • fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py#L24-L25 (this comment)
  • fern/docs/pages/cuopt-server/examples/lp/examples/basic_lp_example.sh#L32-L35
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py` around lines 24 - 25,
The objective coefficient for VAR1 is positive in both LP examples; update the
coefficient array in fern/docs/pages/cuopt-grpc/examples/remote_lp_demo.py lines
24-25 and the JSON coefficients in
fern/docs/pages/cuopt-server/examples/lp/examples/basic_lp_example.sh lines
32-35 to use -0.2 while preserving VAR2's 0.1 value.
fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.py (1)

14-16: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Docstring and code disagree on presolve value.

The docstring (lines 14–16) instructs users to set "presolve": "off", but the code (line 61) uses "presolve": 0. Users following the docstring may use the string form while the example uses the integer form. Align the docstring with the code (or vice-versa) to avoid confusion.

🔧 Proposed fix — update docstring to match code
     To use warm start with PDLP, presolve must be explicitly disabled.
-    Set "presolve": "off" in solver_config, as presolve transforms the problem
+    Set "presolve": 0 in solver_config, as presolve transforms the problem
     and the warm start solution from the original problem cannot be applied.

Also applies to: 58-62

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.py`
around lines 14 - 16, Align the warm-start documentation with the solver_config
value used in the example: update the docstring near the warm-start instructions
to describe the same `presolve` representation configured in the example’s
solver_config. Keep the code behavior unchanged unless the documented form is
the intended API value.
fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.sh (1)

44-44: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Encode maximize as a JSON boolean.

"False" is a string, while the other MILP examples use false/True. Send false here to match the solver payload contract.

Suggested fix
-    "maximize": "False",
+    "maximize": false,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    "maximize": false,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@fern/docs/pages/cuopt-server/examples/lp/examples/warmstart_example.sh` at
line 44, Update the maximize field in the warmstart example payload to use the
JSON boolean false instead of the string "False", matching the solver payload
contract and other MILP examples.

- Accept verify-copyright auto-fixes: example files renamed from docs/
  correctly revert to 2025 (git tracks original creation year)
- Add missing comma in copyright: 2024-2026 NVIDIA → 2024-2026, NVIDIA
  in python/cuopt/cuopt/linear_programming/io/__init__.py
- Exclude .mdx files from verify-hardcoded-version (same as .md):
  documentation version references in MDX are intentional
- Exclude fern/docs.yml and fern/docs-v*.yml from verify-hardcoded-version:
  these version switcher configs have intentional display-name version strings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc Improvements or additions to documentation non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant