Skip to content

Conversation

@rgsl888prabhu
Copy link
Collaborator

@rgsl888prabhu rgsl888prabhu commented Jan 30, 2026

Description

This PR adds new structure for agentic skills based on APIs and particular skill files for debug and others, here is the new structure.

AGENTS.md                              # Root entry point → .github/AGENTS.md

.github/
├── AGENTS.md                          # Main entry point for agents
│
└── skills/
    ├── README.md                      # Skills index
    │
    ├── cuopt-user-rules/
    │   └── SKILL.md                   # 8 behavior rules for user tasks
    │
    ├── cuopt-routing/
    │   ├── SKILL.md                   # VRP, TSP, PDP
    │   └── resources/
    │       ├── python_examples.md
    │       └── server_examples.md
    │
    ├── cuopt-lp-milp/
    │   ├── SKILL.md                   # Linear & integer programming
    │   └── resources/
    │       ├── python_examples.md
    │       ├── c_api_examples.md
    │       ├── cli_examples.md
    │       └── server_examples.md
    │
    ├── cuopt-qp/
    │   ├── SKILL.md                   # Quadratic programming (beta)
    │   └── resources/
    │       └── python_examples.md
    │
    ├── cuopt-server/
    │   ├── SKILL.md                   # REST API deployment
    │   └── resources/
    │       ├── routing_examples.md
    │       └── lp_milp_examples.md
    │
    ├── cuopt-debugging/
    │   ├── SKILL.md                   # Troubleshooting
    │   └── resources/
    │       └── diagnostic_snippets.md
    │
    ├── cuopt-installation/
    │   ├── SKILL.md                   # Setup & requirements
    │   └── resources/
    │       └── verification_examples.md
    │
    └── cuopt-developer/
        └── SKILL.md                   # Contributing (own rules inline)

Pros and cons compared to previous approach.

Pros of New Structure
Focused context — Agent loads only relevant content (routing skill for routing questions)
Better skill triggering — Specific descriptions like "VRP, TSP, PDP" vs generic "use cuOpt"
Separation of concerns — Rules, domain content, and examples are separate
API-specific examples — Python, C, CLI, REST examples organized per-skill
Scalable — Easy to add new skills (cuopt-migration, cuopt-concepts)
Developer rules isolated — Developer workflow doesn't pollute user context
Progressive disclosure — SKILL.md is concise, resources/ has details

Cons of New Structure
More files — 20 files vs 6 files to maintain
Navigation overhead — Agent must potentially load multiple files
Duplication risk — Some content might be duplicated across skills
Prerequisite chain — User skills depend on reading cuopt-user-rules first
Sync burden — Updates to shared patterns need updating in multiple places

Issue

Checklist

  • I am familiar with the Contributing Guidelines.
  • Testing
    • New or existing tests cover these changes
    • Added tests
    • Created an issue to follow-up
    • NA
  • Documentation
    • The documentation is up to date with these changes
    • Added new documentation
    • NA

Summary by CodeRabbit

  • Documentation
    • Added a centralized agent entry point and skills index plus extensive skill guides (installation, debugging, LP/MILP, QP, routing, server, developer, user rules) with runnable examples, verification & diagnostic snippets, and manifest references.
  • Chores
    • Updated code ownership mappings and infra/packaging ownership entries.

✏️ Tip: You can customize this high-level summary in your review settings.

@rgsl888prabhu rgsl888prabhu requested a review from a team as a code owner January 30, 2026 22:58
@rgsl888prabhu rgsl888prabhu self-assigned this Jan 30, 2026
@rgsl888prabhu rgsl888prabhu added non-breaking Introduces a non-breaking change improvement Improves an existing functionality labels Jan 30, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Replaces the agent shim with an explicit cuOpt AI Agent entry point and skills directory, adds many SKILL.md guides and example resources under .github/skills/, updates AGENTS.md/.github/AGENTS.md, and revises .github/CODEOWNERS. All edits are documentation-only.

Changes

