Skip to content

Refactoring agentic skill files based on roles and modules#818

Open
rgsl888prabhu wants to merge 14 commits intoNVIDIA:mainfrom
rgsl888prabhu:add_agentic_skill
Open

Refactoring agentic skill files based on roles and modules#818
rgsl888prabhu wants to merge 14 commits intoNVIDIA:mainfrom
rgsl888prabhu:add_agentic_skill

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 a Skills Directory with Quick Start; published comprehensive skill guides (installation, debugging, developer, user rules) and domain guides (LP/MILP, QP, routing, server) with runnable examples, verification & diagnostic snippets, and escalation guidance.
  • Chores
    • Refined code ownership mappings and added infra/packaging ownership entries.

@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

Adds an explicit cuOpt AI Agent entry point and a structured Skills Directory; removes legacy skill manifest shims; introduces many new SKILL.md guides and resources under .github/skills/; updates AGENTS.md and .github/CODEOWNERS. All changes are documentation-only.

Changes

Cohort / File(s) Summary
Entry Point & Index
AGENTS.md, .github/AGENTS.md, .github/skills/README.md
Declare cuOpt AI Agent entry point, Quick Start, Skills Directory, task→skill mapping, and resource links; replace prior shim-style references with explicit paths.
Skills: LP / MILP
.github/skills/cuopt-lp-milp/SKILL.md, .github/skills/cuopt-lp-milp/resources/*
New LP/MILP skill and examples (Python, C API, CLI, REST): modeling patterns, CSR format, solver settings, status handling, troubleshooting.
Skills: QP
.github/skills/cuopt-qp/SKILL.md, .github/skills/cuopt-qp/resources/python_examples.md
Add QP skill with convexity/minimize guidance and Python examples (portfolio, least squares, constrained QP).
Skills: Routing
.github/skills/cuopt-routing/SKILL.md, .github/skills/cuopt-routing/resources/*
New Routing skill (TSP/VRP/PDP), constraints (time windows, capacities, service times), Python and REST examples, payload mappings, and solution-checking.
Skills: Server
.github/skills/cuopt-server/SKILL.md, .github/skills/cuopt-server/resources/*
Server deployment and REST API docs: endpoints, payload/response schemas for LP/MILP/routing, health checks, polling patterns, and terminology mapping.
Skills: Installation & Verification
.github/skills/cuopt-installation/SKILL.md, .github/skills/cuopt-installation/resources/*
Installation workflows (local/cloud/Docker), CUDA/prereq checks, multiple install methods, verification steps, and troubleshooting examples.
Skills: Developer & Debugging
.github/skills/cuopt-developer/SKILL.md, .github/skills/cuopt-debugging/SKILL.md, .github/skills/cuopt-debugging/resources/*
Developer contribution rules, build/test/DCO guidance, escalation paths, and extensive debugging diagnostics and code snippets for LP/MILP/routing/server.
Skills: User Rules & Governance
.github/skills/cuopt-user-rules/SKILL.md, .github/skills/README.md
Agent/user interaction rules, clarification prompts, verification checklists, environment checks, and resource references for safe agent behavior.
Examples & Misc. Resources
.github/skills/*/resources/*.md
Collection of runnable examples and snippets (Python, C, curl/REST) across skills demonstrating payload formats, sample problems, and response handling.
Manifest Removals
.ai/skills/cuopt.yaml, .github/.ai/skills/cuopt.yaml
Removed legacy machine-readable skill manifest shims.
Ownership
.github/CODEOWNERS
Updated CODEOWNERS: added agent/infra/packaging ownership entries and expanded ownership for AGENTS/.ai/.github/skills paths.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 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 accurately describes the main change: refactoring agentic skill files into a structured directory under .github/skills/ organized by roles and modules.
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

Important

Action Needed: IP Allowlist Update

If your organization protects your Git platform with IP whitelisting, please add the new CodeRabbit IP address to your allowlist:

  • 136.113.208.247/32 (new)
  • 34.170.211.100/32
  • 35.222.179.152/32

Reviews will stop working after February 8, 2026 if the new IP is not added to your allowlist.


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.

@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

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 -->

Copy link
Member

@jameslamb jameslamb left a comment

Choose a reason for hiding this comment

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

@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.

It looks fine to me, the changes in the .github/ directory are not too extensive, and this group of people seem like better reviewers for it than the RAPIDS build team: https://github.com/orgs/NVIDIA/teams/cuopt-infra-codeowners

I don't know anything about how CodeRabbit or other tools like that work, so cannot say anything useful about the content or structure of the files. I didn't even look at them (but will if there's something specific you want me to look at!).

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-qp/resources/python_examples.md:
- Around line 155-177: The docs currently show the expanded scalar form of x^T Q
x but lack a clear note that when users pass a matrix Q to the API they should
pass it as-is (no manual doubling of off-diagonals); update the text around the
Q example to explicitly state the API convention and behavior: state that the
user-supplied Q represents the quadratic form x^T Q x, mention that cuOpt
internally forms Q_symmetric = Q + Q^T and the solver effectively uses 0.5 * x^T
* Q_symmetric * x, and reference the relevant API entry points
(set_quadratic_objective_matrix, cuOptCreateQuadraticProblem,
cuOptCreateQuadraticRangedProblem) so readers know where this convention
applies.
🧹 Nitpick comments (1)
.github/skills/cuopt-qp/resources/python_examples.md (1)

114-123: Add a non‑optimal status branch for consistency with other examples.

This block prints results only on "Optimal" but silently does nothing otherwise, unlike the other sections. Consider adding an error/else path for clarity.

♻️ Suggested tweak
 if problem.Status.name == "Optimal":
     print(f"x = {x.getValue():.4f}")
     print(f"y = {y.getValue():.4f}")
     print(f"z = {z.getValue():.4f}")
     print(f"Objective = {problem.ObjValue:.4f}")
+else:
+    raise RuntimeError(f"Solver failed with status: {problem.Status.name}")

Comment on lines +155 to +177
## Expanding Covariance Matrix

Given covariance matrix Q and weight vector x:

```python
# Covariance matrix
Q = [
[0.04, 0.01, 0.005],
[0.01, 0.02, 0.008],
[0.005, 0.008, 0.01]
]

# Expansion: x^T * Q * x
# = Q[0,0]*x1² + Q[1,1]*x2² + Q[2,2]*x3²
# + 2*Q[0,1]*x1*x2 + 2*Q[0,2]*x1*x3 + 2*Q[1,2]*x2*x3
#
# = 0.04*x1*x1 + 0.02*x2*x2 + 0.01*x3*x3
# + 0.02*x1*x2 + 0.01*x1*x3 + 0.016*x2*x3

objective = (
Q[0][0]*x1*x1 + Q[1][1]*x2*x2 + Q[2][2]*x3*x3 +
2*Q[0][1]*x1*x2 + 2*Q[0][2]*x1*x3 + 2*Q[1][2]*x2*x3
)
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 matrix‑Q vs expanded form to avoid off‑diagonal double‑counting.

The expansion is correct for scalar objective expressions, but readers using matrix‑Q APIs may mistakenly double off‑diagonal terms. Add an explicit note that when supplying Q directly, pass it as‑is (no doubling), because cuOpt interprets the objective as (x^T Q x).

📄 Suggested doc tweak
 ## Expanding Covariance Matrix

 Given covariance matrix Q and weight vector x:

+> Note: If you pass Q via the matrix QP API, provide Q as-is (do not pre-double off-diagonals).
+> The solver interprets the quadratic objective as x^T Q x.
+
 ```python

Based on learnings: In cuOPT's quadratic programming API, when a user provides a quadratic objective matrix Q via set_quadratic_objective_matrix or the C API functions cuOptCreateQuadraticProblem/cuOptCreateQuadraticRangedProblem, the API internally computes Q_symmetric = Q + Q^T and the barrier solver uses 0.5 * x^T * Q_symmetric * x. From the user's perspective, the convention is x^T Q x.

🤖 Prompt for AI Agents
In @.github/skills/cuopt-qp/resources/python_examples.md around lines 155 - 177,
The docs currently show the expanded scalar form of x^T Q x but lack a clear
note that when users pass a matrix Q to the API they should pass it as-is (no
manual doubling of off-diagonals); update the text around the Q example to
explicitly state the API convention and behavior: state that the user-supplied Q
represents the quadratic form x^T Q x, mention that cuOpt internally forms
Q_symmetric = Q + Q^T and the solver effectively uses 0.5 * x^T * Q_symmetric *
x, and reference the relevant API entry points (set_quadratic_objective_matrix,
cuOptCreateQuadraticProblem, cuOptCreateQuadraticRangedProblem) so readers know
where this convention applies.

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/AGENTS.md:
- Around line 7-25: Update all relative skill paths in the AGENTS.md content to
be explicit by prefixing them with .github/skills/ (e.g., change occurrences of
skills/cuopt-user-rules/, skills/cuopt-developer/, skills/cuopt-routing/,
skills/cuopt-lp-milp/, skills/cuopt-qp/, skills/cuopt-debugging/,
skills/cuopt-installation/, skills/cuopt-server/ and the reference
skills/README.md to .github/skills/cuopt-user-rules/,
.github/skills/cuopt-developer/, .github/skills/cuopt-routing/,
.github/skills/cuopt-lp-milp/, .github/skills/cuopt-qp/,
.github/skills/cuopt-debugging/, .github/skills/cuopt-installation/,
.github/skills/cuopt-server/ and .github/skills/README.md respectively so every
path is unambiguous when viewed from the repo root or GitHub UI.

Comment on lines +7 to +25
| Task | Read These Skills |
|------|-------------------|
| **Using cuOpt** (routing, LP, etc.) | `skills/cuopt-user-rules/` → then domain skill |
| **Developing cuOpt** (contributing) | `skills/cuopt-developer/` |

- **Primary**: `.github/.ai/skills/cuopt.yaml`
- **Root shim (compat)**: `.ai/skills/cuopt.yaml`
## Skills Directory

### Canonical contribution guide
See `skills/README.md` for the full index.

- `CONTRIBUTING.md`
### User Skills (read cuopt-user-rules first)
- `skills/cuopt-routing/` — VRP, TSP, PDP
- `skills/cuopt-lp-milp/` — Linear programming, integer variables
- `skills/cuopt-qp/` — Quadratic programming
- `skills/cuopt-debugging/` — Troubleshooting
- `skills/cuopt-installation/` — Setup & requirements
- `skills/cuopt-server/` — REST API deployment

### Developer Skill (has its own rules)
- `skills/cuopt-developer/` — Contributing code
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:

# Check if .github/AGENTS.md exists and read its content
if [ -f ".github/AGENTS.md" ]; then
  echo "=== .github/AGENTS.md exists ==="
  cat -n ".github/AGENTS.md" | head -30
else
  echo ".github/AGENTS.md not found"
fi

Repository: NVIDIA/cuopt

Length of output: 1282


🏁 Script executed:

# Check for skills directories in the repository
echo "=== Checking for skills directories ==="
find . -type d -name "skills" 2>/dev/null | head -20

Repository: NVIDIA/cuopt

Length of output: 112


🏁 Script executed:

# List contents of .github/ to understand structure
echo "=== Contents of .github/ ==="
if [ -d ".github" ]; then
  ls -la ".github/" | head -30
fi

Repository: NVIDIA/cuopt

Length of output: 928


🏁 Script executed:

# Check if there are skills directories at repo root or under .github/
echo "=== Checking repo structure ==="
git ls-files | grep -E "^\.?/?skills/" | head -20

Repository: NVIDIA/cuopt

Length of output: 87


🏁 Script executed:

# List the contents of .github/skills/
echo "=== Contents of .github/skills/ ==="
if [ -d ".github/skills" ]; then
  ls -la ".github/skills/" | head -20
else
  echo ".github/skills/ not found"
fi

Repository: NVIDIA/cuopt

Length of output: 782


🏁 Script executed:

# Check if skills exist at repo root level
echo "=== Checking for skills at repo root ==="
if [ -d "./skills" ]; then
  ls -la "./skills/" | head -20
else
  echo "./skills/ not found at repo root"
fi

Repository: NVIDIA/cuopt

Length of output: 129


🏁 Script executed:

# Get a better listing of what's actually tracked or present
echo "=== All directories under .github/ ==="
find .github -maxdepth 2 -type d | sort

Repository: NVIDIA/cuopt

Length of output: 396


Clarify skill paths as .github/skills/... to avoid ambiguity.

The paths in this document are currently referenced as skills/..., but all these directories actually exist under .github/skills/. While these relative references technically resolve correctly from the document's location, they can be ambiguous when viewed from the repo root or on GitHub. Use explicit .github/skills/... paths throughout to make the references unambiguous.

Affected locations

Quick Start table (lines 9–10), Skills Directory heading (line 14), and all skill paths in the list (lines 17–22, 25).

🤖 Prompt for AI Agents
In @.github/AGENTS.md around lines 7 - 25, Update all relative skill paths in
the AGENTS.md content to be explicit by prefixing them with .github/skills/
(e.g., change occurrences of skills/cuopt-user-rules/, skills/cuopt-developer/,
skills/cuopt-routing/, skills/cuopt-lp-milp/, skills/cuopt-qp/,
skills/cuopt-debugging/, skills/cuopt-installation/, skills/cuopt-server/ and
the reference skills/README.md to .github/skills/cuopt-user-rules/,
.github/skills/cuopt-developer/, .github/skills/cuopt-routing/,
.github/skills/cuopt-lp-milp/, .github/skills/cuopt-qp/,
.github/skills/cuopt-debugging/, .github/skills/cuopt-installation/,
.github/skills/cuopt-server/ and .github/skills/README.md respectively so every
path is unambiguous when viewed from the repo root or GitHub UI.

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.

2 participants