@kolbo/mcp 1.30.3 → 1.30.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/apps/index.js +19 -7
- package/src/apps/widgets/generation.js +1 -1
package/package.json
CHANGED
package/src/apps/index.js
CHANGED
|
@@ -125,6 +125,23 @@ function uiResult(uri, text, structured) {
|
|
|
125
125
|
const ICON_TTL_MS = 10 * 60 * 1000;
|
|
126
126
|
const infoCache = new Map(); // apiBase → { at, byKey: Map<lowername, {icon, eta}> }
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Resolve a Model.avatar value to an absolute URL. Avatars are bare filenames
|
|
130
|
+
* (sometimes with spaces) living in the BACKEND's public assets folder —
|
|
131
|
+
* `<api origin>/assets/<file>`. Do NOT use app.kolbo.ai for this: it's the SPA,
|
|
132
|
+
* whose catch-all returns 200 text/html for any missing file, which renders as
|
|
133
|
+
* a broken image in widgets.
|
|
134
|
+
*/
|
|
135
|
+
function resolveAvatarUrl(avatar, apiBase) {
|
|
136
|
+
if (!avatar) return null;
|
|
137
|
+
if (/^https?:\/\//i.test(avatar)) return avatar;
|
|
138
|
+
let origin = 'https://api.kolbo.ai';
|
|
139
|
+
try {
|
|
140
|
+
origin = new URL(apiBase || 'https://api.kolbo.ai/api').origin;
|
|
141
|
+
} catch (_) { /* keep default */ }
|
|
142
|
+
return `${origin}/assets/${encodeURIComponent(avatar)}`;
|
|
143
|
+
}
|
|
144
|
+
|
|
128
145
|
async function modelInfoMap(client) {
|
|
129
146
|
const cacheKey = client.apiBase || 'default';
|
|
130
147
|
const hit = infoCache.get(cacheKey);
|
|
@@ -135,13 +152,7 @@ async function modelInfoMap(client) {
|
|
|
135
152
|
const models = res?.models || res?.data?.models || [];
|
|
136
153
|
for (const m of models) {
|
|
137
154
|
if (!m) continue;
|
|
138
|
-
|
|
139
|
-
// deployments / internal calls) resolve against the app's public icon dir.
|
|
140
|
-
const icon = m.avatar
|
|
141
|
-
? (/^https?:\/\//i.test(m.avatar)
|
|
142
|
-
? m.avatar
|
|
143
|
-
: `https://app.kolbo.ai/models_icons/${encodeURIComponent(m.avatar)}`)
|
|
144
|
-
: null;
|
|
155
|
+
const icon = resolveAvatarUrl(m.avatar, client.apiBase);
|
|
145
156
|
// Real p75 wall-clock estimate mined from production creditUsages —
|
|
146
157
|
// the same source the in-app countdowns use. No estimate → no ETA shown.
|
|
147
158
|
const eta = Number(m.estimatedDurationSeconds || m.estimated_duration_seconds) || null;
|
|
@@ -232,5 +243,6 @@ module.exports = {
|
|
|
232
243
|
modelIcon,
|
|
233
244
|
modelInfo,
|
|
234
245
|
modelInfoMap,
|
|
246
|
+
resolveAvatarUrl,
|
|
235
247
|
widgetHtml, // exported for smoke tests
|
|
236
248
|
};
|
|
@@ -92,7 +92,7 @@ function renderChips(sc) {
|
|
|
92
92
|
if (s.voice) h += chip('🎤 ' + esc(s.voice));
|
|
93
93
|
if (s.mode) h += chip(esc(s.mode));
|
|
94
94
|
if (sc.count > 1) h += chip('×' + sc.count);
|
|
95
|
-
if (sc.reference_image) h += '<img class="k-ref-thumb" src="' + esc(sc.reference_image) + '" alt="" title="Reference image" onerror="this.style.display
|
|
95
|
+
if (sc.reference_image) h += '<img class="k-ref-thumb" src="' + esc(sc.reference_image) + '" alt="" title="Reference image" onerror="this.style.display=\\'none\\'">';
|
|
96
96
|
el('chips').innerHTML = h;
|
|
97
97
|
}
|
|
98
98
|
function chip(inner) { return '<span class="k-chip">' + inner + '</span>'; }
|