Repository navigation
feat(magic-ai): managed platforms, managed from the CLI - #723
Merged
Merged
Conversation
…rrides MAGIC_AI_ALLOWED_MODELS applied one list to every provider, so it could not restrict a single account without emptying the others. The pre-selection cap stays at five as a class constant.
The installation can ship a managed platform whose key comes from MAGIC_AI_MANAGED_API_KEY. That key is recognised wherever it is used, so it is held to MAGIC_AI_MANAGED_MODELS and pinned to its provider and endpoint on save, connection test and model fetch, including when the form submits it masked. Without the pin, an edited endpoint would send the stored key to any host. Generation swaps a model outside the list for one on it. Any other key, including a client's own Concentrate AI key, is unrestricted. unopim:magic-ai:managed-platform creates or refreshes the platform and makes it the default when none is set.
Copilot started reviewing on behalf of
navneetkumar-pim-webkul
September 24, 2026 06:50
View session
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Three unresolved findings remain, including one critical endpoint-validation issue and two moderate behavior issues.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (3)
What changed in this PR
Adds a managed Magic AI platform restricted to configured providers, endpoints, and models, replacing unreleased global model settings.
Changes:
- Adds managed-platform configuration, provisioning, validation, and enforcement.
- Applies model restrictions to fetching, generation, and chat.
- Updates tests, translations, changelog, and environment documentation.
Outstanding findings include one critical endpoint-validation issue and two moderate behavior issues.
| File | Description |
|---|---|
packages/Webkul/MagicAI/tests/Feature/ManagedPlatformTest.php |
Managed-platform feature coverage |
packages/Webkul/MagicAI/src/Support/ModelRecommender.php |
Fixed recommendation limit |
packages/Webkul/MagicAI/src/Services/ManagedPlatform.php |
Managed credential enforcement |
packages/Webkul/MagicAI/src/Providers/MagicAIServiceProvider.php |
Registers provisioning command |
packages/Webkul/MagicAI/src/MagicAI.php |
Applies model restrictions |
packages/Webkul/MagicAI/src/Console/Commands/ProvisionManagedPlatform.php |
Provisions managed platform |
packages/Webkul/MagicAI/src/Config/magic_ai.php |
Managed-platform configuration |
packages/Webkul/AiAgent/tests/Unit/ModelSelectionConfigTest.php |
Recommendation-limit tests |
packages/Webkul/AiAgent/src/Http/Controllers/ChatController.php |
Restricts chat model selection |
packages/Webkul/Admin/src/Resources/lang/zh_TW/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/zh_CN/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/vi_VN/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/uk_UA/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/tr_TR/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/tl_PH/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/sv_SE/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/ru_RU/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/ro_RO/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/pt_PT/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/pl_PL/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/no_NO/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/nl_NL/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/mn_MN/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/ko_KR/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/ja_JP/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/it_IT/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/id_ID/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/hr_HR/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/hi_IN/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/fr_FR/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/fi_FI/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/es_VE/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/es_ES/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/en_US/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/en_NZ/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/en_GB/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/en_AU/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/de_DE/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/da_DK/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/ca_ES/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Resources/lang/ar_AE/app.php |
Managed-platform translations |
packages/Webkul/Admin/src/Http/Requests/MagicAI/PlatformTestRequest.php |
Adds managed validation |
packages/Webkul/Admin/src/Http/Requests/MagicAI/PlatformRequest.php |
Adds managed validation |
packages/Webkul/Admin/src/Http/Requests/MagicAI/FetchModelsRequest.php |
Adds managed validation |
packages/Webkul/Admin/src/Http/Requests/MagicAI/Concerns/GuardsManagedPlatform.php |
Shared managed-platform guard |
packages/Webkul/Admin/src/Http/Controllers/MagicAI/MagicAIPlatformController.php |
Handles restricted model fetching |
CHANGELOG.md |
Documents the feature |
.env.example |
Documents managed settings |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
A managed platform saved without a URL is called on the provider's default endpoint, which bypassed a configured MAGIC_AI_MANAGED_API_URL; an empty URL is now held to the managed endpoint like any other. The managed fetch pre-selects through the recommender so the five-model cap applies, and re-provisioning restores the default when none is set.
…naged flag The hosting owner's Concentrate AI key no longer lives in .env. The unopim:magic-ai:managed-platform command prompts for it (never an argv option), stores it encrypted on the platform row and sets is_managed, which is not fillable, so no admin request can set or forge it. The managed platform is recognised by that flag instead of comparing keys. While it runs on its stored key it stays pinned to the managed provider, endpoint and model list, and it cannot be deleted. A client entering their own key lifts the restriction and clears the flag; every other platform stays unrestricted.
The managed platform no longer depends on MAGIC_AI_MANAGED_* settings. unopim:magic-ai:managed-platform now collects a platform the way the admin form does (provider, label, endpoint, key, Azure settings, models fetched from the provider, default, status) plus the managed flag, and saves it through the platform repository. It also runs unattended from options, reading the key from standard input so it never lands in argv. The form's checks move into a shared PlatformValidator used by both the controller and the command, and model discovery goes through a ModelDiscovery service so the command can be tested without the network. A managed platform is now locked to its own saved provider, endpoint and model list instead of config, so several managed platforms can coexist.
…ake it create-only The command now only adds platforms: the target select, edit pre-fill, --platform option and keep-stored-key path are gone, along with the translations only they used.
…ead-only in the UI Replace the single add command with unopim:magic-ai:platform:list, :add, :edit, :delete and :default. They share a base command and traits, save through the platform repository with the shared PlatformValidator, and run unattended from options with the key read only from standard input. A managed platform is now read-only in the admin panel apart from its status and default flag: an update that changes any other field or submits a new key is rejected, which closes the path where an admin could take over the hosted key by typing their own. The edit modal shows every field read-only for such a platform with a note that it is managed from the server. Setting the default now goes through one repository method shared by the controller and the CLI.
The literal key "0" kept the stored key in v3.1.1 and overwrote it here; it keeps the stored key again. The guard ran on payloads that had already failed validation, so an array provider or URL raised a 500 instead of a 422; it now stops there and only reads string input. The after() hook drops its return type and the helpers take a managed prefix, so a plugin subclass that already declares after() or a helper of the same name does not hit a fatal signature mismatch.
The label, endpoint, key and Azure fields were read-only on a managed platform but kept the editable look and took focus. They now fade and ignore pointer input like the disabled provider select. They stay read-only rather than disabled so the form still submits their values.
…otes Tenants of a hosted install have no server access, so pointing them at the command line is noise; the notes now only say the platform is managed for them and which settings they can still change.
…platform # Conflicts: # packages/Webkul/AiAgent/tests/Unit/ModelSelectionConfigTest.php # packages/Webkul/MagicAI/src/Support/ModelRecommender.php
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
is_managedis locked to its own stored provider, endpoint and model list. Intended for hosted installs that ship the operator's own AI account.is_managed = falseand behave exactly as before.CLI
unopim:magic-ai:platform:listunopim:magic-ai:platform:addunopim:magic-ai:platform:edit {id?}unopim:magic-ai:platform:delete {id?}--force; can delete managed platforms; refuses the default oneunopim:magic-ai:platform:default {id?}--key-stdin), never from argv.Enforcement
managed-cli-only. Delete returns 400.********) managed key combined with another provider, endpoint, extras or model. This closes a path where the stored key could be sent to an arbitrary host.PlatformValidator.Upgrade notes
php artisan migrate(additiveis_managedcolumn). The AI Platforms grid needs it.Compatibility (patch release)
after()has no return type and its helpers use amanaged*prefix, so plugin subclasses keep working.Tests
unopim:translations:checkclean; new strings in all 33 locales.