mirror of
https://github.com/storytold/craft-ai-integrations.git
synced 2026-11-02 18:06:49 +00:00
7be5af833f
* feat(client): one start button for setting up a built-in model, with no tick box unless a licence needs one (#94) Part of #94, slice 1 of 3. The shared pieces for a one-click setup existed but nothing joined them. - NativeRoute/NativeSetupPlan::needs_agreement: the licence tick shows, and a download waits for it, only when a file's licence needs agreement. SAM 2.1 needs none. - SetupSession::start/next_task/blocker: one button that checks complete files on disk or downloads, and says why it does nothing (SetupBlock). - FolderDesk::ensure_default(_at): takes the suggested folder only when none is chosen. The widget offers it (UseSuggestedFolder) instead of dead-ending at "Choose a model folder". - ToolDesk::adopt(&CheckedNative): only checked files, binds only if no choice exists, and returns the choice it kept. - Docs: the flow in use-in-your-app, LAYOUT lists the Burn crates, STATUS row. - Mutation group fr (6 cases, 6 caught); two older cases re-aimed at the changed code. Checked: fmt, strict clippy and tests for craft-ai-features, -client, -egui and -comfy-env (473 passed, 2 ignored), wasm check for craft-ai-features, every mutation group --dry clean, group fr run for real, documentation 14/14. Scripted tests only: no real download, no model run through it, no app has mounted it, no macOS or Linux run. * feat(client): try a built-in selection model with a click, and fail a selection that chose nothing (#94) Part of #94, slice 2 of 3 (stacked on slice 1). The launcher's try-it sample for Select subject sent only a description. The default built-in route (SAM 2.1 on rten) refuses descriptions and selects by clicking, so the sample failed on the default route. - sample_request_for(feature, built_in): for image.segment with a built-in route, one click on the middle of the test disc and no description. Everything else is the plain sample. - ToolDesk::start_sample: picks the sample from the tool's current choice (a built-in engine the tool's recipe lists gets the click; ComfyUI and hosted routes keep the description). - ToolDesk::finish: a selection that ran but reports matched: false is a failed test. - Docs: step 5 of the set-up flow, STATUS row. - Mutation group fr gains 2 cases (8 in all, 8 caught). Checked: fmt, strict clippy and tests for craft-ai-features, -client, -egui and -comfy-env (478 passed, 2 ignored), wasm check for craft-ai-features, group fr run for real, documentation 34/34. Scripted tests and a fake provider only: no real model, no app, no macOS or Linux run. * feat(client): status, picker, route notes and engine advice agree with what the default route can do (#94) Part of #94, slice 3 of 3 (stacked on slices 1 and 2). - AiClient::status: a built-in model whose weights file has gone is not Ready. - The picker lists such a model once, as one to set up again, not also as a ready one. - NativeRoute::note: the setup option, the picker row and its description say the built-in SAM 2.1 route selects by clicking on the picture, instead of offering a prompt it refuses. - NativeRoute::fast_on_processor (rten, one Windows machine, about 35 ms a click, not a benchmark): engine advice gives it Pace::Processor, not "slow", and ranks it level with a card engine, so the recipe's first engine is the suggestion with or without a graphics card. - Mutation group fr gains 6 cases (14 in all, 14 caught); the Burn route case is re-aimed. Checked: fmt, strict clippy and tests for craft-ai-features, -client, -egui and -comfy-env (483 passed, 2 ignored), wasm check for craft-ai-features, every mutation group --dry clean, group fr run for real. Documentation 66/67; the one flagged is an untouched neighbour of a doc line. Scripted tests only: no real download, no model run through it, no app, no macOS or Linux run. * fix(client): one real start button, a failed check falls through to download, folder order (#98 review) Fixes the CodeRabbit findings on #98 that held up. - The setup widget showed "Check existing files" and "Download model files" side by side when complete files were on disk, so a person could start a download instead of the check. It now draws one start button from SetupSession::next_task and blocker, and its click calls SetupSession::start. The licence tick shows only when the next task is a download. - After a failed check, start kept choosing the check again, so files that did not match were a dead end. The session now remembers the folder that failed and downloads next; a different folder, or a different target, is checked again. - FolderDesk::ensure_default needed the computer's suggested folder even when the person had already chosen one. It now looks at chosen folders first. - The adopting guide told a host to call ensure_default before drawing the first screen, which makes the folder before the person accepts it. It now says to call it only on their yes. Checked: fmt; strict clippy; client tests and egui tests pass except the existing panel::a_dead_server_is_reported flake, which passed 3 of 3 alone; docs bar 38/38; mutation group fr 11/11 caught. Group nw had a case aimed at the old two-button code; it is re-aimed and caught. * fix(client): the sample copies only the small result outputs, not whole pictures (#99 review) finish cloned every output to read the selection result, copying large inline pictures and videos. It now copies only inline JSON, the form of a selection result. Behaviour is unchanged, so no test can see the copy; the existing sample tests still pass. Checked: fmt, strict clippy, client tests (309 passed), docs bar 64/64, mutation group fr 13/13. * fix(client,engine-candle,features): a selection sample needs its result, Candle sends it, small card pace (#100 review) Fixes the CodeRabbit findings on #100. - A segmentation sample passed when the route returned a mask and no Found result. The contract gives every route both, so the sample now fails with "did not say whether it selected anything". Other tools are unchanged. - Candle SAM 3 returned only a mask, which would now fail that test. It sends the Found result too (matched with its score, or nothing found when the model gave no prediction). - A processor-quick engine whose matching card is too small was called slow. It is now judged by the processor, as the card is not needed. - The adopting guide said every built-in selection model rejects words. It now says the sample uses a click, which every built-in route reads, and names the new rule. Docs bar: undocumented neighbours of the changed hunks are documented, the chain walked up to the first documented function (tests/engine.rs helpers and tests, three Candle runner methods). Checked: fmt; strict clippy (features, client, engine-candle); tests (features, client, candle lib: 440 passed); wasm check of craft-ai-features; docs bar 124/124; mutation group fr 22/22 caught, with three new cases. Not run: the live Candle test (needs the SAM 3 weights), so Candle sending Found is covered by a unit test of the result, not by a real run. * fix(client): only the connection this suite saves gets the click sample (#99 review) start_sample treated any connection whose provider is a built-in engine's name as built in. A custom connection that reuses the name `rten` may serve a model that needs a description, and the click-only request is refused by the planner before it is sent. The click sample now needs the engine's own saved connection id as well. Others keep the description sample. Checked: fmt, strict clippy, client tests (310 passed), docs bar 65/65, mutation group fr 14/14 caught (one new case; 'sample-ignores-the-route' re-aimed at the changed line). * fix(egui): show suggested folder before creating it The suggestion action creates the folder. Display its actual path first, and hide the action if no suggestion can be made. Keep the native path helper available in the egui library, not only its tests. Checked: fmt, strict clippy, 492 focused tests, wasm, 24/24 first-run mutations, docs 134/134. * fix(egui): keep the folder suggestion idle-only and test no suggestion The suggestion now waits for an active check to finish. Tests guard systems without a suggested path and exercise a busy session with discovered read-only files. Checked: 493 affected tests, fmt, strict clippy, wasm, 25/25 first-run mutations, docs 135/135. * fix(client): recover from bad files in a new approved folder A failed check now blocks reuse of the rejected directory and the previously shown destination. The person chooses a fresh folder, and the worker creates its model directory only if absent. The old files remain untouched, even if the newly approved directory appears before the worker begins. Scripted transfer and retry regressions: 388 affected tests, fmt, strict clippy, wasm, 15/15 first-run mutations, docs 49/49. Four unrelated native-feature mutations survive on upstream main too. * fix(client): explain why a fresh model folder could not be made Preserve the atomic create and distinguish an occupied destination, a missing approved parent and permission denial. Red regressions cover missing and occupied paths, and a mutation checks the message. Checked: 390 affected tests, fmt, strict clippy, wasm, 16/16 first-run mutations, docs 66/66. * fix(client): try another model under the built-in connection with words The sample picked a click whenever the connection was the one this suite saves for the engine, without checking the model. Connection management can put another model under that id, one that wants a description, and the click sample then failed for the wrong reason. Match the model the engine's recipe names as well. --------- Co-authored-by: scratch <s@s>
72 lines
4.3 KiB
Python
72 lines
4.3 KiB
Python
"""be: the Burn engine's own rules (saved-weights loading, the panic guard, the answer checks, the
|
|
file names it accepts), the catalogue route it is listed by, the binding's `.bpk` rule and the
|
|
shared revision.
|
|
|
|
Not reached here, because they need the real model, a graphics card or a graph the converter
|
|
panics on (the ignored live tests in `crates/ai-engine-burn/tests/live.rs` and
|
|
`crates/ai-client/tests/burn_engine.rs` are not run by this checker): the picture-size check in
|
|
`encode`, the click-count check in `segment`, the choice between the graphics card and the
|
|
processor, the converter's panic guard in `runner/prepare.rs`, and the cargo feature wiring in
|
|
`ai-client`.
|
|
Case shape: name, file, old, new, package, target, test filter.
|
|
"""
|
|
B = 'crates/ai-engine-burn/src/'
|
|
PKG = 'craft-ai-engine-burn'
|
|
|
|
|
|
def lib(name, file, old, new, test):
|
|
"""A case run against the engine crate's own unit tests."""
|
|
return name, B + file, old, new, PKG, 'lib', test
|
|
|
|
|
|
BE = [
|
|
lib('burn-magic-unchecked', 'backend.rs', ' && &head == MAGIC', ' && true',
|
|
'only_a_file_that_starts'),
|
|
lib('burn-missing-weights-allowed', 'backend.rs',
|
|
'&& result.missing.is_empty()', '', 'a_load_that_left_a_weight'),
|
|
lib('burn-weight-errors-allowed', 'backend.rs',
|
|
'result.is_success() &&', '', 'a_load_that_left_a_weight'),
|
|
lib('burn-panic-not-guarded', 'backend.rs',
|
|
'catch_unwind(AssertUnwindSafe(work)).ok()', 'Some(work())', 'a_panic_in_guarded'),
|
|
lib('burn-wrong-length-answer-accepted', 'backend.rs',
|
|
'if masks.len() != PROPOSALS * side || scores.len() != PROPOSALS {', 'if false {',
|
|
'an_answer_of_the_wrong_size'),
|
|
lib('burn-best-proposal-ignored', 'backend.rs',
|
|
'let best = best_proposal(scores);', 'let best = 0;', 'best_rated'),
|
|
lib('burn-onnx-file-guessed', 'runner.rs',
|
|
'if weights.file_name() == Some(OsStr::new("encoder.onnx")) {', 'if false {',
|
|
'not_the_supported_export'),
|
|
lib('burn-prepare-decoder-not-required', 'runner/prepare.rs',
|
|
'filter(|d| d.join("decoder.onnx").is_file())', 'filter(|_| true)',
|
|
'no_decoder_says_what_is_missing'),
|
|
lib('burn-prepared-copy-inside-the-model-folder', 'runner/prepare.rs',
|
|
'source.parent().map(|p| p.join(PREPARED_DIR))', 'Some(source.join(PREPARED_DIR))',
|
|
'not_the_supported_export'),
|
|
lib('burn-decoder-not-required', 'runner.rs',
|
|
'd.join(DECODER_FILE).is_file() && weights.is_file()', 'weights.is_file()',
|
|
'not_both_files'),
|
|
lib('burn-encoder-name-not-checked', 'runner.rs',
|
|
'.filter(|_| weights.file_name() == Some(OsStr::new(ENCODER_FILE)));',
|
|
'.filter(|_| true);', 'not_both_files'),
|
|
lib('burn-nvidia-not-declared', 'runner.rs',
|
|
' GpuVendor::Nvidia,\n GpuVendor::Amd,', ' GpuVendor::Amd,\n GpuVendor::Amd,',
|
|
'is_the_burn_sam21'),
|
|
lib('burn-damaged-copy-not-explained', 'runner/prepare.rs',
|
|
'if error.message == craft_ai_burn_setup::DAMAGED_COPY {', 'if false {',
|
|
'a_damaged_saved_copy_is_explained'),
|
|
('burn-revision-bumped-in-the-architecture', B + 'model/mod.rs',
|
|
'onnx-0.22.0-v1";', 'onnx-0.22.0-v2";', PKG, 'revision', 'the_architecture_and_the_saved'),
|
|
('burn-revision-bumped-in-the-cache-key', 'crates/ai-burn-setup/src/sam21.rs',
|
|
'onnx-0.22.0-v1";', 'onnx-0.22.0-v2";', PKG, 'revision', 'the_architecture_and_the_saved'),
|
|
('burn-route-lists-no-files', 'crates/ai-features/src/catalogue/sam21.rs',
|
|
' models: sam21_onnx_files(),\n note: Some("Selects by clicking on the picture, not by a description.".to_owned()),\n fast_on_processor: false,\n },\n ],',
|
|
' models: Vec::new(),\n note: Some("Selects by clicking on the picture, not by a description.".to_owned()),\n fast_on_processor: false,\n },\n ],',
|
|
'craft-ai-features', 'native_files', 'burns_sam_2_1_route'),
|
|
('burn-route-named-rten', 'crates/ai-features/src/catalogue/sam21.rs',
|
|
'provider: "burn".to_owned(),', 'provider: "rten".to_owned(),',
|
|
'craft-ai-features', 'native_files', 'burns_sam_2_1_route'),
|
|
('burn-bpk-refused-when-binding', 'crates/ai-client/src/local.rs',
|
|
'["safetensors", "onnx", "bpk"]', '["safetensors", "onnx"]',
|
|
'craft-ai-client', 'local_native', 'burn_route_is_registered'),
|
|
]
|