sysmlv2copilot 0.2.0__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.
- sysmlv2copilot-0.2.0/CHANGELOG.md +8 -0
- sysmlv2copilot-0.2.0/LICENSE +21 -0
- sysmlv2copilot-0.2.0/MANIFEST.in +17 -0
- sysmlv2copilot-0.2.0/PKG-INFO +432 -0
- sysmlv2copilot-0.2.0/README.md +391 -0
- sysmlv2copilot-0.2.0/examples/README.md +4 -0
- sysmlv2copilot-0.2.0/examples/client_sdk_basic.py +13 -0
- sysmlv2copilot-0.2.0/examples/repair_basic.py +18 -0
- sysmlv2copilot-0.2.0/examples/sdk_smoke_test.py +25 -0
- sysmlv2copilot-0.2.0/pyproject.toml +67 -0
- sysmlv2copilot-0.2.0/setup.cfg +4 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot/__init__.py +49 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot/__main__.py +5 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot/cli.py +121 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot/client.py +197 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot/exceptions.py +40 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot/types.py +112 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot.egg-info/PKG-INFO +432 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot.egg-info/SOURCES.txt +21 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot.egg-info/dependency_links.txt +1 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot.egg-info/entry_points.txt +2 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot.egg-info/requires.txt +22 -0
- sysmlv2copilot-0.2.0/sysmlv2copilot.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
- split the public package into a client-only SDK and CLI boundary
|
|
6
|
+
- added PyPI-ready metadata, MIT licensing, and release workflow docs
|
|
7
|
+
- added a repair workflow across the API, SDK, and CLI
|
|
8
|
+
- added packaging, CI, and smoke-test improvements
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Chance LaVoie
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
recursive-include sysmlv2copilot *.py
|
|
4
|
+
recursive-include examples *.py *.md *.txt
|
|
5
|
+
include CHANGELOG.md
|
|
6
|
+
prune app
|
|
7
|
+
prune alembic
|
|
8
|
+
prune context
|
|
9
|
+
prune docker
|
|
10
|
+
prune docs
|
|
11
|
+
prune infra
|
|
12
|
+
prune scripts
|
|
13
|
+
prune sysmlv2copilot_admin
|
|
14
|
+
prune tests
|
|
15
|
+
exclude alembic.ini
|
|
16
|
+
exclude Dockerfile
|
|
17
|
+
exclude prompt.txt
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sysmlv2copilot
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Python client SDK and CLI for the SysML refinement API
|
|
5
|
+
Author: Chance LaVoie
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cmuchancel/sysmlv2copilot
|
|
8
|
+
Project-URL: Repository, https://github.com/cmuchancel/sysmlv2copilot
|
|
9
|
+
Project-URL: Issues, https://github.com/cmuchancel/sysmlv2copilot/issues
|
|
10
|
+
Project-URL: Documentation, https://github.com/cmuchancel/sysmlv2copilot/tree/main/docs
|
|
11
|
+
Keywords: sysml,sysmlv2,api-client,sdk,llm
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: httpx<1,>=0.28
|
|
22
|
+
Requires-Dist: pydantic<3,>=2.7
|
|
23
|
+
Provides-Extra: server
|
|
24
|
+
Requires-Dist: alembic<2,>=1.14; extra == "server"
|
|
25
|
+
Requires-Dist: anthropic<1,>=0.84; extra == "server"
|
|
26
|
+
Requires-Dist: fastapi<1,>=0.116; extra == "server"
|
|
27
|
+
Requires-Dist: openai<2,>=1.0; extra == "server"
|
|
28
|
+
Requires-Dist: psycopg[binary]<4,>=3.2; extra == "server"
|
|
29
|
+
Requires-Dist: pydantic-settings<3,>=2.7; extra == "server"
|
|
30
|
+
Requires-Dist: python-dotenv<2,>=1.0; extra == "server"
|
|
31
|
+
Requires-Dist: sqlalchemy<3,>=2.0; extra == "server"
|
|
32
|
+
Requires-Dist: uvicorn<1,>=0.35; extra == "server"
|
|
33
|
+
Provides-Extra: admin
|
|
34
|
+
Requires-Dist: pandas<3,>=2.2; extra == "admin"
|
|
35
|
+
Requires-Dist: streamlit<2,>=1.45; extra == "admin"
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: build<2,>=1.2; extra == "dev"
|
|
38
|
+
Requires-Dist: pytest<9,>=8.3; extra == "dev"
|
|
39
|
+
Requires-Dist: twine<7,>=5; extra == "dev"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# SysML Refinement API
|
|
43
|
+
|
|
44
|
+
This repository contains two distinct products:
|
|
45
|
+
- a public Python SDK and CLI, published as `sysmlv2copilot`
|
|
46
|
+
- an internal server/admin implementation that stays hosted and black-box
|
|
47
|
+
|
|
48
|
+
## Repo Split
|
|
49
|
+
|
|
50
|
+
The repository is now organized into two explicit halves:
|
|
51
|
+
- `api/`: index for the service/SDK/admin side
|
|
52
|
+
- `finetune/`: local dataset generation, repair corpus, and fine-tuning assets
|
|
53
|
+
|
|
54
|
+
To avoid breaking runtime imports in one large move, the API code still currently lives in the root-owned paths such as `app/`, `alembic/`, `sysmlv2copilot/`, `sysmlv2copilot_admin/`, and the main `scripts/` directory. The fine-tuning assets now live directly under `finetune/`.
|
|
55
|
+
|
|
56
|
+
The hosted service accepts either natural-language requirements or SysML input, runs the compiler-in-the-loop workflow, returns SysML plus structured metadata, and stores each request with a single persisted artifact bundle.
|
|
57
|
+
|
|
58
|
+
The service itself is intentionally narrow:
|
|
59
|
+
- internal-only
|
|
60
|
+
- one user, one API key
|
|
61
|
+
- plain text in, SysML text out
|
|
62
|
+
- FastAPI HTTP layer
|
|
63
|
+
- Postgres-compatible metadata storage
|
|
64
|
+
- filesystem artifact storage by default
|
|
65
|
+
- admin operations through CLI scripts, not public admin routes
|
|
66
|
+
|
|
67
|
+
## Public SDK
|
|
68
|
+
|
|
69
|
+
The public package is client-only. It does not ship the backend, migrations, deployment code, or admin console.
|
|
70
|
+
|
|
71
|
+
Install from PyPI:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
python -m pip install sysmlv2copilot
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Basic generation:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from sysmlv2copilot import SysMLCopilot
|
|
81
|
+
|
|
82
|
+
with SysMLCopilot(
|
|
83
|
+
api_key="sysml_live_...",
|
|
84
|
+
base_url="https://your-deployment.example.com",
|
|
85
|
+
) as client:
|
|
86
|
+
response = client.responses.create(
|
|
87
|
+
input="Design a compact warehouse inspection drone that can hover for 15 minutes.",
|
|
88
|
+
provider="openai",
|
|
89
|
+
)
|
|
90
|
+
print(response.id)
|
|
91
|
+
print(response.output_text)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Basic repair:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from sysmlv2copilot import SysMLCopilot
|
|
98
|
+
|
|
99
|
+
broken_sysml = """package Example {
|
|
100
|
+
public import ScalarValues::*;
|
|
101
|
+
requirement def R { text = "Missing semicolon" }
|
|
102
|
+
}
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
with SysMLCopilot(
|
|
106
|
+
api_key="sysml_live_...",
|
|
107
|
+
base_url="https://your-deployment.example.com",
|
|
108
|
+
) as client:
|
|
109
|
+
repaired = client.repairs.create(input=broken_sysml, provider="openai")
|
|
110
|
+
print(repaired.compiler_passed)
|
|
111
|
+
print(repaired.output_text)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
CLI examples:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
sysmlv2copilot --api-key sysml_live_... \
|
|
118
|
+
--base-url https://your-deployment.example.com \
|
|
119
|
+
responses create \
|
|
120
|
+
--input "Design a compact warehouse inspection drone that can hover for 15 minutes."
|
|
121
|
+
|
|
122
|
+
sysmlv2copilot --api-key sysml_live_... \
|
|
123
|
+
--base-url https://your-deployment.example.com \
|
|
124
|
+
repairs create \
|
|
125
|
+
--input-file ./broken.sysml
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
SDK details:
|
|
129
|
+
- [docs/PYTHON_SDK.md](/Users/chancelavoie/Desktop/sysmlv2copilot/docs/PYTHON_SDK.md)
|
|
130
|
+
- [docs/PYPI_RELEASE.md](/Users/chancelavoie/Desktop/sysmlv2copilot/docs/PYPI_RELEASE.md)
|
|
131
|
+
|
|
132
|
+
## What It Solves
|
|
133
|
+
|
|
134
|
+
The upstream pipeline already knows how to:
|
|
135
|
+
- build the iterative refinement prompt
|
|
136
|
+
- call the OpenAI Responses API
|
|
137
|
+
- write every iteration prompt and candidate SysML file
|
|
138
|
+
- run `syside check`
|
|
139
|
+
- capture compiler diagnostics
|
|
140
|
+
- stop on success or refinement limits
|
|
141
|
+
|
|
142
|
+
This service wraps that exact behavior in an authenticated API with request tracking and persistent artifacts so an internal team can use it immediately.
|
|
143
|
+
|
|
144
|
+
The refinement loop now supports either upstream provider:
|
|
145
|
+
- OpenAI via the Responses API
|
|
146
|
+
- Anthropic via the Messages API
|
|
147
|
+
|
|
148
|
+
The public API surface stays narrow and OpenAI-style. Provider choice is an internal runtime option exposed as an extra request field.
|
|
149
|
+
|
|
150
|
+
## Repo Layout
|
|
151
|
+
|
|
152
|
+
- `app/`: FastAPI app, auth, DB models, storage, and upstream wrapper
|
|
153
|
+
- `app/upstream/refine_sysml.py`: vendored upstream refiner used as the behavior source of truth
|
|
154
|
+
- `context/upstream/`: tight context package copied from the upstream repo
|
|
155
|
+
- `scripts/`: admin CLI for user creation, API key reset, and usage reporting
|
|
156
|
+
- `alembic/`: schema migrations
|
|
157
|
+
- `sysmlv2copilot/`: public client SDK and CLI package
|
|
158
|
+
- `sysmlv2copilot_admin/`: internal Streamlit admin console
|
|
159
|
+
- `tests/`: API, CLI, and config coverage
|
|
160
|
+
|
|
161
|
+
## Internal Repo Setup
|
|
162
|
+
|
|
163
|
+
If you are working on the hosted backend from this repo, install the internal extras:
|
|
164
|
+
|
|
165
|
+
1. Create a virtual environment and install dependencies:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
python3 -m venv .venv
|
|
169
|
+
source .venv/bin/activate
|
|
170
|
+
python -m pip install --upgrade pip
|
|
171
|
+
python -m pip install -e ".[server,admin,dev]"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
2. Create `.env`:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
cp .env.example .env
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
3. Fill in at least:
|
|
181
|
+
- one or both of `OPENAI_API_KEY` / `ANTHROPIC_API_KEY`
|
|
182
|
+
- one of `SYSIDE_VENV_PATH` or `SYSIDE_EXECUTABLE_PATH`
|
|
183
|
+
- `API_KEY_HASH_PEPPER`
|
|
184
|
+
- optionally a PostgreSQL `DATABASE_URL`
|
|
185
|
+
|
|
186
|
+
SQLite works for local development. PostgreSQL or Supabase Postgres is preferred for shared environments.
|
|
187
|
+
For PostgreSQL or Supabase, install/runtime support now includes `psycopg`.
|
|
188
|
+
|
|
189
|
+
## Migrations
|
|
190
|
+
|
|
191
|
+
Run the schema migration before starting the service:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
alembic upgrade head
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Start The Service
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
uvicorn app.main:app --reload
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The default address is `http://127.0.0.1:8000`.
|
|
204
|
+
|
|
205
|
+
## Create A User And API Key
|
|
206
|
+
|
|
207
|
+
Create a user and print the plaintext key once:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
python scripts/create_user.py --email engineer@example.com --name "Internal Engineer"
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Reset the single API key for an existing user:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
python scripts/reset_api_key.py --email engineer@example.com
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
List usage:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
python scripts/list_usage.py --email engineer@example.com --from-date 2026-03-01 --to-date 2026-03-31
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Call The API
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
curl -s http://127.0.0.1:8000/v1/responses \
|
|
229
|
+
-H "Authorization: Bearer sysml_live_..." \
|
|
230
|
+
-H "Content-Type: application/json" \
|
|
231
|
+
-d '{
|
|
232
|
+
"input": "Design a compact battery-powered inspection drone that fits in a 30 cm cube and flies for 20 minutes.",
|
|
233
|
+
"model": "refine-sysml-v1",
|
|
234
|
+
"provider": "openai",
|
|
235
|
+
"max_iters": 10,
|
|
236
|
+
"max_total_tokens": 40000,
|
|
237
|
+
"temperature": null
|
|
238
|
+
}'
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Example successful response:
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"id": "resp_20260312_161200_abcd",
|
|
246
|
+
"object": "response",
|
|
247
|
+
"status": "completed",
|
|
248
|
+
"model": "refine-sysml-v1",
|
|
249
|
+
"output_text": "package RequirementsOnly { ... }",
|
|
250
|
+
"compiler_passed": true,
|
|
251
|
+
"iterations_completed": 4,
|
|
252
|
+
"started_at": "2026-03-12T16:12:00Z",
|
|
253
|
+
"finished_at": "2026-03-12T16:12:22Z",
|
|
254
|
+
"duration_ms": 22014,
|
|
255
|
+
"request_user_id": "usr_1234",
|
|
256
|
+
"metadata": {
|
|
257
|
+
"provider": "openai",
|
|
258
|
+
"upstream_model": "gpt-5-mini",
|
|
259
|
+
"run_id": "run_20260312_161200_abcd",
|
|
260
|
+
"artifact_paths": {
|
|
261
|
+
"request_artifact": "/abs/path/request_artifact.json"
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
"error": null
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Repair request example:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
curl -s http://127.0.0.1:8000/v1/repairs \
|
|
272
|
+
-H "Authorization: Bearer sysml_live_..." \
|
|
273
|
+
-H "Content-Type: application/json" \
|
|
274
|
+
-d '{
|
|
275
|
+
"input": "package Example { requirement def R { text = \"Missing semicolon\" } }",
|
|
276
|
+
"model": "refine-sysml-v1",
|
|
277
|
+
"provider": "openai"
|
|
278
|
+
}'
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Anthropic request example:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
curl -s http://127.0.0.1:8000/v1/responses \
|
|
285
|
+
-H "Authorization: Bearer sysml_live_..." \
|
|
286
|
+
-H "Content-Type: application/json" \
|
|
287
|
+
-d '{
|
|
288
|
+
"input": "Design a compact battery-powered inspection drone that fits in a 30 cm cube and flies for 20 minutes.",
|
|
289
|
+
"model": "refine-sysml-v1",
|
|
290
|
+
"provider": "anthropic",
|
|
291
|
+
"upstream_model": "claude-sonnet-4-5-20250929"
|
|
292
|
+
}'
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Check a stored request:
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
curl -s http://127.0.0.1:8000/v1/requests/resp_20260312_161200_abcd \
|
|
299
|
+
-H "Authorization: Bearer sysml_live_..."
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Health check:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
curl -s http://127.0.0.1:8000/healthz
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Repair Workflow
|
|
309
|
+
|
|
310
|
+
The hosted API now supports a repair-oriented workflow:
|
|
311
|
+
- accept raw SysML text
|
|
312
|
+
- run SysIDE immediately
|
|
313
|
+
- if the model already passes, return it unchanged with `iterations_completed = 0`
|
|
314
|
+
- if it fails, feed the broken SysML plus real compiler diagnostics into the repair loop
|
|
315
|
+
- persist the same request tracking and single-artifact bundle used by generation requests
|
|
316
|
+
|
|
317
|
+
Repair metadata includes:
|
|
318
|
+
- `metadata.operation = "repair"`
|
|
319
|
+
- `metadata.initial_compiler_passed`
|
|
320
|
+
- `metadata.diagnostics_summary`
|
|
321
|
+
|
|
322
|
+
Design note:
|
|
323
|
+
- [docs/ITERATION_STALL_POLICY.md](/Users/chancelavoie/Desktop/sysmlv2copilot/docs/ITERATION_STALL_POLICY.md)
|
|
324
|
+
|
|
325
|
+
## Admin Frontend
|
|
326
|
+
|
|
327
|
+
Run the Streamlit admin console:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
streamlit run sysmlv2copilot_admin/app.py
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
It uses the real configured database and supports:
|
|
334
|
+
- create users and issue API keys
|
|
335
|
+
- rotate existing keys
|
|
336
|
+
- inspect per-user usage totals
|
|
337
|
+
- inspect overall usage and compiler performance
|
|
338
|
+
- browse recent request activity
|
|
339
|
+
- check live API health against a configured base URL
|
|
340
|
+
|
|
341
|
+
More detail:
|
|
342
|
+
- [docs/ADMIN_FRONTEND.md](/Users/chancelavoie/Desktop/sysmlv2copilot/docs/ADMIN_FRONTEND.md)
|
|
343
|
+
- [docs/PYPI_RELEASE.md](/Users/chancelavoie/Desktop/sysmlv2copilot/docs/PYPI_RELEASE.md)
|
|
344
|
+
|
|
345
|
+
## Artifact Storage
|
|
346
|
+
|
|
347
|
+
Artifacts are stored under `ARTIFACT_ROOT`, defaulting to `./data/artifacts`. Each request gets a run directory with a single persisted artifact:
|
|
348
|
+
- `request_artifact.json`
|
|
349
|
+
|
|
350
|
+
That JSON bundle stores:
|
|
351
|
+
- the original input text
|
|
352
|
+
- the final SysML output
|
|
353
|
+
- request statistics such as tokens, chars, duration, and iterations
|
|
354
|
+
- provider/model metadata and any terminal error
|
|
355
|
+
|
|
356
|
+
Each request registers exactly one row in the `artifacts` table. Temporary iteration files used during SysIDE checks are removed before persistence.
|
|
357
|
+
|
|
358
|
+
## Tests
|
|
359
|
+
|
|
360
|
+
Run the test suite with:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
pytest
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
The tests mock the expensive upstream generation path and cover auth, request tracking, repair flow, artifacts, CLI operations, health reporting, packaging boundaries, and config validation.
|
|
367
|
+
|
|
368
|
+
## Docker
|
|
369
|
+
|
|
370
|
+
Build:
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
docker build \
|
|
374
|
+
--build-arg SYSIDE_PIP_SPEC='syside==<your-version>' \
|
|
375
|
+
--build-arg REQUIRE_SYSIDE=1 \
|
|
376
|
+
-t sysml-refinement-api .
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Run:
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
docker run --rm -p 8000:8000 --env-file .env sysml-refinement-api
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
The container runs `alembic upgrade head` before starting `uvicorn`.
|
|
386
|
+
|
|
387
|
+
## Azure And Supabase
|
|
388
|
+
|
|
389
|
+
The repo is now prepared for:
|
|
390
|
+
- Azure Container Apps for compute
|
|
391
|
+
- Azure Container Registry for the private image
|
|
392
|
+
- Azure Files for persistent artifacts
|
|
393
|
+
- Supabase Postgres for metadata
|
|
394
|
+
|
|
395
|
+
Relevant files:
|
|
396
|
+
- [docs/AZURE_CONTAINER_APPS.md](/Users/chancelavoie/Desktop/sysmlv2copilot/docs/AZURE_CONTAINER_APPS.md)
|
|
397
|
+
- [scripts/deploy_azure_container_app.sh](/Users/chancelavoie/Desktop/sysmlv2copilot/scripts/deploy_azure_container_app.sh)
|
|
398
|
+
- [scripts/build_database_url.py](/Users/chancelavoie/Desktop/sysmlv2copilot/scripts/build_database_url.py)
|
|
399
|
+
- [scripts/render_azure_containerapp_yaml.py](/Users/chancelavoie/Desktop/sysmlv2copilot/scripts/render_azure_containerapp_yaml.py)
|
|
400
|
+
- [infra/supabase/create_service_role.sql](/Users/chancelavoie/Desktop/sysmlv2copilot/infra/supabase/create_service_role.sql)
|
|
401
|
+
|
|
402
|
+
To build a Supabase-compatible SQLAlchemy URL:
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
python scripts/build_database_url.py \
|
|
406
|
+
--host db.<project-ref>.supabase.co \
|
|
407
|
+
--port 5432 \
|
|
408
|
+
--database postgres \
|
|
409
|
+
--user sysml_api_service \
|
|
410
|
+
--password 'replace-me'
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
To deploy to Azure Container Apps:
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
export BUILD_MODE=local-docker
|
|
417
|
+
bash scripts/deploy_azure_container_app.sh
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Upstream Context
|
|
421
|
+
|
|
422
|
+
The copied upstream context package lives in:
|
|
423
|
+
- `context/upstream/refine_sysml.py`
|
|
424
|
+
- `context/upstream/setup_pipeline_env.sh`
|
|
425
|
+
- `context/upstream/pipeline_README.md`
|
|
426
|
+
- `context/upstream/pipeline_HELP.md`
|
|
427
|
+
- `context/upstream/env.example`
|
|
428
|
+
- `context/examples/example_prompt.txt`
|
|
429
|
+
- `context/examples/example_output.sysml`
|
|
430
|
+
- `context/examples/example_run_log.json`
|
|
431
|
+
|
|
432
|
+
That context is intentionally tight and keeps the original refinement flow visible without copying the whole older repository.
|