assignment-codeval 0.0.30__tar.gz → 0.0.32__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. assignment_codeval-0.0.32/PKG-INFO +242 -0
  2. assignment_codeval-0.0.32/README.md +221 -0
  3. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/pyproject.toml +2 -2
  4. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/ai_benchmark.py +12 -3
  5. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/convertMD2Html.py +192 -180
  6. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/create_assignment.py +18 -13
  7. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/evaluate.py +53 -59
  8. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/export_tests.py +2 -2
  9. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/file_utils.py +15 -10
  10. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/github_connect.py +63 -10
  11. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/recent_comments.py +6 -2
  12. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/submissions.py +298 -37
  13. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/test_template.html +76 -9
  14. assignment_codeval-0.0.32/src/assignment_codeval.egg-info/PKG-INFO +242 -0
  15. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval.egg-info/SOURCES.txt +1 -8
  16. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval.egg-info/requires.txt +1 -0
  17. assignment_codeval-0.0.30/PKG-INFO +0 -351
  18. assignment_codeval-0.0.30/README.md +0 -331
  19. assignment_codeval-0.0.30/src/assignment_codeval.egg-info/PKG-INFO +0 -351
  20. assignment_codeval-0.0.30/tests/test_check_grading.py +0 -68
  21. assignment_codeval-0.0.30/tests/test_codeval.py +0 -107
  22. assignment_codeval-0.0.30/tests/test_create_assignment.py +0 -481
  23. assignment_codeval-0.0.30/tests/test_evaluate_submissions.py +0 -312
  24. assignment_codeval-0.0.30/tests/test_export_tests.py +0 -172
  25. assignment_codeval-0.0.30/tests/test_function_detection.py +0 -411
  26. assignment_codeval-0.0.30/tests/test_install_assignment.py +0 -183
  27. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/setup.cfg +0 -0
  28. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/__init__.py +0 -0
  29. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/canvas_utils.py +0 -0
  30. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/check_grading.py +0 -0
  31. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/cli.py +0 -0
  32. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/commons.py +0 -0
  33. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval/install_assignment.py +0 -0
  34. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval.egg-info/dependency_links.txt +0 -0
  35. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval.egg-info/entry_points.txt +0 -0
  36. {assignment_codeval-0.0.30 → assignment_codeval-0.0.32}/src/assignment_codeval.egg-info/top_level.txt +0 -0