Cohort / File(s) Summary
Entry Point & Index
AGENTS.md, .github/AGENTS.md, .github/skills/README.md
Rewrite of agent entry guidance: explicit cuOpt AI Agent entry point, Quick Start, Skills Directory, resource links, and manifest path references.
LP / MILP Skill + Examples
.github/skills/cuopt-lp-milp/SKILL.md, .github/skills/cuopt-lp-milp/resources/python_examples.md, .github/skills/cuopt-lp-milp/resources/c_api_examples.md, .github/skills/cuopt-lp-milp/resources/cli_examples.md, .github/skills/cuopt-lp-milp/resources/server_examples.md
New LP/MILP modeling guide with Python/C/CLI/REST examples, CSR format, solver settings, status handling, and troubleshooting.
QP Skill + Examples
.github/skills/cuopt-qp/SKILL.md, .github/skills/cuopt-qp/resources/python_examples.md
New QP skill: convexity and MINIMIZE requirements, Python examples, status semantics, and solver notes.
Routing Skill + Examples
.github/skills/cuopt-routing/SKILL.md, .github/skills/cuopt-routing/resources/python_examples.md, .github/skills/cuopt-routing/resources/server_examples.md
Routing SKILL added with VRP/PDP/TSP modeling, time windows/capacity examples, Python and REST payload mappings, and solution-checking guidance.
Server Skill & Server Examples
.github/skills/cuopt-server/SKILL.md, .github/skills/cuopt-server/resources/lp_milp_examples.md, .github/skills/cuopt-server/resources/routing_examples.md
Server deployment and API docs: endpoints, payload/response schemas for LP/MILP/routing, health checks, polling examples, and terminology mapping.
Installation & Verification
.github/skills/cuopt-installation/SKILL.md, .github/skills/cuopt-installation/resources/verification_examples.md
Comprehensive installation workflows (local/cloud/Docker), verification commands, package/env checks, and troubleshooting procedures.
Developer & Debugging
.github/skills/cuopt-developer/SKILL.md, .github/skills/cuopt-debugging/SKILL.md, .github/skills/cuopt-debugging/resources/diagnostic_snippets.md
Developer contribution rules, build/test/DCO guidance, escalation paths, and extensive debugging diagnostics/snippets for LP/MILP/routing/server issues.
User Rules / Agent Behavior
.github/skills/cuopt-user-rules/SKILL.md, .github/skills/README.md
Agent/user interaction rules, verification checklists, clarification prompts, and resource references for safe agent behavior.
Examples & Language Snippets
.github/skills/*/resources/*.md
Collection of runnable examples across skills (Python, C API, curl/REST) showing typical problem setups, payload formats, and example responses.
Manifest & Ownership
.github/CODEOWNERS
Updated CODEOWNERS to include agent/infra/packaging paths and ownership entries for AGENTS/skills-related files and infra.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main change: introducing a new agentic skills structure organized by roles and modules with cuopt-specific skill directories.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🤖 Fix all issues with AI agents
In @.github/skills/cuopt-debugging/SKILL.md:
- Around line 182-205: The LP/MILP status tables need a clarifying note: update
the "LP Status Values" (near the LP table) to state that solve_lp() and
solve_mip() run concurrent PDLP (barrier) + Dual Simplex by default, and that
the terminal statuses PrimalInfeasible and DualInfeasible are emitted only by
the Dual Simplex solver (the pure PDLP barrier solver does not produce
infeasible/unbounded diagnoses); also add a short sentence explaining that
PDLP-only mode will not return those statuses and how users can switch to/enable
Dual Simplex if they need infeasible/unbounded reporting.

In @.github/skills/cuopt-developer/SKILL.md:
- Around line 84-89: Update the wording in the architecture section so
cpp/include/cuopt/ is described as internal C++ headers
(implementation/intermediate infrastructure) rather than “Public C/C++ headers”;
explicitly state that the officially supported public APIs are the C API
(cuopt_c.h) and the Python API, and remove any implication of a public C++ API.

In @.github/skills/cuopt-installation/SKILL.md:
- Line 75: The pinned version formats in the installation examples are
inconsistent: update the three occurrences so they use the same versioning style
(either "26.2.*" or "26.02.*") across the pip cuopt-cu12 example ('pip install
... cuopt-cu12'), the pip cuopt-server-cu12 example ('pip install ...
cuopt-server-cu12'), and the conda cuopt example (the conda install entry); pick
the canonical format used by the packages and make all three examples match
exactly.

In @.github/skills/cuopt-lp-milp/resources/python_examples.md:
- Around line 224-238: Update the "Status Checking (Critical)" section to
include the missing LP termination values from the LPTerminationStatus enum
(IterationLimit, NoTermination, ConcurrentLimit) and expand the explanatory text
to state that different solvers (e.g., Barrier, PDLP, Dual Simplex) may return
different subsets of these statuses in practice; reference the
LPTerminationStatus enum name and the existing example checks
(problem.Status.name) so readers know to match against the enum string values
rather than hard-coded uppercase strings and provide a brief enumerated list of
the full LP statuses and a note about solver-specific behavior.

In @.github/skills/cuopt-lp-milp/SKILL.md:
- Around line 110-126: The LP Status Values list is missing the ConcurrentLimit
enum value; update the explanatory list under "LP Status Values" to include
"ConcurrentLimit" so it matches the pdlp_termination_status_t enum used by
concurrent solver methods (i.e., change the list for LP Status Values to include
Optimal, NoTermination, NumericalError, PrimalInfeasible, DualInfeasible,
IterationLimit, TimeLimit, PrimalFeasible, ConcurrentLimit).

In @.github/skills/cuopt-routing/SKILL.md:
- Around line 162-180: The documentation example lists four SolutionStatus
values but the server-side solver only returns SUCCESS and FAIL in practice;
update SKILL.md to clarify that solution.get_status() will practically return
only 0 (SUCCESS) or 1 (FAIL) and that the enum values 2 (TIMEOUT) and 3 (EMPTY)
exist in the client API but cause HTTP 409 on the server and are not returned by
the solver. Amend the example and surrounding text to reflect this behavior,
reference the SolutionStatus enum and solution.get_status() in the explanation,
and optionally show a short guarded example that handles only 0 and 1 while
noting 2/3 are server-side 409 cases.
- Around line 131-160: The example payload in the "Minimal REST Payload" uses
the wrong nested key ("data") inside cost_matrix_data and
travel_time_matrix_data; update the payload so both objects use "cost_matrix" as
the inner key (e.g., change cost_matrix_data: {"data": ...} to cost_matrix_data:
{"cost_matrix": ...} and similarly for travel_time_matrix_data) so it matches
the API spec and the rest of the documentation.

In @.github/skills/cuopt-user-rules/SKILL.md:
- Line 142: The document has duplicated heading numbers: "## 7. Ask Before
Running" and "## 7. No Privileged Operations"; update the second heading title
("## 7. No Privileged Operations") to "## 8. No Privileged Operations" so
section numbering is sequential—locate the second heading text and change the
leading "7." to "8." (refer to the headings "## 7. Ask Before Running" and "##
7. No Privileged Operations" to find the spot).
🧹 Nitpick comments (6)
.github/skills/README.md (1)

14-40: Optional: Address markdown formatting warnings.

The markdownlint tool flags missing blank lines around tables and inconsistent table column spacing. While these don't affect readability, addressing them would improve markdown consistency.

📝 Proposed formatting fixes

Add blank lines before and after each table, and ensure consistent spacing in table pipes:

 ## Skills Index
+
 ### Rules
+
 | Skill | Description |
 |-------|-------------|
 | `cuopt-user-rules/` | Behavior rules for user tasks (read first) |
+
 ### Problem-Solving
+
 | Skill | Description |
 |-------|-------------|
-| `cuopt-routing/` | VRP, TSP, PDP, fleet optimization |
-| `cuopt-lp-milp/` | Linear & mixed-integer programming |
-| `cuopt-qp/` | Quadratic programming (beta) |
+| `cuopt-routing/`   | VRP, TSP, PDP, fleet optimization |
+| `cuopt-lp-milp/`   | Linear & mixed-integer programming |
+| `cuopt-qp/`        | Quadratic programming (beta) |

Apply similar formatting to the remaining tables.

.github/skills/cuopt-server/SKILL.md (1)

67-74: Optional: Address markdown table formatting.

Similar to the skills README, markdownlint flags inconsistent table column spacing. While not affecting readability, consistent formatting would improve markdown quality.

Also applies to: 193-199

.github/skills/cuopt-lp-milp/resources/c_api_examples.md (1)

61-97: Add minimal error handling for settings creation and allocation.

The LP example skips status checks for cuOptCreateSolverSettings / cuOptSet*Parameter and doesn’t guard malloc. A small addition avoids examples that crash on failure.

✅ Suggested adjustments
-    cuOptCreateSolverSettings(&settings);
-    cuOptSetFloatParameter(settings, CUOPT_ABSOLUTE_PRIMAL_TOLERANCE, 0.0001);
-    cuOptSetFloatParameter(settings, CUOPT_TIME_LIMIT, 60.0);
+    status = cuOptCreateSolverSettings(&settings);
+    if (status != CUOPT_SUCCESS) { printf("Error creating settings: %d\n", status); goto cleanup; }
+    status = cuOptSetFloatParameter(settings, CUOPT_ABSOLUTE_PRIMAL_TOLERANCE, 0.0001);
+    if (status != CUOPT_SUCCESS) { printf("Error setting param: %d\n", status); goto cleanup; }
+    status = cuOptSetFloatParameter(settings, CUOPT_TIME_LIMIT, 60.0);
+    if (status != CUOPT_SUCCESS) { printf("Error setting param: %d\n", status); goto cleanup; }
 ...
-    cuopt_float_t* sol = malloc(num_variables * sizeof(cuopt_float_t));
+    cuopt_float_t* sol = malloc(num_variables * sizeof(cuopt_float_t));
+    if (!sol) { printf("Allocation failed\n"); goto cleanup; }
.github/skills/cuopt-debugging/SKILL.md (1)

118-123: Specify a language for the fenced block to satisfy markdownlint (MD040).

💡 Minimal markdown tweak
-```
+```text
❌ transit_time_matrix_data → ✅ travel_time_matrix_data
❌ vehicle_capacities       → ✅ capacities
❌ locations                → ✅ task_locations
.github/skills/cuopt-developer/SKILL.md (1)

27-34: Add a language hint to the fenced block (MD040).

💡 Minimal markdown tweak
-```
+```text
"Let me confirm:
- Component: [cpp/python/server/docs]
- Change: [what you'll modify]
- Tests needed: [what tests to add/update]
Is this correct?"
.github/skills/cuopt-lp-milp/resources/python_examples.md (1)

31-33: Document parameter ranges and units for SolverSettings.

The code examples use time_limit, mip_relative_gap, and log_to_console parameters without documenting their valid ranges or units. Add inline comments clarifying:

  • time_limit: seconds (numeric, no default limit)
  • mip_relative_gap: fractional tolerance, 0.0–1.0 (e.g., 0.01 = 1% gap)
  • log_to_console: 0 (disabled) or 1 (enabled)
Suggested addition

At lines 31–33:

settings = SolverSettings()
settings.set_parameter("time_limit", 60)  # seconds
settings.set_parameter("log_to_console", 1)  # 0=off, 1=on

At lines 118–119:

settings.set_parameter("time_limit", 120)  # seconds
settings.set_parameter("mip_relative_gap", 0.01)  # 1% optimality gap

This aligns with the guideline to document parameter ranges in API documentation.

Comment on lines +182 to +205
## Status Code Reference

### LP Status Values
| Status | Meaning |
|--------|---------|
| `Optimal` | Found optimal solution |
| `PrimalFeasible` | Found feasible but may not be optimal |
| `PrimalInfeasible` | No feasible solution exists |
| `DualInfeasible` | Problem is unbounded |
| `TimeLimit` | Stopped due to time limit |
| `IterationLimit` | Stopped due to iteration limit |
| `NumericalError` | Numerical issues encountered |
| `NoTermination` | Solver didn't converge |

### MILP Status Values
| Status | Meaning |
|--------|---------|
| `Optimal` | Found optimal solution |
| `FeasibleFound` | Found feasible, within gap tolerance |
| `Infeasible` | No feasible solution exists |
| `Unbounded` | Problem is unbounded |
| `TimeLimit` | Stopped due to time limit |
| `NoTermination` | No solution found yet |

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find status enum definitions
find . -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.cu" -o -name "*.cpp" \) | head -20 | xargs grep -l "enum.*Status" 2>/dev/null | head -10

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

# Search for Status enum definition in headers
fd -e h -e hpp | xargs grep -B2 -A10 "enum.*Status" 2>/dev/null | head -100

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

# Find where solver status values are defined or assigned
rg "Optimal|PrimalInfeasible|DualInfeasible|INFEASIBLE|UNBOUNDED" -t cpp -t h -A2 -B2 | grep -i "status\|enum" | head -50

Repository: NVIDIA/cuopt

Length of output: 4542


🏁 Script executed:

# Check the solve.cu file mentioned in the learning to understand barrier solver limitations
find . -path "*/linear_programming/solve.cu" -exec cat {} \; 2>/dev/null | head -100

