diff --git a/src/locales/en/main.json b/src/locales/en/main.json
index 9fd1284fd..19b731d6a 100644
--- a/src/locales/en/main.json
+++ b/src/locales/en/main.json
@@ -2385,6 +2385,21 @@
"assetCard": "{name} - {type} asset",
"loadingAsset": "Loading asset"
},
+ "modelInfo": {
+ "title": "Model Info",
+ "basicInfo": "Basic Info",
+ "displayName": "Display Name",
+ "fileName": "File Name",
+ "source": "Source",
+ "viewOnSource": "View on {source}",
+ "modelTagging": "Model Tagging",
+ "modelType": "Model Type",
+ "compatibleBaseModels": "Compatible Base Models",
+ "additionalTags": "Additional Tags",
+ "modelDescription": "Model Description",
+ "triggerPhrases": "Trigger Phrases",
+ "description": "Description"
+ },
"media": {
"threeDModelPlaceholder": "3D Model",
"audioPlaceholder": "Audio"
diff --git a/src/platform/assets/components/AssetBrowserModal.vue b/src/platform/assets/components/AssetBrowserModal.vue
index b7db7494c..5db471458 100644
--- a/src/platform/assets/components/AssetBrowserModal.vue
+++ b/src/platform/assets/components/AssetBrowserModal.vue
@@ -60,12 +60,16 @@
@asset-deleted="refreshAssets"
/>
+
+
+
+
diff --git a/src/platform/assets/components/modelInfo/ModelInfoPanel.vue b/src/platform/assets/components/modelInfo/ModelInfoPanel.vue
new file mode 100644
index 000000000..901b336e2
--- /dev/null
+++ b/src/platform/assets/components/modelInfo/ModelInfoPanel.vue
@@ -0,0 +1,140 @@
+
+
+
+
+
diff --git a/src/platform/assets/utils/assetMetadataUtils.ts b/src/platform/assets/utils/assetMetadataUtils.ts
index 2d32fa07f..2d50f3dbe 100644
--- a/src/platform/assets/utils/assetMetadataUtils.ts
+++ b/src/platform/assets/utils/assetMetadataUtils.ts
@@ -25,3 +25,63 @@ export function getAssetBaseModel(asset: AssetItem): string | null {
? asset.user_metadata.base_model
: null
}
+
+/**
+ * Gets the display name for an asset, falling back to filename
+ * @param asset - The asset to get display name from
+ * @returns The display name or filename
+ */
+export function getAssetDisplayName(asset: AssetItem): string {
+ return typeof asset.user_metadata?.display_name === 'string'
+ ? asset.user_metadata.display_name
+ : asset.name
+}
+
+/**
+ * Safely extracts source URL from asset metadata
+ * @param asset - The asset to extract source URL from
+ * @returns The source URL or null if not present
+ */
+export function getAssetSourceUrl(asset: AssetItem): string | null {
+ return typeof asset.user_metadata?.source_url === 'string'
+ ? asset.user_metadata.source_url
+ : null
+}
+
+/**
+ * Extracts trigger phrases from asset metadata
+ * @param asset - The asset to extract trigger phrases from
+ * @returns Array of trigger phrases
+ */
+export function getAssetTriggerPhrases(asset: AssetItem): string[] {
+ const phrases = asset.user_metadata?.trigger_phrases
+ if (Array.isArray(phrases)) {
+ return phrases.filter((p): p is string => typeof p === 'string')
+ }
+ if (typeof phrases === 'string') return [phrases]
+ return []
+}
+
+/**
+ * Extracts additional tags from asset user_metadata
+ * @param asset - The asset to extract tags from
+ * @returns Array of user-defined tags
+ */
+export function getAssetTags(asset: AssetItem): string[] {
+ const tags = asset.user_metadata?.tags
+ if (Array.isArray(tags)) {
+ return tags.filter((t): t is string => typeof t === 'string')
+ }
+ return []
+}
+
+/**
+ * Determines the source name from a URL
+ * @param url - The source URL
+ * @returns Human-readable source name
+ */
+export function getSourceName(url: string): string {
+ if (url.includes('civitai.com')) return 'Civitai'
+ if (url.includes('huggingface.co')) return 'Hugging Face'
+ return 'Source'
+}