models: update_custom + delete_custom, fix add/remove filter#169
Merged
Conversation
Companion to atlas-app PR #1916. Three concrete behavior changes: 1. add() / remove() now operate on the full project model list (public + custom). The previous type="public" filter silently dropped custom-model IDs from Project.Models on every call. 2. New update_custom(model_id, *, api_url, api_key, max_tokens) — the customer's primary workflow: repoint api_url for ephemeral vLLM endpoints behind cloudflared tunnels whose hostname changes between sessions. 3. New delete_custom(model_id) — full teardown: disables the record, strips it from Project.Models, releases the name for reuse. Mirrors all three in AsyncModels. Adds unit tests (12 new in test_models_resource.py) and a @pytest.mark.live lifecycle test in test_models_custom_live.py. Docs and the custom_model sample now exercise update + delete. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI's format check insists on these two cosmetic adjustments. No behavior change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
update_custom(model_id, *, api_url, api_key, max_tokens)(sync + async) — repoint a custom model's mutable fields without recreating it. Customer's primary workflow: ephemeral vLLM endpoints behind cloudflared tunnels whose URL rotates between sessions.delete_custom(model_id)(sync + async) — full teardown that disables the record, strips it fromProject.Models, releases the name for reuse.add()/remove()to operate on the full project model list (public + custom). The previoustype="public"filter silently dropped custom-model IDs fromProject.Modelson every call.Companion to atlas-app PR https://github.com/LayerLens/atlas-app/pull/1916, which lands the matching backend routes (
PATCH+DELETE /custom-models/{id}on the API-key router) and the PatchProject validator fix that the SDK depends on. Merge atlas-app first, then this one.Customer context
client.models.remove(custom_model_id)was returning a 500 referencing a different model. Root cause was the atlas-app PatchProject validator only checking the public ModelsCollection; the newupdate_custompath lets the customer repoint their tunnel-backed model in place, which is what they actually wanted to do all along.delete_customis the explicit teardown path for the rare cases where recreate is needed.What changed
src/layerlens/resources/models/models.py— three new flows (sync + async); docstring + behavior change onadd/remove.tests/resources/test_models_resource.py— 12 new unit tests covering update_custom (partial / full / error / non-dict response), delete_custom (happy / error envelope), plus regression tests thatadd/removenow preserve custom models in the PATCH payload.tests/test_models_custom_live.py— new@pytest.mark.liveend-to-end (create → update → delete → confirm gone). Auto-skipped withoutLAYERLENS_STRATIX_API_KEY. Includes best-effort cleanup on failure.tests/test_samples_e2e.py— mocked client fixture grewupdate_custom/delete_customstubs.docs/api-reference/models-benchmarks.md— newupdate_customanddelete_customsections;add/removeblurbs reworded.docs/examples/models-and-benchmarks.md— two worked examples (repointing api_url; replacing a custom model).samples/core/custom_model.py— extended to exercise update + delete after the existing create flow.Test plan
pytest tests/resources/test_models_resource.py— 68 pass (12 new)pytest tests/test_samples_e2e.py -k custom_model— sample runs cleanly under the mocked clientpytest tests/test_models_custom_live.py— skips cleanly without API keymypy src/layerlens/— 70 files cleanmodels.remove(custom_id)returns success, andupdate_custom(custom_id, api_url=...)lands the new URLNotes
tests/cli/test_commands.py(CliRunner(mix_stderr=False)is removed in click ≥ 8.2) are unrelated and predate this branch.🤖 Generated with Claude Code