Repository: NVIDIA/cuopt

Length of output: 5408


🏁 Script executed:

# Find the public status enum definitions
fd -e h -e hpp -e cu | xargs grep -l "problem\.Status\|enum.*Status" | grep -E "(api|public|include|python)" | head -10

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

# Search for status enums in solve.hpp or main solver files
rg "enum class.*status_t|enum.*Status" -A 8 -B 1 | head -100

Repository: NVIDIA/cuopt

Length of output: 6268


🏁 Script executed:

# Find the main solver dispatch logic
find . -path "*/linear_programming/solve.cu" -o -path "*/linear_programming/solve.hpp" | xargs cat 2>/dev/null | grep -A 30 "enum\|return.*status" | head -80

Repository: NVIDIA/cuopt

Length of output: 3884


🏁 Script executed:

# Check Python bindings to see what status values are exposed to users
find . -name "*.py" -type f | xargs grep -l "Status\|status" | head -5

Repository: NVIDIA/cuopt

Length of output: 470


🏁 Script executed:

# Look for the status enum that maps to problem.Status.name
rg "class.*Status|status_to_string|status_name" -t cpp -t h -B2 -A5 | head -100

Repository: NVIDIA/cuopt

Length of output: 1590


🏁 Script executed:

# Find PDLP termination status enum
fd -e h -e hpp | xargs grep -A 15 "enum class pdlp_termination_status_t" 2>/dev/null

Repository: NVIDIA/cuopt

Length of output: 1859


🏁 Script executed:

# Check which solver is default for LP problems
rg "run_barrier|run_dual_simplex" -B 5 -A 5 --max-count=10 | grep -E "(if|else|default|barrier|simplex)" | head -30

Repository: NVIDIA/cuopt

Length of output: 3177


🏁 Script executed:

# Find public API for LP solver - check optimization_problem or solver interface
fd -e h -e hpp "optimization_problem" | head -5 | xargs cat 2>/dev/null | grep -A 20 "Status\|status"

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

# Look at PDLP solver solution header to understand what status values are exposed
cat cpp/include/cuopt/linear_programming/pdlp/solver_solution.hpp 2>/dev/null | head -100

Repository: NVIDIA/cuopt

Length of output: 4195


🏁 Script executed:

# Check the run_barrier function signature and implementation more carefully
rg "run_barrier.*{" -A 50 cpp/src/linear_programming/solve.cu | head -150

Repository: NVIDIA/cuopt

Length of output: 147


🏁 Script executed:

# Look for comments or documentation about barrier solver limitations
rg "barrier.*INFEASIBLE|barrier.*UNBOUNDED|barrier.*return" cpp/src/linear_programming/solve.cu -B 3 -A 3 | head -80

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

# Check if there's a pure PDLP implementation vs barrier wrapping dual simplex
fd -e cu "*.cu" | xargs grep -l "pdlp\|PDLP" | head -5

Repository: NVIDIA/cuopt

Length of output: 339


🏁 Script executed:

# Look at the actual PDLP solver implementation to see what it returns
find . -path "*/linear_programming/pdlp.cuh" -o -path "*/linear_programming/pdlp.cu" | xargs cat 2>/dev/null | grep -A 5 "return.*status\|termination" | head -100

Repository: NVIDIA/cuopt

Length of output: 4631


🏁 Script executed:

# Find where solve() method is defined and what it calls
rg "void.*solve\(|solve\(" cpp/include/cuopt -B 2 -A 10 | head -80

Repository: NVIDIA/cuopt

Length of output: 5892


🏁 Script executed:

# Check for solver selection logic
rg "barrier|simplex" cpp/src/linear_programming/solve.cu | grep -i "select\|choose\|default\|if\|use" | head -30

Repository: NVIDIA/cuopt

Length of output: 1958


🏁 Script executed:

# Look at optimization_problem solve method
fd -e hpp "optimization_problem" cpp/include | xargs grep -A 20 "solve(" 2>/dev/null | head -80

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

# Check what status values the PDLP solver can actually return based on termination logic
rg "PrimalInfeasible|DualInfeasible" cpp/include/cuopt/linear_programming/pdlp -B 3 -A 3 | head -60

Repository: NVIDIA/cuopt

Length of output: 2710


🏁 Script executed:

# Find the main solve function for LP and see which solver it uses by default
rg "optimization_problem_solution_t.*solve\(" cpp/src/linear_programming -A 30 | grep -E "(barrier|simplex|pdlp|run_|if|settings)" | head -40

Repository: NVIDIA/cuopt

Length of output: 1242


🏁 Script executed:

# Check the solve.cu file around line 732 where the learning mentions barrier solver
sed -n '720,760p' cpp/src/linear_programming/solve.cu

Repository: NVIDIA/cuopt

Length of output: 2004


🏁 Script executed:

# Look for the main public solve functions
rg "template.*solve\(" cpp/include/cuopt/linear_programming/solve.hpp -A 20 | head -100

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

# Find the main solve entry points for LP
cat cpp/include/cuopt/linear_programming/solve.hpp | head -150

Repository: NVIDIA/cuopt

Length of output: 6601


🏁 Script executed:

