Skip to content

feat(magic-ai): managed platforms, managed from the CLI - #723

Merged
navneetkumar-pim-webkul merged 13 commits into
3.xfrom
feat/magic-ai-managed-platform
Sep 24, 2026
Merged

navneetkumar-pim-webkul merged 13 commits into
3.xfrom
feat/magic-ai-managed-platform

Conversation

@navneetkumar-pim-webkul

@navneetkumar-pim-webkul navneetkumar-pim-webkul commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Adds managed platforms: a platform flagged is_managed is locked to its own stored provider, endpoint and model list. Intended for hosted installs that ship the operator's own AI account.
  • Managed platforms are created and changed only from the CLI, since server access is the trust boundary. The admin UI shows them read-only (status and default can still be toggled) and cannot delete them.
  • Existing platforms get is_managed = false and behave exactly as before.

CLI

Command Purpose
unopim:magic-ai:platform:list List platforms (never shows the key)
unopim:magic-ai:platform:add Wizard with the same fields and validation as the admin form, plus "managed?"
unopim:magic-ai:platform:edit {id?} Pre-filled wizard; an empty key keeps the stored one
unopim:magic-ai:platform:delete {id?} Confirm or --force; can delete managed platforms; refuses the default one
unopim:magic-ai:platform:default {id?} Set the default (the platform must be enabled)
  • Every command also runs non-interactively. The key is read only from STDIN (--key-stdin), never from argv.

Enforcement

  • UI edits: any change to a managed platform other than status or default returns 422 managed-cli-only. Delete returns 400.
  • Masked key: test connection, fetch models and save all reject a masked (********) 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.
  • Generation: a model outside the managed list is swapped for one on it.
  • Shared validation: the form and the CLI both use PlatformValidator.

Upgrade notes

  • Run php artisan migrate (additive is_managed column). The AI Platforms grid needs it.

Compatibility (patch release)

  • Checked against v3.1.1: routes, request fields, response keys, translation keys and public/protected method signatures are unchanged or only extended.
  • Every new 4xx response applies only to managed platforms.
  • The guard's after() has no return type and its helpers use a managed* prefix, so plugin subclasses keep working.

Tests

  • Magic AI, Admin Magic AI and AiAgent suites: 737 passed.
  • Pint, PHPStan (level 2), Rector and unopim:translations:check clean; new strings in all 33 locales.

…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 AI lite review requested due to automatic review settings September 24, 2026 06:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 High severity · 2 Medium severity

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.

Comment thread packages/Webkul/MagicAI/src/Services/ManagedPlatform.php Outdated
Comment thread packages/Webkul/Admin/src/Http/Controllers/MagicAI/MagicAIPlatformController.php Outdated
Comment thread packages/Webkul/MagicAI/src/Console/Commands/ProvisionManagedPlatform.php Outdated
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.
@navneetkumar-pim-webkul navneetkumar-pim-webkul changed the title feat(magic-ai): managed platform key restricted to its models feat(magic-ai): managed platforms, managed from the CLI Sep 24, 2026
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
@navneetkumar-pim-webkul
navneetkumar-pim-webkul merged commit 2a16b83 into 3.x Sep 24, 2026
23 checks passed
@navneetkumar-pim-webkul
navneetkumar-pim-webkul deleted the feat/magic-ai-managed-platform branch September 24, 2026 16:04
navneetkumar-pim-webkul added a commit that referenced this pull request Sep 24, 2026
… on hover (#733)

#723 added hover:text-danger to the Magic AI platform form after the
last asset build, so the compiled stylesheet did not carry the rule.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants