forked from 1b-agent/opencadstudio-upstream
feat(mcp): add side-effect-free request preflight
Add local ocs_read validate calls that check operation parameters, nested definitions, request envelopes and batch bindings without dispatching. Report document-dependent checks and unresolved result bindings explicitly. Share validation with execution and validate inline JSON Schema fragments before dispatch. Validation: 66 targeted tests, desktop build, WebAssembly app/worker check, schema validation and MCP stdio smoke tests.
This commit is contained in:
1 parent
97afb57333
commit
006be8909e
4 files changed
+293
-188
No files matched your search
@@ -8,7 +8,20 @@ Before creating an unfamiliar entity, use `ocs_read` with `op: entity_schema` an
|
||||
`parameters.type` (for example, `Circle`) to get its creation fields, required
|
||||
values, units, defaults and example. Omit type for the catalog. Creation schemas
|
||||
describe the inputs to `entities_create`; `record_schema` describes stored records.
|
||||
Schema discovery runs locally and can omit `ocs_session_id`.
|
||||
|
||||
Use `ocs_read` with `op: validate` and `parameters.request` containing the proposed
|
||||
execute request to preflight it without running it. These local operations can
|
||||
omit `ocs_session_id`; no GUI is launched or contacted. `request_id` may be omitted
|
||||
for preflight, but is required for actual execution. Static validation checks
|
||||
operation parameters, nested entity and inline data definitions, and batch
|
||||
bindings. It uses the real entity constructor for geometry checks. Results
|
||||
include `valid`, `executed: false`, warnings, unresolved bindings and checks that
|
||||
still require execution. Live revisions, handles, styles, file access and command
|
||||
behavior are not certified by static preflight. Batches are not simulated: later
|
||||
bindings are fully validated when their values become available during execution.
|
||||
Invalid requests return a tool error with a JSON Pointer identifying the bad
|
||||
field where available. Unknown top-level operation parameters remain warnings;
|
||||
unknown entity fields and invalid nested data are rejected before dispatch.
|
||||
|
||||
For interactive work, call start and follow state.command.accepts, options and input_example. To have the person at the screen pick entities for you, call user_select and keep polling until it completes; running means they are still picking. A run.cmd contains the command name followed by prompt answers separated by spaces; points use x,y or x,y,z.
|
||||
|
||||
|
||||
@@ -144,6 +144,26 @@ def legacy(server: Path) -> None:
|
||||
assert not entity_schema["result"].get("isError"), entity_schema
|
||||
contract = entity_schema["result"]["structuredContent"]["schema"]
|
||||
assert contract["required"] == ["type", "center", "radius"]
|
||||
validated = request(process, {
|
||||
"jsonrpc": "2.0", "id": "preflight", "method": "tools/call",
|
||||
"params": {"name": "ocs_read", "arguments": {
|
||||
"op": "validate", "parameters": {"request": {
|
||||
"op": "entities_create", "entities": contract["examples"],
|
||||
}},
|
||||
}},
|
||||
})
|
||||
assert validated["result"]["structuredContent"]["valid"] is True
|
||||
assert validated["result"]["structuredContent"]["executed"] is False
|
||||
rejected = request(process, {
|
||||
"jsonrpc": "2.0", "id": "bad-preflight", "method": "tools/call",
|
||||
"params": {"name": "ocs_read", "arguments": {
|
||||
"op": "validate", "parameters": {"request": {
|
||||
"op": "entities_create", "entities": [{"type": "Circle", "center": ["bad", 0], "radius": 5}],
|
||||
}},
|
||||
}},
|
||||
})
|
||||
assert rejected["result"]["isError"] is True
|
||||
assert "/entities/0/center/0" in rejected["result"]["content"][0]["text"]
|
||||
close(process)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user