# Check how the solver selects between barrier and simplex
rg "barrier_thread|dual_simplex_thread|concurrent" cpp/src/linear_programming/solve.cu -B 2 -A 5 | head -80

Repository: NVIDIA/cuopt

Length of output: 3840


🏁 Script executed:

# Verify the PDLP enum definition matches what the header documents
rg "CUOPT_TERIMINATION_STATUS_" cpp/include -r | grep "define\|enum" | head -30

Repository: NVIDIA/cuopt

Length of output: 469


🏁 Script executed:

# Find the constants definition for termination statuses
fd -e h "constants" cpp/include/cuopt/linear_programming | xargs grep -A 20 "CUOPT_TERIMINATION_STATUS"

Repository: NVIDIA/cuopt

Length of output: 1132


🏁 Script executed:

# Check the solve_lp function implementation to see final status mapping
rg "solve_lp" cpp/src/linear_programming/solve.cu -A 100 | grep -E "(status|return|barrier|simplex)" | head -50

Repository: NVIDIA/cuopt

Length of output: 2024


Clarify which LP solver modes emit infeasible/unbounded statuses.

The documented LP/MILP status values are correct for the public solve_lp() and solve_mip() APIs, which use concurrent execution (PDLP + Dual Simplex). However, the table omits a critical caveat: PrimalInfeasible and DualInfeasible statuses are only returned by the Dual Simplex solver; the pure PDLP barrier solver does not emit these statuses. Users relying on PDLP-only mode will not observe infeasible or unbounded diagnoses. Add a note specifying which solver modes produce which terminal statuses, or clarify the default behavior.

🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 185-185: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 186-186: Table column style
Table pipe is missing space to the right for style "compact"

(MD060, table-column-style)


[warning] 186-186: Table column style
Table pipe is missing space to the left for style "compact"

(MD060, table-column-style)


[warning] 186-186: Table column style
Table pipe is missing space to the right for style "compact"

(MD060, table-column-style)


[warning] 186-186: Table column style
Table pipe is missing space to the left for style "compact"

(MD060, table-column-style)


[warning] 197-197: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 198-198: Table column style
Table pipe is missing space to the right for style "compact"

(MD060, table-column-style)


[warning] 198-198: Table column style
Table pipe is missing space to the left for style "compact"

(MD060, table-column-style)


[warning] 198-198: Table column style
Table pipe is missing space to the right for style "compact"

(MD060, table-column-style)


[warning] 198-198: Table column style
Table pipe is missing space to the left for style "compact"

(MD060, table-column-style)

🤖 Prompt for AI Agents
In @.github/skills/cuopt-debugging/SKILL.md around lines 182 - 205, The LP/MILP
status tables need a clarifying note: update the "LP Status Values" (near the LP
table) to state that solve_lp() and solve_mip() run concurrent PDLP (barrier) +
Dual Simplex by default, and that the terminal statuses PrimalInfeasible and
DualInfeasible are emitted only by the Dual Simplex solver (the pure PDLP
barrier solver does not produce infeasible/unbounded diagnoses); also add a
short sentence explaining that PDLP-only mode will not return those statuses and
how users can switch to/enable Dual Simplex if they need infeasible/unbounded
reporting.

Comment on lines +84 to +89
```
cuopt/
├── cpp/ # Core C++ engine
│ ├── include/cuopt/ # Public C/C++ headers
│ ├── src/ # Implementation (CUDA kernels)
│ └── tests/ # C++ unit tests (gtest)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clarify public API wording for cpp/include/cuopt.

The architecture section labels cpp/include/cuopt/ as “Public C/C++ headers,” but C++ headers there are internal; public APIs are C (via cuopt_c.h) and Python. Please adjust to avoid implying public C++ API support.

✏️ Suggested wording
-│   ├── include/cuopt/      # Public C/C++ headers
+│   ├── include/cuopt/      # Public C headers (cuopt_c.h) + internal C++ headers

Based on learnings: C++ headers under cpp/include/cuopt are internal/intermediate infrastructure, not public-facing. The officially supported public APIs for cuOpt are C (via cuopt_c.h) and Python.

🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 84-84: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In @.github/skills/cuopt-developer/SKILL.md around lines 84 - 89, Update the
wording in the architecture section so cpp/include/cuopt/ is described as
internal C++ headers (implementation/intermediate infrastructure) rather than
“Public C/C++ headers”; explicitly state that the officially supported public
APIs are the C API (cuopt_c.h) and the Python API, and remove any implication of
a public C++ API.

pip install --extra-index-url=https://pypi.nvidia.com cuopt-cu12

# With version pinning (recommended for reproducibility)
pip install --extra-index-url=https://pypi.nvidia.com 'cuopt-cu12==26.2.*'
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check actual cuOpt version formats on PyPI

echo "=== PyPI versions for cuopt-cu12 ==="
curl -s https://pypi.org/pypi/cuopt-cu12/json | jq -r '.releases | keys[]' | grep -E '^26\.' | sort -V | tail -10

echo -e "\n=== PyPI versions for cuopt-server-cu12 ==="
curl -s https://pypi.org/pypi/cuopt-server-cu12/json | jq -r '.releases | keys[]' | grep -E '^26\.' | sort -V | tail -10

echo -e "\n=== PyPI versions for cuopt ==="
curl -s https://pypi.org/pypi/cuopt/json | jq -r '.releases | keys[]' | grep -E '^26\.' | sort -V | tail -10

Repository: NVIDIA/cuopt

Length of output: 237


🏁 Script executed:

#!/bin/bash
# Check PyPI versions using curl and grepping HTML responses

echo "=== Checking cuopt-cu12 on PyPI ==="
curl -s https://pypi.org/simple/cuopt-cu12/ | grep -oP 'cuopt-cu12-[^<]+' | head -10

echo -e "\n=== Checking cuopt-server-cu12 on PyPI ==="
curl -s https://pypi.org/simple/cuopt-server-cu12/ | grep -oP 'cuopt-server-cu12-[^<]+' | head -10

echo -e "\n=== Checking cuopt on PyPI ==="
curl -s https://pypi.org/simple/cuopt/ | grep -oP 'cuopt-[^<]+' | head -10

echo -e "\n=== Checking exact version pattern for 26.x versions ==="
curl -s https://pypi.org/simple/cuopt-cu12/ | grep -oP '26\.[0-9]+\.[0-9]+' | sort -u

Repository: NVIDIA/cuopt

Length of output: 225


🏁 Script executed:

#!/bin/bash
# Read the specific lines from SKILL.md to verify the version formats
sed -n '70,105p' .github/skills/cuopt-installation/SKILL.md

Repository: NVIDIA/cuopt

Length of output: 885


Inconsistent version format in pinning examples.

The version format differs across installation examples:

  • Line 75 (pip cuopt-cu12): 26.2.* (two components)
  • Line 87 (pip cuopt-server-cu12): 26.02.* (zero-padded)
  • Line 100 (conda cuopt): 26.02.* (zero-padded)

Clarify whether these packages use different versioning schemes or update the examples to use consistent formatting.

🤖 Prompt for AI Agents
In @.github/skills/cuopt-installation/SKILL.md at line 75, The pinned version
formats in the installation examples are inconsistent: update the three
occurrences so they use the same versioning style (either "26.2.*" or "26.02.*")
across the pip cuopt-cu12 example ('pip install ... cuopt-cu12'), the pip
cuopt-server-cu12 example ('pip install ... cuopt-server-cu12'), and the conda
cuopt example (the conda install entry); pick the canonical format used by the
packages and make all three examples match exactly.

Comment on lines 224 to 238
## Status Checking (Critical)

```python
# ✅ CORRECT - use PascalCase
if problem.Status.name in ["Optimal", "FeasibleFound"]:
print(problem.ObjValue)