@@ -0,0 +1,242 @@
1
+ Metadata-Version: 2.4
2
+ Name: assignment-codeval
3
+ Version: 0.0.32
4
+ Summary: CodEval for evaluating programming assignments
5
+ Requires-Python: >=3.12
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: canvasapi==3.3.0
8
+ Requires-Dist: click==8.2.1
9
+ Requires-Dist: configparser==5.2.0
10
+ Requires-Dist: pytz==2021.3
11
+ Requires-Dist: requests>=2.28.0
12
+ Requires-Dist: pymongo==4.3.3
13
+ Requires-Dist: markdown==3.4.1
14
+ Requires-Dist: mdx-better-lists>=1.0.0
15
+ Requires-Dist: anthropic>=0.39.0
16
+ Requires-Dist: openai>=1.0.0
17
+ Requires-Dist: google-generativeai>=0.8.0
18
+ Provides-Extra: test
19
+ Requires-Dist: pytest>=7.0; extra == "test"
20
+ Requires-Dist: pytest-cov; extra == "test"
21
+
22
+ # CodEval
23
+
24
+ [![CI](https://github.com/SJSU-CMPE-195/group-project-team-29/actions/workflows/test.yml/badge.svg)](https://github.com/SJSU-CMPE-195/group-project-team-29/actions/workflows/test.yml)
25
+ [![codecov](https://codecov.io/gh/SJSU-CMPE-195/group-project-team-29/branch/main/graph/badge.svg)](https://codecov.io/gh/SJSU-CMPE-195/group-project-team-29)
26
+ [![PyPI](https://img.shields.io/pypi/v/assignment-codeval)](https://pypi.org/project/assignment-codeval/)
27
+
28
+ A Python utility to download student submissions to programming assignments from Canvas and GitHub and evaluate them using codeval scripts.
29
+
30
+ ## Team
31
+ - Sabira Abdolcader (sabdolc)
32
+ - Chelsie Chen (cChe1z)
33
+ - Aisha Syed (aisha-syed)
34
+ - Zarah Taufique (zarahtau)
35
+
36
+ ## Prerequisites
37
+ - Python 3.x
38
+ - Docker (for running evaluations in containers)
39
+ - A Canvas account with API access
40
+ - A GitHub account (for GitHub-based assignments)
41
+ - Optional AI provider packages: `anthropic`, `openai`, `google-generativeai`
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ # Install locally for development
47
+ pip install -e .
48
+
49
+ # Or install from PyPI
50
+ pip install assignment-codeval
51
+
52
+ # Install with AI provider support
53
+ pip install assignment-codeval[ai]
54
+ ```
55
+
56
+ ## Configuration
57
+
58
+ Create a `codeval.ini` file with your Canvas and run settings:
59
+
60
+ ```ini
61
+ [SERVER]
62
+ url=<canvas API>
63
+ token=<canvas token>
64
+ [RUN]
65
+ precommand=
66
+ command=
67
+ ```
68
+
69
+ For distributed assignments, add:
70
+ ```ini
71
+ [RUN]
72
+ dist_command=
73
+ host_ip=
74
+ [MONGO]
75
+ url=
76
+ db=
77
+ ```
78
+
79
+ For AI benchmarking, add:
80
+ ```ini
81
+ [AI]
82
+ anthropic_key=sk-ant-...
83
+ openai_key=sk-...
84
+ google_key=...
85
+ ```
86
+
87
+ AI keys can also be set via environment variables: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GOOGLE_API_KEY`.
88
+
89
+ Refer to a sample config file [here](samples/codeval.ini)
90
+
91
+ ## Running the Application
92
+
93
+ ```bash
94
+ # List all available commands
95
+ assignment-codeval --help
96
+
97
+ # Download submissions from Canvas/GitHub
98
+ assignment-codeval download-submissions <course_name>
99
+
100
+ # Evaluate downloaded submissions
101
+ assignment-codeval evaluate-submissions <course_name>
102
+
103
+ # Upload grading comments back to Canvas
104
+ assignment-codeval upload-submission-comments <course_name>
105
+
106
+ # Create an assignment on Canvas
107
+ assignment-codeval create-assignment <course_name> <specification_file>
108
+
109
+ # Check which submissions are missing grading
110
+ assignment-codeval check-grading <course_name>
111
+
112
+ # List recent codeval comments
113
+ assignment-codeval recent-comments <course_name>
114
+
115
+ # Test an assignment with AI models
116
+ assignment-codeval test-with-ai <codeval_file> [OPTIONS]
117
+ ```
118
+
119
+ ## Usage
120
+
121
+ ### Codeval Specification Files
122
+
123
+ Codeval files (`.codeval` extension) define how to build, run, and test student submissions.
124
+
125
+ #### Assignment Description Tags
126
+ - `ASSIGNMENT START <Assignment_name>` — begins the Canvas assignment description in markdown (`CRT_HW START` also accepted, but deprecated)
127
+ - `ASSIGNMENT END` — ends the assignment description (`CRT_HW END` also accepted, but deprecated)
128
+
129
+ #### Specification Tags
130
+
131
+ | Tag | Meaning | Function |
132
+ |---|---|---|
133
+ | C | Compile Code | Specifies the command to compile the submission code |
134
+ | CTO | Compile Timeout | Timeout in seconds for the whole evaluation (compile **and** all test cases) to run |
135
+ | T/HT | Test Case | Command to run to test the submission (HT = hidden test) |
136
+ | I/IB/IF | Supply Input | Input for a test case. I adds a newline, IB does not, IF reads from a file |
137
+ | O/OB/OF | Check Output | Expected output. O adds a newline, OB does not, OF reads from a file |
138
+ | E/EB | Check Error | Expected error output. E adds a newline, EB does not |
139
+ | TO | Timeout | Time limit in seconds for a test case (default: 10) |
140
+ | X | Exit Code | Expected exit code for a test case (not checked unless X is specified) |
141
+ | TEMP | Temp File | Registers a file to be deleted before and after the next test run |
142
+ | CF | Check Function | Checks that a function is used in the submission |
143
+ | NCF | Check Not Function | Checks that a function is **not** used |
144
+ | CMD/TCMD | Run Command | Runs a command. TCMD fails evaluation if the command errors |
145
+ | PRINT | Print Label | Prints a label/message to stdout |
146
+ | CMP | Compare | Compares two files |
147
+ | Z | Download Zip | Zip files to download from Canvas for test cases |
148
+
149
+ #### Assignment Description Macros
150
+
151
+ | Macro | Replacement |
152
+ |---|---|
153
+ | `DISCSN_URL` | URL of the discussion created for the assignment |
154
+ | `EXMPLS <n>` | First `n` non-hidden test cases formatted for display |
155
+ | `FILE[file_name]` | Link to the specified file in the Codeval folder |
156
+ | `COMPILE` | Compile command from the `C` tag |
157
+ | `GITHUB_DIRECTORY` | GitHub directory for submission |
158
+
159
+ #### Example Specification File
160
+
161
+ ```
162
+ ASSIGNMENT START Hello World
163
+ # Hello World
164
+
165
+ ## Problem Statement
166
+ Write a C program that reads a name from stdin and prints `Hello, <name>!`
167
+
168
+ ## Submission
169
+ Submit your code to GITHUB_DIRECTORY
170
+
171
+ ## Sample Examples
172
+ EXMPLS 2
173
+
174
+ ## Discussion
175
+ DISCSN_URL
176
+
177
+ ASSIGNMENT END
178
+
179
+ # Compile the submission
180
+ C gcc -o hello hello.c
181
+
182
+ # Test case 1: greet "World"
183
+ T ./hello
184
+ I World
185
+ O Hello, World!
186
+
187
+ # Test case 2: greet "Alice"
188
+ T ./hello
189
+ I Alice
190
+ O Hello, Alice!
191
+ ```
192
+
193
+ ### AI Benchmarking
194
+
195
+ Test assignments against multiple AI models:
196
+
197
+ ```bash
198
+ # Test with all Anthropic models
199
+ assignment-codeval test-with-ai my_assignment.codeval -p anthropic
200
+
201
+ # Test with a specific model, 3 attempts
202
+ assignment-codeval test-with-ai my_assignment.codeval -m "Claude Sonnet 4" -n 3
203
+ ```
204
+
205
+ | Option | Description |
206
+ |--------|-------------|
207
+ | `-o, --output-dir` | Directory to store solutions and results (default: `ai_test_results`) |
208
+ | `-n, --attempts` | Number of attempts per model (default: 1) |
209
+ | `-m, --models` | Specific models to test (repeatable) |
210
+ | `-p, --providers` | Filter by provider: `anthropic`, `openai`, `google` |
211
+
212
+ ## Project Structure
213
+
214
+ ```
215
+ src/assignment_codeval/
216
+ ├── cli.py # Click CLI entry point, registers all subcommands
217
+ ├── submissions.py # Download/upload submissions, list assignments
218
+ ├── evaluate.py # Run evaluation on submissions (run-evaluation)
219
+ ├── create_assignment.py # Create assignments on Canvas
220
+ ├── github_connect.py # GitHub repository setup and integration
221
+ ├── canvas_utils.py # Canvas API utilities
222
+ ├── ai_benchmark.py # AI model testing (test-with-ai)
223
+ ├── install_assignment.py # Install codeval files to local/remote destinations
224
+ ├── recent_comments.py # List recent codeval comments on Canvas
225
+ ├── check_grading.py # Check which submissions are missing grading
226
+ ├── export_tests.py # Export test cases from codeval files
227
+ ├── convertMD2Html.py # Markdown to HTML conversion
228
+ ├── commons.py # Shared utilities
229
+ ├── file_utils.py # File handling utilities
230
+ └── test_template.html # HTML template for test results
231
+
232
+ tests/
233
+ ├── unit/ # Unit tests and sample programs/codeval fixtures
234
+ ├── integration/
235
+ │ └── test_codeval.py # Integration test suite
236
+ └── e2e/
237
+ └── test_e2e.py # End-to-end tests
238
+
239
+ samples/
240
+ ├── codeval.ini # Sample configuration file
241
+ └── assignment-name.codeval # Sample specification file
242
+ ```
@@ -0,0 +1,221 @@
1
+ # CodEval
2
+
3
+ [![CI](https://github.com/SJSU-CMPE-195/group-project-team-29/actions/workflows/test.yml/badge.svg)](https://github.com/SJSU-CMPE-195/group-project-team-29/actions/workflows/test.yml)
4
+ [![codecov](https://codecov.io/gh/SJSU-CMPE-195/group-project-team-29/branch/main/graph/badge.svg)](https://codecov.io/gh/SJSU-CMPE-195/group-project-team-29)
5
+ [![PyPI](https://img.shields.io/pypi/v/assignment-codeval)](https://pypi.org/project/assignment-codeval/)
6
+
7
+ A Python utility to download student submissions to programming assignments from Canvas and GitHub and evaluate them using codeval scripts.
8
+
9
+ ## Team
10
+ - Sabira Abdolcader (sabdolc)
11
+ - Chelsie Chen (cChe1z)
12
+ - Aisha Syed (aisha-syed)
13
+ - Zarah Taufique (zarahtau)
14
+
15
+ ## Prerequisites
16
+ - Python 3.x
17
+ - Docker (for running evaluations in containers)
18
+ - A Canvas account with API access
19
+ - A GitHub account (for GitHub-based assignments)
20
+ - Optional AI provider packages: `anthropic`, `openai`, `google-generativeai`
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ # Install locally for development
26
+ pip install -e .
27
+
28
+ # Or install from PyPI
29
+ pip install assignment-codeval
30
+
31
+ # Install with AI provider support
32
+ pip install assignment-codeval[ai]
33
+ ```
34
+
35
+ ## Configuration
36
+
37
+ Create a `codeval.ini` file with your Canvas and run settings:
38
+
39
+ ```ini
40
+ [SERVER]
41
+ url=<canvas API>
42
+ token=<canvas token>
43
+ [RUN]
44
+ precommand=
45
+ command=
46
+ ```
47
+
48
+ For distributed assignments, add:
49
+ ```ini
50
+ [RUN]
51
+ dist_command=
52
+ host_ip=
53
+ [MONGO]
54
+ url=
55
+ db=
56
+ ```
57
+
58
+ For AI benchmarking, add:
59
+ ```ini
60
+ [AI]
61
+ anthropic_key=sk-ant-...
62
+ openai_key=sk-...
63
+ google_key=...
64
+ ```
65
+
66
+ AI keys can also be set via environment variables: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GOOGLE_API_KEY`.
67
+
68
+ Refer to a sample config file [here](samples/codeval.ini)
69
+
70
+ ## Running the Application
71
+
72
+ ```bash
73
+ # List all available commands
74
+ assignment-codeval --help
75
+
76
+ # Download submissions from Canvas/GitHub
77
+ assignment-codeval download-submissions <course_name>
78
+
79
+ # Evaluate downloaded submissions
80
+ assignment-codeval evaluate-submissions <course_name>
81
+
82
+ # Upload grading comments back to Canvas
83
+ assignment-codeval upload-submission-comments <course_name>
84
+
85
+ # Create an assignment on Canvas
86
+ assignment-codeval create-assignment <course_name> <specification_file>
87
+
88
+ # Check which submissions are missing grading
89
+ assignment-codeval check-grading <course_name>
90
+
91
+ # List recent codeval comments
92
+ assignment-codeval recent-comments <course_name>
93
+
94
+ # Test an assignment with AI models
95
+ assignment-codeval test-with-ai <codeval_file> [OPTIONS]
96
+ ```
97
+
98
+ ## Usage
99
+
100
+ ### Codeval Specification Files
101
+
102
+ Codeval files (`.codeval` extension) define how to build, run, and test student submissions.
103
+
104
+ #### Assignment Description Tags
105
+ - `ASSIGNMENT START <Assignment_name>` — begins the Canvas assignment description in markdown (`CRT_HW START` also accepted, but deprecated)
106
+ - `ASSIGNMENT END` — ends the assignment description (`CRT_HW END` also accepted, but deprecated)
107
+
108
+ #### Specification Tags
109
+
110
+ | Tag | Meaning | Function |
111
+ |---|---|---|
112
+ | C | Compile Code | Specifies the command to compile the submission code |
113
+ | CTO | Compile Timeout | Timeout in seconds for the whole evaluation (compile **and** all test cases) to run |
114
+ | T/HT | Test Case | Command to run to test the submission (HT = hidden test) |
115
+ | I/IB/IF | Supply Input | Input for a test case. I adds a newline, IB does not, IF reads from a file |
116
+ | O/OB/OF | Check Output | Expected output. O adds a newline, OB does not, OF reads from a file |
117
+ | E/EB | Check Error | Expected error output. E adds a newline, EB does not |
118
+ | TO | Timeout | Time limit in seconds for a test case (default: 10) |
119
+ | X | Exit Code | Expected exit code for a test case (not checked unless X is specified) |
120
+ | TEMP | Temp File | Registers a file to be deleted before and after the next test run |
121
+ | CF | Check Function | Checks that a function is used in the submission |
122
+ | NCF | Check Not Function | Checks that a function is **not** used |
123
+ | CMD/TCMD | Run Command | Runs a command. TCMD fails evaluation if the command errors |
124
+ | PRINT | Print Label | Prints a label/message to stdout |
125
+ | CMP | Compare | Compares two files |
126
+ | Z | Download Zip | Zip files to download from Canvas for test cases |
127
+
128
+ #### Assignment Description Macros
129
+
130
+ | Macro | Replacement |
131
+ |---|---|
132
+ | `DISCSN_URL` | URL of the discussion created for the assignment |
133
+ | `EXMPLS <n>` | First `n` non-hidden test cases formatted for display |
134
+ | `FILE[file_name]` | Link to the specified file in the Codeval folder |
135
+ | `COMPILE` | Compile command from the `C` tag |
136
+ | `GITHUB_DIRECTORY` | GitHub directory for submission |
137
+
138
+ #### Example Specification File
139
+
140
+ ```
141
+ ASSIGNMENT START Hello World
142
+ # Hello World
143
+
144
+ ## Problem Statement
145
+ Write a C program that reads a name from stdin and prints `Hello, <name>!`
146
+
147
+ ## Submission
148
+ Submit your code to GITHUB_DIRECTORY
149
+
150
+ ## Sample Examples
151
+ EXMPLS 2
152
+
153
+ ## Discussion
154
+ DISCSN_URL
155
+
156
+ ASSIGNMENT END
157
+
158
+ # Compile the submission
159
+ C gcc -o hello hello.c
160
+
161
+ # Test case 1: greet "World"
162
+ T ./hello
163
+ I World
164
+ O Hello, World!
165
+
166
+ # Test case 2: greet "Alice"
167
+ T ./hello
168
+ I Alice
169
+ O Hello, Alice!
170
+ ```
171
+
172
+ ### AI Benchmarking
173
+
174
+ Test assignments against multiple AI models:
175
+
176
+ ```bash
177
+ # Test with all Anthropic models
178
+ assignment-codeval test-with-ai my_assignment.codeval -p anthropic
179
+
180
+ # Test with a specific model, 3 attempts
181
+ assignment-codeval test-with-ai my_assignment.codeval -m "Claude Sonnet 4" -n 3
182
+ ```
183
+
184
+ | Option | Description |
185
+ |--------|-------------|
186
+ | `-o, --output-dir` | Directory to store solutions and results (default: `ai_test_results`) |
187
+ | `-n, --attempts` | Number of attempts per model (default: 1) |
188
+ | `-m, --models` | Specific models to test (repeatable) |
189
+ | `-p, --providers` | Filter by provider: `anthropic`, `openai`, `google` |
190
+
191
+ ## Project Structure
192
+
193
+ ```
194
+ src/assignment_codeval/
195
+ ├── cli.py # Click CLI entry point, registers all subcommands
196
+ ├── submissions.py # Download/upload submissions, list assignments
197
+ ├── evaluate.py # Run evaluation on submissions (run-evaluation)
198
+ ├── create_assignment.py # Create assignments on Canvas
199
+ ├── github_connect.py # GitHub repository setup and integration
200
+ ├── canvas_utils.py # Canvas API utilities
201
+ ├── ai_benchmark.py # AI model testing (test-with-ai)
202
+ ├── install_assignment.py # Install codeval files to local/remote destinations
203
+ ├── recent_comments.py # List recent codeval comments on Canvas
204
+ ├── check_grading.py # Check which submissions are missing grading
205
+ ├── export_tests.py # Export test cases from codeval files
206
+ ├── convertMD2Html.py # Markdown to HTML conversion
207
+ ├── commons.py # Shared utilities
208
+ ├── file_utils.py # File handling utilities
209
+ └── test_template.html # HTML template for test results
210
+
211
+ tests/
212
+ ├── unit/ # Unit tests and sample programs/codeval fixtures
213
+ ├── integration/
214
+ │ └── test_codeval.py # Integration test suite
215
+ └── e2e/
216
+ └── test_e2e.py # End-to-end tests
217
+
218
+ samples/
219
+ ├── codeval.ini # Sample configuration file
220
+ └── assignment-name.codeval # Sample specification file
221
+ ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "assignment-codeval"
7
- version = "0.0.30"
7
+ version = "0.0.32"
8
8
  description = "CodEval for evaluating programming assignments"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -23,7 +23,7 @@ dependencies = [
23
23
  ]
24
24
 
25
25
  [project.optional-dependencies]
26
- test = ["pytest>=7.0"]
26
+ test = ["pytest>=7.0", "pytest-cov"]
27
27
 
28
28
  [project.scripts]
29
29
  assignment-codeval = "assignment_codeval.cli:cli"
@@ -75,8 +75,10 @@ def extract_assignment_from_codeval(codeval_path: str) -> tuple[str, str, str]:
75
75
  with open(codeval_path, "r", encoding="utf-8") as f:
76
76
  content = f.read()
77
77
 
78
- # Extract content between CRT_HW START and CRT_HW END
79
- match = re.search(r"CRT_HW START \S+\n(.*?)CRT_HW END", content, re.DOTALL)
78
+ # Extract content between ASSIGNMENT START / CRT_HW START and ASSIGNMENT END / CRT_HW END.
79
+ # The title after the marker may contain spaces (e.g. "CRT_HW START Place Boats")
80
+ # or be absent entirely, so match the rest of the marker line, not a single token.
81
+ match = re.search(r"(?:ASSIGNMENT START|CRT_HW START)[^\n]*\n(.*?)(?:ASSIGNMENT END|CRT_HW END)", content, re.DOTALL)
80
82
  if match:
81
83
  description = match.group(1).strip()
82
84
  else:
@@ -223,10 +225,17 @@ def call_openai(model_id: str, prompt: str, api_key: str) -> Optional[str]:
223
225
  try:
224
226
  client = openai.OpenAI(api_key=api_key)
225
227
 
228
+ # Reasoning models (o1/o3/o4 families, gpt-5) reject `max_tokens` and
229
+ # require `max_completion_tokens` instead.
230
+ if model_id.startswith(("o1", "o3", "o4", "gpt-5")):
231
+ token_kwargs = {"max_completion_tokens": 8192}
232
+ else:
233
+ token_kwargs = {"max_tokens": 8192}
234
+
226
235
  response = client.chat.completions.create(
227
236
  model=model_id,
228
237
  messages=[{"role": "user", "content": prompt}],
229
- max_tokens=8192,
238
+ **token_kwargs,
230
239
  )
231
240
 
232
241
  return response.choices[0].message.content