Add Morpheus provider with dynamic model discovery#1488
Add Morpheus provider with dynamic model discovery#1488betterbrand wants to merge 4 commits intogenlayerlabs:mainfrom
Conversation
Add Morpheus decentralized AI inference as a provider option. Models are fetched in real time from the Morpheus marketplace API via a schema-driven x-models-url mechanism, with graceful fallback to manual text input if the API is unreachable.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdded Morpheus, IONet, and OpenRouter as provider options: environment variable placeholder, backend and frontend schema entries with provider-specific defaults and models URL, and UI changes to fetch and display provider models dynamically with loading/error handling. Changes
Sequence DiagramsequenceDiagram
participant User as User
participant Modal as ProviderModal
participant Schema as Schema Processor
participant API as Morpheus API
participant UI as UI State
User->>Modal: Select provider "morpheus"
Modal->>Schema: Evaluate provider schema
Schema-->>Modal: Return x-models-url & x-plugin-config-defaults
Modal->>UI: isLoadingModels = true
Modal->>API: fetchDynamicModels(x-models-url)
API-->>Modal: models list
Modal->>Modal: Filter LLM models & apply plugin_config defaults
Modal->>UI: populate modelOptions & set default model
Modal->>UI: isLoadingModels = false / show errors if any
UI-->>User: Display models and provider options
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
backend/node/create_nodes/providers_schema.json (1)
77-83:⚠️ Potential issue | 🟡 MinorDuplicate model entry in google enum.
"gemini-2.5-flash-lite"appears twice in the enum (lines 79 and 82). This won't break functionality but is likely unintended.🔧 Proposed fix
"model": { "enum": [ "gemini-2.0-flash-lite-001", "gemini-2.5-flash-lite", "gemini-2.5-flash", - "gemini-3.0-flash", - "gemini-2.5-flash-lite" + "gemini-3.0-flash" ] }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/node/create_nodes/providers_schema.json` around lines 77 - 83, Remove the duplicate enum entry "gemini-2.5-flash-lite" from the providers_schema.json models enum so each model appears only once; locate the "enum" array that lists model names (contains "gemini-2.0-flash-lite", "gemini-2.5-flash-lite", etc.) and delete the repeated "gemini-2.5-flash-lite" entry to ensure unique values.
🧹 Nitpick comments (1)
frontend/src/components/Simulator/ProviderModal.vue (1)
206-228: Consider adding timeout and request cancellation for reliability.The dynamic model fetch lacks a timeout and cancellation mechanism. If the Morpheus API is slow or unresponsive, the request could hang indefinitely. Additionally, if the user switches providers while a fetch is in progress, stale results could populate the dropdown.
♻️ Suggested improvement with AbortController and timeout
+let modelFetchController: AbortController | null = null; + const fetchDynamicModels = async (modelsUrl: string) => { + // Cancel any in-flight request + if (modelFetchController) { + modelFetchController.abort(); + } + modelFetchController = new AbortController(); + isLoadingModels.value = true; modelFetchError.value = ''; try { - const response = await fetch(modelsUrl); + const timeoutId = setTimeout(() => modelFetchController?.abort(), 10000); + const response = await fetch(modelsUrl, { signal: modelFetchController.signal }); + clearTimeout(timeoutId); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); // ... rest of the logic } catch (err) { + if ((err as Error).name === 'AbortError') return; console.error('Failed to fetch models:', err); modelFetchError.value = 'Could not fetch available models. You can type a model name manually.'; } finally { isLoadingModels.value = false; + modelFetchController = null; } };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/components/Simulator/ProviderModal.vue` around lines 206 - 228, The fetchDynamicModels function should be made cancellable and time-limited: create an AbortController for each call (store the controller in a scoped variable so subsequent calls can abort the previous request), pass controller.signal to fetch(modelsUrl), and implement a timeout (e.g., setTimeout that calls controller.abort() after N ms) to ensure the request doesn't hang; handle AbortError in the catch to avoid showing the generic modelFetchError for intentional cancellations, and ensure the timeout is cleared and isLoadingModels.value is reset in the finally block; update references to modelOptions.value, newProviderData.model and modelFetchError.value exactly where fetchDynamicModels sets them so stale responses cannot overwrite UI state after an abort.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/src/assets/schemas/providers_schema.json`:
- Around line 14-16: The frontend providers schema is missing the "openrouter"
provider present in the backend examples; either add "openrouter" to the
providers list in frontend/src/assets/schemas/providers_schema.json and mirror
the necessary allOf configuration used in the backend (match the backend's
provider example and schema fields for "openrouter"), or add a clear JSON
comment/docstring in that same schema file explaining that "openrouter" is
backend-only and intentionally omitted; locate the providers array near the
entries "google" and "morpheus" and update it accordingly and ensure any
referenced schema definitions used by the backend's "openrouter" example are
also added or referenced.
---
Outside diff comments:
In `@backend/node/create_nodes/providers_schema.json`:
- Around line 77-83: Remove the duplicate enum entry "gemini-2.5-flash-lite"
from the providers_schema.json models enum so each model appears only once;
locate the "enum" array that lists model names (contains
"gemini-2.0-flash-lite", "gemini-2.5-flash-lite", etc.) and delete the repeated
"gemini-2.5-flash-lite" entry to ensure unique values.
---
Nitpick comments:
In `@frontend/src/components/Simulator/ProviderModal.vue`:
- Around line 206-228: The fetchDynamicModels function should be made
cancellable and time-limited: create an AbortController for each call (store the
controller in a scoped variable so subsequent calls can abort the previous
request), pass controller.signal to fetch(modelsUrl), and implement a timeout
(e.g., setTimeout that calls controller.abort() after N ms) to ensure the
request doesn't hang; handle AbortError in the catch to avoid showing the
generic modelFetchError for intentional cancellations, and ensure the timeout is
cleared and isLoadingModels.value is reset in the finally block; update
references to modelOptions.value, newProviderData.model and
modelFetchError.value exactly where fetchDynamicModels sets them so stale
responses cannot overwrite UI state after an abort.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.env.examplebackend/node/create_nodes/providers_schema.jsonfrontend/src/assets/schemas/providers_schema.jsonfrontend/src/components/Simulator/ProviderModal.vue
The backend schema included openrouter and ionet provider blocks (added in genlayerlabs#1427/genlayerlabs#1429) but these were never mirrored to the frontend. Sync the examples array and allOf conditional blocks so both schemas list the same set of providers.
|
Good catch by CodeRabbit on the openrouter/ionet frontend schema drift. T Addressed in 739bf9a where both schemas now list the same 9 providers with matching allOf blocks. Happy to help as always from the Morpheus community |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@cristiam86 @kstroobants — this is ready for review when you get a chance. Two commits:
|
Match the underscore convention used by newer providers (ANTHROPIC_API_KEY, XAI_API_KEY, GEMINI_API_KEY).
|
Third commit renames the env var from |
With the integration of the Morpheus Marketplace, Intelligent Contracts gain censorship-resistant inference with no single point of failure, and the available model catalog updates automatically as new providers join the marketplace. This PR adds Morpheus as a provider in GenLayer Studio with fully dynamic model discovery. When a user selects Morpheus, Studio fetches the live model catalog from the Morpheus marketplace in real time, so validators always see whatever models are currently available across the decentralized network.
Summary
x-models-urlextension for dynamic model fetchingProviderModal.vueto detectx-models-urland populate the model dropdown from the Morpheus API at runtimeMORPHEUSAPIKEY, API URL) viax-plugin-config-defaultsschema extensionMORPHEUSAPIKEYto.env.exampleHow it works
The integration uses a schema-driven approach: a custom
x-models-urlJSON Schema property tells the frontend where to fetch models dynamically. This is generic — any future provider can opt in by addingx-models-urlto their schema block. If the API is unreachable, the UI gracefully degrades to a free-text input.Files changed
frontend/src/assets/schemas/providers_schema.json— add Morpheus conditional block withx-models-urlbackend/node/create_nodes/providers_schema.json— same schema changes (backend mirror)frontend/src/components/Simulator/ProviderModal.vue— dynamic model fetching, loading states, provider-specific defaults.env.example— addMORPHEUSAPIKEYplaceholderTest plan
cd frontend && npm run test— all 113 unit tests passapi_key_env_varpre-fills asMORPHEUSAPIKEY,api_urlashttps://api.mor.org/api/v1api.mor.orgreturns proper headers for browser requestsSummary by CodeRabbit
New Features
Chores