# ❌ WRONG - will silently fail!
if problem.Status.name == "OPTIMAL": # Never matches!
print(problem.ObjValue)

# LP status values: Optimal, PrimalFeasible, PrimalInfeasible,
# DualInfeasible, TimeLimit, NumericalError
# MILP status values: Optimal, FeasibleFound, Infeasible,
# Unbounded, TimeLimit, NoTermination
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

cuOpt Python API Problem.Status barrier solver documentation

💡 Result:

Problem.Status (Python)

  • The Python LP/MILP modeling API documents Problem.Status as “(int) Status of the problem after solving” on the LP and MILP API Reference page. The page does not list the full set of status values/names. [1]
  • The LP and MILP Examples show that in practice you can access a human-readable name via problem.Status.name (e.g., "Optimal"). [2]
  • For the actual status meanings, NVIDIA’s docs do explicitly enumerate them in the C API examples as termination-status constants (e.g., Optimal, Infeasible, Unbounded, Iteration limit, Time limit, Numerical error). These are the clearest published definitions to map against when interpreting status codes. [3]

Barrier solver (LP/QP) documentation

  • Barrier is enabled via the solver parameter CUOPT_METHOD = Barrier (other options include Concurrent/PDLP/Dual Simplex). This is documented under LP, QP and MILP Settings → Method. [4]
  • Barrier-specific tuning knobs (folding, dualize, ordering, etc.) are documented under LP and MILP Settings → Barrier Solver Settings. [5]
  • Also note: for QP, NVIDIA documents that barrier is currently the only method that supports QPs. [6]

Sources: [1] [2] [3] [4] [5] [6]


🏁 Script executed:

# Search the repository for documentation on Problem.Status values
find . -name "*.md" -o -name "*.py" | head -20

Repository: NVIDIA/cuopt

Length of output: 941


🏁 Script executed:

# Search for references to Problem.Status in the codebase
rg "Problem\.Status" --type py -A 2 -B 2 | head -50

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

# Look at the specific file mentioned in the review
cat -n .github/skills/cuopt-lp-milp/resources/python_examples.md | sed -n '220,245p'

Repository: NVIDIA/cuopt

Length of output: 803


🏁 Script executed:

# Search for status values in the barrier solver implementation
rg "OPTIMAL|INFEASIBLE|UNBOUNDED|NUMERICAL" cpp/src/linear_programming/solve.cu -A 1 -B 1 | head -100

Repository: NVIDIA/cuopt

Length of output: 1774


🏁 Script executed:

# Search for Status enum or constant definitions in Python API
find . -name "*.py" -type f | xargs rg "class Status|Status\s*=" | head -30

Repository: NVIDIA/cuopt

Length of output: 238


🏁 Script executed:

# Look for barrier solver return status handling
rg "barrier|Barrier" cpp/src/linear_programming/solve.cu -A 3 -B 3 | head -100

Repository: NVIDIA/cuopt

Length of output: 4792


🏁 Script executed:

# Check if there are Python bindings that define Status values
find . -name "*.pyx" -o -name "*.pxd" | xargs rg "Status" 2>/dev/null | head -20

Repository: NVIDIA/cuopt

Length of output: 1186


🏁 Script executed:

# Read the actual termination status enum definitions
cat -n python/cuopt/cuopt/linear_programming/solver/solver_wrapper.pyx | grep -A 20 "class LPTerminationStatus\|class MILPTerminationStatus"

Repository: NVIDIA/cuopt

Length of output: 1447


🏁 Script executed:

# Search for pdlp_termination_status_t enum definition
rg "pdlp_termination_status_t" cpp/src/linear_programming/solve.cu -B 5 -A 15 | head -80

Repository: NVIDIA/cuopt

Length of output: 3737


🏁 Script executed:

# Check what the barrier solver actually returns in the code
rg "to_termination_status" cpp/src/linear_programming/solve.cu -A 5 -B 2 | head -100

Repository: NVIDIA/cuopt

Length of output: 2003


LP status documentation is incomplete and lacks solver-specific clarity.

The current LP status list is missing several values present in the actual LPTerminationStatus enum: IterationLimit, NoTermination, and ConcurrentLimit. Additionally, the documentation doesn't clarify that different solvers (Barrier, PDLP, Dual Simplex) may return different subsets of these statuses in practice.

✏️ Suggested clarification
-# LP status values: Optimal, PrimalFeasible, PrimalInfeasible, 
-#                   DualInfeasible, TimeLimit, NumericalError
+# LP status values: Optimal, PrimalFeasible, PrimalInfeasible,
+#                   DualInfeasible, TimeLimit, IterationLimit, 
+#                   NumericalError, NoTermination, ConcurrentLimit
+# Note: Different LP solvers may return different subsets of these values
🤖 Prompt for AI Agents
In @.github/skills/cuopt-lp-milp/resources/python_examples.md around lines 224 -
238, Update the "Status Checking (Critical)" section to include the missing LP
termination values from the LPTerminationStatus enum (IterationLimit,
NoTermination, ConcurrentLimit) and expand the explanatory text to state that
different solvers (e.g., Barrier, PDLP, Dual Simplex) may return different
subsets of these statuses in practice; reference the LPTerminationStatus enum
name and the existing example checks (problem.Status.name) so readers know to
match against the enum string values rather than hard-coded uppercase strings
and provide a brief enumerated list of the full LP statuses and a note about
solver-specific behavior.

Comment on lines +110 to +126
## CRITICAL: Status Checking

**Status values use PascalCase, NOT ALL_CAPS:**

```python
# ✅ CORRECT
if problem.Status.name in ["Optimal", "FeasibleFound"]:
print(problem.ObjValue)

# ❌ WRONG - will silently fail!
if problem.Status.name == "OPTIMAL": # Never matches!
print(problem.ObjValue)
```

**LP Status Values:** `Optimal`, `NoTermination`, `NumericalError`, `PrimalInfeasible`, `DualInfeasible`, `IterationLimit`, `TimeLimit`, `PrimalFeasible`

**MILP Status Values:** `Optimal`, `FeasibleFound`, `Infeasible`, `Unbounded`, `TimeLimit`, `NoTermination`
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Find status enum definitions
fd -e cu -e cuh -e cpp -e hpp -e h | head -20 | xargs rg -l "Status|OPTIMAL|Optimal" | head -10

Repository: NVIDIA/cuopt

Length of output: 432


🏁 Script executed:

# Search for status enum definitions more directly
rg "enum.*Status|OPTIMAL|Optimal" --type cpp --type cu -B 2 -A 10 | head -100

Repository: NVIDIA/cuopt

Length of output: 82


🏁 Script executed:

# Find barrier solver implementation
fd "solve.cu" | xargs cat -n | head -50

Repository: NVIDIA/cuopt

Length of output: 2340


🏁 Script executed:

# Look for status return values in solve files
rg "return.*Status|Status.*=|\.Status" --type cpp --type cu | head -30

Repository: NVIDIA/cuopt

Length of output: 82


🏁 Script executed:

# Find where Status values/names are defined
fd -e cu -e cuh -e cpp -e hpp | xargs rg "PrimalInfeasible|DualInfeasible|Unbounded|Infeasible|Unbounded" | head -20

Repository: NVIDIA/cuopt

Length of output: 2209


🏁 Script executed:

# Find status type definitions
fd -type f -name "*.h" -o -name "*.hpp" | xargs rg "termination_status|Status.*enum" -B 2 -A 10 | head -150

Repository: NVIDIA/cuopt

Length of output: 13968


🏁 Script executed:

# Look for constants.h which was listed
cat cpp/include/cuopt/linear_programming/constants.h | head -200

Repository: NVIDIA/cuopt

Length of output: 5268


🏁 Script executed:

# Find MIP status enum
fd -type f \( -name "*.h" -o -name "*.hpp" \) | xargs rg "mip_termination_status|enum.*Status" -B 2 -A 15 | head -200

Repository: NVIDIA/cuopt

Length of output: 18947


🏁 Script executed:

# Find PDLP status enum
fd -type f \( -name "*.h" -o -name "*.hpp" \) | xargs rg "pdlp_termination_status|barrier.*status" -B 2 -A 15 | head -200

Repository: NVIDIA/cuopt

Length of output: 19128


🏁 Script executed:

# Look for default solver selection
fd -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.cpp" \) | xargs rg "default.*solver|barrier|simplex|pdlp" -i | head -50

Repository: NVIDIA/cuopt

Length of output: 5852


🏁 Script executed:

# Double-check the ConcurrentLimit in LP enum
fd -name "solver_solution.hpp" | xargs rg -A 10 "enum class pdlp_termination_status_t"

Repository: NVIDIA/cuopt

Length of output: 1587


🏁 Script executed:

# Verify Python enum mapping for LP
fd -name "solver_wrapper.pyx" | xargs rg -A 15 "class LPTerminationStatus"

Repository: NVIDIA/cuopt

Length of output: 2051


LP Status Values list is incomplete.

The documented LP Status Values omit ConcurrentLimit, which is part of the actual pdlp_termination_status_t enum and can be returned by concurrent solver methods. Update the list to include it:

# LP Status Values: Optimal, NoTermination, NumericalError, PrimalInfeasible, DualInfeasible, IterationLimit, TimeLimit, PrimalFeasible, ConcurrentLimit

The MILP Status Values list is accurate and complete.

🤖 Prompt for AI Agents
In @.github/skills/cuopt-lp-milp/SKILL.md around lines 110 - 126, The LP Status
Values list is missing the ConcurrentLimit enum value; update the explanatory
list under "LP Status Values" to include "ConcurrentLimit" so it matches the
pdlp_termination_status_t enum used by concurrent solver methods (i.e., change
the list for LP Status Values to include Optimal, NoTermination, NumericalError,
PrimalInfeasible, DualInfeasible, IterationLimit, TimeLimit, PrimalFeasible,
ConcurrentLimit).

Comment on lines +131 to +160
### Terminology Difference

| Concept | Python API | REST Server |
|---------|------------|-------------|
| Jobs | `order_locations` | `task_locations` |
| Time windows | `set_order_time_windows()` | `task_time_windows` |
| Service times | `set_order_service_times()` | `service_times` |

### Minimal REST Payload

```json
{
"cost_matrix_data": {
"data": {"0": [[0,10,15],[10,0,12],[15,12,0]]}
},
"travel_time_matrix_data": {
"data": {"0": [[0,10,15],[10,0,12],[15,12,0]]}
},
"task_data": {
"task_locations": [1, 2]
},
"fleet_data": {
"vehicle_locations": [[0, 0]],
"capacities": [[100]]
},
"solver_config": {
"time_limit": 10
}
}
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

cuOpt REST API OpenAPI specification field names task_locations service_times

💡 Result:

In the cuOpt REST API request payload (schema OptimizeRoutingData), both fields are in snake_case under task_data:

  • task_locations: array of integers (location indices into your cost/time matrix / waypoint graph). Must be ≥ 0. [1]
  • service_times: array of integers (per-task service duration). Must be ≥ 0. [1]

Example (from the server quickstart cURL payload):

"task_data": {
  "task_locations": [1],
  "service_times": [1]
}

[2]

Sources: [1] https://docs.nvidia.com/cuopt/service/latest/api.html, [2] https://docs.nvidia.com/cuopt/user-guide/latest/cuopt-server/quick-start.html


🌐 Web query:

cuOpt REST API travel_time_matrix_data field name schema

💡 Result:

travel_time_matrix_data in the cuOpt (managed service) problem JSON uses the same inner schema as cost_matrix_data: it is an object containing a cost_matrix map whose keys identify the matrix (typically the vehicle type id), and whose values are square 2‑D arrays (NxN) of non‑negative travel-time numbers.

Schema (JSON shape):

{
  "travel_time_matrix_data": {
    "cost_matrix": {
      "0": [[0, 2, 2],
            [1, 0, 2],
            [1, 1, 0]],
      "1": [[...], [...], [...]]
    }
  }
}

Notes:

  • Keys under cost_matrix are typically stringified integers like "0", "1" (one per vehicle type / matrix). [1][2]
  • Each value is a square matrix (NxN). [1]
  • travel_time_matrix_data is used for satisfying time constraints (e.g., time windows), and you can provide multiple matrices for heterogeneous fleets. [2][3]

Sources: [1] [2] [3]


Fix nested matrix field structure to use cost_matrix instead of data.

The top-level field names are correct, but the inner structure of both cost_matrix_data and travel_time_matrix_data should use "cost_matrix" as the key, not "data". Per the official API spec, the structure should be:

{
  "cost_matrix_data": {
    "cost_matrix": {"0": [[0,10,15],[10,0,12],[15,12,0]]}
  },
  "travel_time_matrix_data": {
    "cost_matrix": {"0": [[0,10,15],[10,0,12],[15,12,0]]}
  }
}
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 134-134: Table column style
Table pipe is missing space to the right for style "compact"

(MD060, table-column-style)


[warning] 134-134: Table column style
Table pipe is missing space to the left for style "compact"

(MD060, table-column-style)


[warning] 134-134: Table column style
Table pipe is missing space to the right for style "compact"

(MD060, table-column-style)


[warning] 134-134: Table column style
Table pipe is missing space to the left for style "compact"

(MD060, table-column-style)


[warning] 134-134: Table column style
Table pipe is missing space to the right for style "compact"

(MD060, table-column-style)


[warning] 134-134: Table column style
Table pipe is missing space to the left for style "compact"

(MD060, table-column-style)

🤖 Prompt for AI Agents
In @.github/skills/cuopt-routing/SKILL.md around lines 131 - 160, The example
payload in the "Minimal REST Payload" uses the wrong nested key ("data") inside
cost_matrix_data and travel_time_matrix_data; update the payload so both objects
use "cost_matrix" as the inner key (e.g., change cost_matrix_data: {"data": ...}
to cost_matrix_data: {"cost_matrix": ...} and similarly for
travel_time_matrix_data) so it matches the API spec and the rest of the
documentation.

Comment on lines 162 to 180
## Solution Checking

```python
status = solution.get_status()
# 0 = SUCCESS
# 1 = FAIL
# 2 = TIMEOUT
# 3 = EMPTY

if status == 0:
solution.display_routes()
route_df = solution.get_route()
total_cost = solution.get_total_objective()
else:
print(f"Error: {solution.get_error_message()}")
infeasible = solution.get_infeasible_orders()
if len(infeasible) > 0:
print(f"Infeasible orders: {infeasible.to_list()}")
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Search for solution status code definitions
find . -type f \( -name "*.md" -o -name "*.py" -o -name "*.json" -o -name "*.yaml" -o -name "*.yml" \) | head -20

Repository: NVIDIA/cuopt

Length of output: 866


🏁 Script executed:

# Search for references to solution status or get_status in the codebase
rg "get_status|solution.*status|status.*code" -t py -t md --max-count=20

Repository: NVIDIA/cuopt

Length of output: 27062


🏁 Script executed:

# Look for OpenAPI or API spec files
find . -type f \( -name "*openapi*" -o -name "*swagger*" -o -name "*api*.json" -o -name "*api*.yaml" \) 2>/dev/null

Repository: NVIDIA/cuopt

Length of output: 150


🏁 Script executed:

# Search in the cuopt-routing skill file and related documentation
find . -path "*/cuopt-routing/*" -type f

Repository: NVIDIA/cuopt

Length of output: 215


🏁 Script executed:

# Look for any documentation about solution status codes
rg "SUCCESS|FAIL|TIMEOUT|EMPTY" -t md -A 2 -B 2 | head -50

Repository: NVIDIA/cuopt

Length of output: 724


🏁 Script executed:

# Find and read the get_status() implementation in assignment.py
cat -n python/cuopt/cuopt/routing/assignment.py | grep -A 10 "def get_status"

Repository: NVIDIA/cuopt

Length of output: 415


🏁 Script executed:

# Search for status code definitions or enum mappings
rg "SUCCESS|FAIL|TIMEOUT|EMPTY" -t py -A 2 -B 2 | head -100

Repository: NVIDIA/cuopt

Length of output: 2135


🏁 Script executed:

# Look for any status code enum or constants in routing module
find python/cuopt/cuopt/routing -type f -name "*.py" | xargs grep -l "status\|Status" | head -5

Repository: NVIDIA/cuopt

Length of output: 212


🏁 Script executed:

# Check for OpenAPI or API documentation files that might define status codes
find . -type f \( -name "*.openapi.json" -o -name "*openapi*.yaml" -o -name "*openapi*.yml" \) 2>/dev/null

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

# Look at the routing solver implementation for status validation
cat -n python/cuopt_server/cuopt_server/utils/routing/solver.py | grep -A 5 -B 5 "valid_solve_status"

Repository: NVIDIA/cuopt

Length of output: 512


Clarify which routing status codes are returned in practice.

The status code mapping (0=SUCCESS, 1=FAIL, 2=TIMEOUT, 3=EMPTY) is defined in the Python routing API (SolutionStatus enum), but the server-side routing solver only validates statuses 0 and 1 as valid. Statuses 2 and 3 are defined in the enum but trigger HTTP 409 errors in the server. Clarify whether all four statuses can actually be returned by solution.get_status() or if only 0 and 1 are expected in practice.

🤖 Prompt for AI Agents
In @.github/skills/cuopt-routing/SKILL.md around lines 162 - 180, The
documentation example lists four SolutionStatus values but the server-side
solver only returns SUCCESS and FAIL in practice; update SKILL.md to clarify
that solution.get_status() will practically return only 0 (SUCCESS) or 1 (FAIL)
and that the enum values 2 (TIMEOUT) and 3 (EMPTY) exist in the client API but
cause HTTP 409 on the server and are not returned by the solver. Amend the
example and surrounding text to reflect this behavior, reference the
SolutionStatus enum and solution.get_status() in the explanation, and optionally
show a short guarded example that handles only 0 and 1 while noting 2/3 are
server-side 409 cases.


---

## 7. No Privileged Operations
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix duplicate section numbering.

There are two sections numbered "7" in this document:

  • Line 125: "## 7. Ask Before Running"
  • Line 142: "## 7. No Privileged Operations"

The second one should be numbered "8".

🔢 Proposed fix for section numbering
-## 7. No Privileged Operations
+## 8. No Privileged Operations
📝 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.

Suggested change
## 7. No Privileged Operations
## 8. No Privileged Operations
🤖 Prompt for AI Agents
In @.github/skills/cuopt-user-rules/SKILL.md at line 142, The document has
duplicated heading numbers: "## 7. Ask Before Running" and "## 7. No Privileged
Operations"; update the second heading title ("## 7. No Privileged Operations")
to "## 8. No Privileged Operations" so section numbering is sequential—locate
the second heading text and change the leading "7." to "8." (refer to the
headings "## 7. Ask Before Running" and "## 7. No Privileged Operations" to find
the spot).

@rgsl888prabhu rgsl888prabhu requested review from jameslamb and removed request for KyleFromNVIDIA January 30, 2026 23:05
@rgsl888prabhu
Copy link
Collaborator Author

@jameslamb would need your help on CODEOWNERS file changes. I wanted to make few set of folders and files to be part of infra code owners such as agentic files, templates and code rabbit files. Please let me know if I should restructure it so I can reduce changes to CODEOWNERS file and whether the current changes look good.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
.github/CODEOWNERS (1)

29-33: ⚠️ Potential issue | 🟡 Minor

Remove the non-existent .devcontainer/ entry from CODEOWNERS.

The /.devcontainer/ directory does not exist in the repository. The other packaging paths (conda/, dependencies.yaml, build.sh, pyproject.toml) are present. Remove line 29 (the .devcontainer/ entry) to keep CODEOWNERS accurate.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.github/skills/cuopt-lp-milp/resources/server_examples.md:
- Around line 149-155: The code block labeled as JSON contains JavaScript-style
comments which invalidates parsers; update the snippet so it is copy/paste-valid
by either changing the fenced block language from "json" to "jsonc" or by
removing the inline comments, keeping the object keys "constraint_bounds",
"lower_bounds", and "upper_bounds" intact and their values unchanged.
🧹 Nitpick comments (6)
.github/skills/cuopt-lp-milp/resources/server_examples.md (1)

137-145: Add a language to the CSR fenced block for MD040 compliance.
Static analysis flags this block as missing a fence language.

✅ Suggested fix
-```
+```text
 Matrix:  [2, 3]    (row 0: 2*x0 + 3*x1)
          [4, 2]    (row 1: 4*x0 + 2*x1)

 CSR format:
   offsets: [0, 2, 4]           # Row pointers
   indices: [0, 1, 0, 1]        # Column indices
   values:  [2.0, 3.0, 4.0, 2.0] # Non-zero values
.github/skills/cuopt-server/SKILL.md (3)

8-10: Consider linking the canonical agent entrypoint here as well.
This section points to cuopt-user-rules/SKILL.md, but the repo’s canonical entrypoint is .github/AGENTS.md; adding it can reduce onboarding ambiguity.

✅ Suggested tweak
-> **Prerequisites**: Read `cuopt-user-rules/SKILL.md` first for behavior rules.
+> **Prerequisites**: Read `.github/AGENTS.md` (entrypoint) and `cuopt-user-rules/SKILL.md` first for behavior rules.

Based on learnings: “The canonical AI-agent entrypoint for this repository is .github/AGENTS.md - coding agents should start there”.


67-74: Fix MD060 table spacing for the API endpoints table.
Static analysis flags spacing around pipes.

✅ Suggested fix
-| Endpoint | Method | Purpose |
-|----------|--------|---------|
+| Endpoint | Method | Purpose |
+| -------- | ------ | ------- |
 | `/cuopt/health` | GET | Health check |
 | `/cuopt/request` | POST | Submit optimization request |
 | `/cuopt/solution/{reqId}` | GET | Get solution by request ID |
 | `/cuopt.yaml` | GET | OpenAPI specification |
 | `/cuopt/docs` | GET | Swagger UI |

193-199: Fix MD060 table spacing in the REST vs Python API table.
Static analysis flags spacing around pipes here too.

✅ Suggested fix
-| Concept | Python API | REST API |
-|---------|------------|----------|
+| Concept | Python API | REST API |
+| ------- | ---------- | -------- |
 | Orders/Jobs | `order_locations` | `task_locations` |
 | Time windows | `set_order_time_windows()` | `task_time_windows` |
 | Service times | `set_order_service_times()` | `service_times` |
 | Transit matrix | `add_transit_time_matrix()` | `travel_time_matrix_data` |
.github/skills/cuopt-routing/SKILL.md (2)

184-190: Optional: Fix markdown table formatting.

The table on lines 184-190 has minor spacing issues around pipe characters. While this doesn't affect rendering in most viewers, adding spaces improves consistency with markdown best practices.

🎨 Formatted table
 | Problem | Likely Cause | Fix |
-|---------|--------------|-----|
+| ------- | ------------ | --- |
 | Empty solution | Time windows too tight | Widen windows or check travel times |
 | Infeasible orders | Demand > capacity | Increase fleet or capacity |
 | Status != 0 | Missing transit time matrix | Add `add_transit_time_matrix()` when using time windows |
 | Wrong route cost | Matrix not symmetric | Check cost_matrix values |

218-225: Optional: Vary phrasing to improve readability.

The repetition of "User wants to" in the escalation conditions can be streamlined for better flow.

✍️ Alternative phrasing
 Switch to **cuopt-developer** if:
-- User wants to modify solver behavior
-- User wants to add new constraint types
+- Modifying solver behavior is needed
+- Adding new constraint types is required

Comment on lines +149 to +155
```json
{
"constraint_bounds": {
"lower_bounds": ["ninf", "ninf"], // -infinity
"upper_bounds": [100.0, "inf"] // +infinity
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Make the “Special Values” snippet valid JSON for copy/paste.
The block is labeled json but includes // comments, which will break parsers. Consider jsonc or remove the comments.

✅ Suggested fix
-```json
+```jsonc
 {
   "constraint_bounds": {
-    "lower_bounds": ["ninf", "ninf"],  // -infinity
-    "upper_bounds": [100.0, "inf"]      // +infinity
+    "lower_bounds": ["ninf", "ninf"],  // -infinity
+    "upper_bounds": [100.0, "inf"]      // +infinity
   }
 }
🤖 Prompt for AI Agents
In @.github/skills/cuopt-lp-milp/resources/server_examples.md around lines 149 -
155, The code block labeled as JSON contains JavaScript-style comments which
invalidates parsers; update the snippet so it is copy/paste-valid by either
changing the fenced block language from "json" to "jsonc" or by removing the
inline comments, keeping the object keys "constraint_bounds", "lower_bounds",
and "upper_bounds" intact and their values unchanged.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.github/skills/cuopt-lp-milp/resources/server_examples.md:
- Around line 139-147: The fenced code block containing the CSR example (the
block starting with "Matrix:  [2, 3]" and the closing triple backticks) is
missing a language tag and triggers MD040; update the opening fence from "```"
to "```text" (and keep the closing fence) so the block is explicitly marked as
text, ensuring the CSR example (offsets/indices/values) is rendered correctly.

In @.github/skills/cuopt-server/resources/lp_milp_examples.md:
- Around line 133-136: The JSON snippet under "lower_bounds" and "upper_bounds"
is not valid JSON because it contains // comments and missing punctuation for a
copy/paste-ready object; either change the fenced block from ```json to ```jsonc
to allow comments, or remove the inline comments and ensure the snippet is valid
JSON (add any needed commas/braces so "lower_bounds": [...] and "upper_bounds":
[...] appear as properly comma-separated properties in an object). Update the
code fence and/or remove comments accordingly so the block can be pasted as
valid JSON.
- Around line 122-129: The fenced code block that starts with "Matrix:" and
contains "offsets:", "indices:", and "values:" is missing a language tag; update
the opening triple-backtick for that block from ``` to a tagged form like
```text (or ```json/```yaml if more appropriate) so the block satisfies MD040
and ensures proper syntax highlighting for the Matrix example.

Comment on lines +139 to +147
```
Matrix: [2, 3] (row 0: 2*x0 + 3*x1)
[4, 2] (row 1: 4*x0 + 2*x1)

CSR format:
offsets: [0, 2, 4] # Row pointers
indices: [0, 1, 0, 1] # Column indices
values: [2.0, 3.0, 4.0, 2.0] # Non-zero values
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a language to the fenced block (MD040).

Proposed fix
-```
+```text
 Matrix:  [2, 3]    (row 0: 2*x0 + 3*x1)
          [4, 2]    (row 1: 4*x0 + 2*x1)
@@
   values:  [2.0, 3.0, 4.0, 2.0] # Non-zero values

</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **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.

```suggestion

🤖 Prompt for AI Agents
In @.github/skills/cuopt-lp-milp/resources/server_examples.md around lines 139 -
147, The fenced code block containing the CSR example (the block starting with
"Matrix:  [2, 3]" and the closing triple backticks) is missing a language tag
and triggers MD040; update the opening fence from "```" to "```text" (and keep
the closing fence) so the block is explicitly marked as text, ensuring the CSR
example (offsets/indices/values) is rendered correctly.

Comment on lines +122 to +129
```
Matrix: [2, 3] row 0
[4, 2] row 1

offsets: [0, 2, 4] # row pointers
indices: [0, 1, 0, 1] # column indices
values: [2, 3, 4, 2] # values
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a language to the fenced block (MD040).

Proposed fix
-```
+```text
 Matrix:  [2, 3]    row 0
          [4, 2]    row 1
@@
 values:  [2, 3, 4, 2]    # values

</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.20.0)</summary>

[warning] 122-122: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In @.github/skills/cuopt-server/resources/lp_milp_examples.md around lines 122 -
129, The fenced code block that starts with "Matrix:" and contains "offsets:",
"indices:", and "values:" is missing a language tag; update the opening
triple-backtick for that block from to a tagged form liketext (or
json/yaml if more appropriate) so the block satisfies MD040 and ensures
proper syntax highlighting for the Matrix example.


</details>

<!-- fingerprinting:phantom:triton:eagle -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +133 to +136
```json
"lower_bounds": ["ninf", "ninf"] // negative infinity
"upper_bounds": ["inf", 100.0] // positive infinity
```
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Make the JSON snippet valid for copy/paste.

The block is labeled json but contains // comments. Consider switching to jsonc or removing comments.

Proposed fix (jsonc)
-```json
+```jsonc
 "lower_bounds": ["ninf", "ninf"]   // negative infinity
 "upper_bounds": ["inf", 100.0]     // positive infinity

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In @.github/skills/cuopt-server/resources/lp_milp_examples.md around lines 133 -
136, The JSON snippet under "lower_bounds" and "upper_bounds" is not valid JSON
because it contains // comments and missing punctuation for a copy/paste-ready
object; either change the fenced block from json to jsonc to allow
comments, or remove the inline comments and ensure the snippet is valid JSON
(add any needed commas/braces so "lower_bounds": [...] and "upper_bounds": [...]
appear as properly comma-separated properties in an object). Update the code
fence and/or remove comments accordingly so the block can be pasted as valid
JSON.


</details>

<!-- fingerprinting:phantom:triton:eagle -->

<!-- This is an auto-generated comment by CodeRabbit -->

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant