@wavespeed/mcp 1.2.1 → 1.2.2
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/assets/result.html +74 -25
- package/package.json +1 -1
package/assets/result.html
CHANGED
|
@@ -18,9 +18,12 @@
|
|
|
18
18
|
.prompt { color: var(--muted); margin: 0 0 10px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
|
19
19
|
.grid { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
|
|
20
20
|
.grid.one { grid-template-columns: 1fr; }
|
|
21
|
-
.tile { background: var(--card); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
|
|
21
|
+
.tile { position: relative; background: var(--card); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
|
|
22
22
|
.tile img, .tile video { display: block; width: 100%; max-height: 520px; object-fit: contain; background: var(--card); }
|
|
23
23
|
.tile video { background: #000; }
|
|
24
|
+
.tile-spin { position: absolute; top: 40%; left: 50%; margin: -9px 0 0 -9px; pointer-events: none; }
|
|
25
|
+
.code { margin: 0; padding: 12px; max-height: 360px; overflow: auto; font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre-wrap; word-break: break-word; }
|
|
26
|
+
.text { padding: 12px; white-space: pre-wrap; word-break: break-word; max-height: 360px; overflow: auto; }
|
|
24
27
|
.broken { padding: 28px 12px; text-align: center; color: var(--muted); font-size: 13px; }
|
|
25
28
|
.tile img { cursor: zoom-in; }
|
|
26
29
|
.tile audio { display: block; width: 100%; padding: 10px; }
|
|
@@ -113,19 +116,21 @@
|
|
|
113
116
|
resize();
|
|
114
117
|
}
|
|
115
118
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
// File types by extension, the same lists the WaveSpeed site uses to pick a preview.
|
|
120
|
+
var EXT = {
|
|
121
|
+
image: "jpg jpeg png gif webp avif bmp tiff tif svg ico",
|
|
122
|
+
video: "mp4 mov avi mkv webm flv wmv m4v",
|
|
123
|
+
audio: "mp3 wav m4a ogg aac flac wma aiff au mid midi rmi opus",
|
|
124
|
+
model: "glb gltf",
|
|
125
|
+
subtitle: "srt vtt",
|
|
126
|
+
};
|
|
121
127
|
function kindOf(url) {
|
|
122
128
|
var path = url.split("?")[0].split("#")[0].toLowerCase();
|
|
123
129
|
var ext = path.slice(path.lastIndexOf(".") + 1);
|
|
124
|
-
if (
|
|
125
|
-
if (/^(mp4|webm|mov|m4v)$/.test(ext)) return "video";
|
|
126
|
-
if (/^(mp3|wav|m4a|ogg|flac|aac)$/.test(ext)) return "audio";
|
|
130
|
+
for (var k in EXT) if ((" " + EXT[k] + " ").indexOf(" " + ext + " ") >= 0) return k;
|
|
127
131
|
return "file";
|
|
128
132
|
}
|
|
133
|
+
var KIND_LABEL = { model: "3D model", subtitle: "Subtitles", file: "File" };
|
|
129
134
|
function el(tag, cls, text) {
|
|
130
135
|
var n = document.createElement(tag);
|
|
131
136
|
if (cls) n.className = cls;
|
|
@@ -138,30 +143,74 @@
|
|
|
138
143
|
return b;
|
|
139
144
|
}
|
|
140
145
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
146
|
+
// Like the site: one thing plays at a time.
|
|
147
|
+
function onlyOnePlays(media) {
|
|
148
|
+
media.addEventListener("play", function () {
|
|
149
|
+
document.querySelectorAll("video, audio").forEach(function (m) { if (m !== media) m.pause(); });
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// A spinner stands in until the media has something to draw (the site does the same).
|
|
153
|
+
function withSpinner(t, media, readyEvent) {
|
|
154
|
+
var sp = el("div", "spin tile-spin");
|
|
155
|
+
t.appendChild(sp);
|
|
156
|
+
var done = function () { if (sp.parentNode) sp.parentNode.removeChild(sp); };
|
|
157
|
+
media.addEventListener(readyEvent, done);
|
|
158
|
+
media.addEventListener("error", done);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function brokenNote(t, media, what) {
|
|
162
|
+
// The host may not let the card load this address; say so and keep the Open button working.
|
|
163
|
+
media.addEventListener("error", function () {
|
|
164
|
+
if (media.parentNode !== t) return;
|
|
165
|
+
t.replaceChild(el("div", "broken", "This chat can't show the " + what + " here. Use Open / save."), media); resize();
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// One tile per output. Outputs are links to files, plain text, or JSON.
|
|
170
|
+
function tile(o) {
|
|
171
|
+
var t = el("div", "tile");
|
|
172
|
+
if (o !== null && typeof o === "object") {
|
|
173
|
+
var text = JSON.stringify(o, null, 2);
|
|
174
|
+
t.appendChild(el("pre", "code", text));
|
|
175
|
+
var jm = el("div", "meta"); jm.appendChild(el("span", "", "JSON"));
|
|
176
|
+
var cb = el("button", "", "Copy");
|
|
177
|
+
cb.addEventListener("click", function () {
|
|
178
|
+
try { navigator.clipboard.writeText(text).then(function () { cb.textContent = "Copied"; }, function () { cb.textContent = "Copy failed"; }); }
|
|
179
|
+
catch (e) { cb.textContent = "Copy failed"; }
|
|
180
|
+
});
|
|
181
|
+
jm.appendChild(cb); t.appendChild(jm);
|
|
182
|
+
return t;
|
|
183
|
+
}
|
|
184
|
+
var url = typeof o === "string" ? o : String(o);
|
|
185
|
+
if (!/^https?:\/\//i.test(url)) { t.appendChild(el("div", "text", url)); return t; }
|
|
186
|
+
var kind = kindOf(url), media;
|
|
144
187
|
if (kind === "image") {
|
|
145
188
|
media = el("img"); media.src = url; media.alt = "Generated image"; media.loading = "lazy";
|
|
146
189
|
media.addEventListener("click", function () { openLink(url); });
|
|
147
190
|
media.addEventListener("load", resize);
|
|
148
|
-
|
|
149
|
-
media.addEventListener("error", function () {
|
|
150
|
-
var m = el("div", "broken", "This chat can't show the image here. Use Open / save.");
|
|
151
|
-
t.replaceChild(m, media); resize();
|
|
152
|
-
});
|
|
191
|
+
brokenNote(t, media, "image");
|
|
153
192
|
t.appendChild(media);
|
|
193
|
+
withSpinner(t, media, "load");
|
|
154
194
|
} else if (kind === "video") {
|
|
155
|
-
|
|
195
|
+
// #t=0.001 makes the browser draw the first frame; without it iOS shows a black box until play.
|
|
196
|
+
media = el("video"); media.src = url + (url.indexOf("#") < 0 ? "#t=0.001" : ""); media.controls = true; media.playsInline = true; media.preload = "metadata"; media.loop = true;
|
|
156
197
|
media.addEventListener("loadedmetadata", resize);
|
|
198
|
+
onlyOnePlays(media);
|
|
199
|
+
brokenNote(t, media, "video");
|
|
157
200
|
t.appendChild(media);
|
|
201
|
+
withSpinner(t, media, "loadeddata");
|
|
158
202
|
} else if (kind === "audio") {
|
|
159
203
|
media = el("audio"); media.src = url; media.controls = true; media.preload = "metadata";
|
|
204
|
+
onlyOnePlays(media);
|
|
205
|
+
brokenNote(t, media, "audio");
|
|
160
206
|
t.appendChild(media);
|
|
207
|
+
} else {
|
|
208
|
+
// 3D models, subtitles, documents and other links cannot be drawn here: show the link.
|
|
209
|
+
t.appendChild(el("div", "text", url.split("?")[0].split("/").pop() || url));
|
|
161
210
|
}
|
|
162
|
-
var meta = el("div", "meta")
|
|
163
|
-
meta.appendChild(el("span", "", kind
|
|
164
|
-
meta.appendChild(openButton(url, kind === "file" ? "Open" : "Open / save"));
|
|
211
|
+
var meta = el("div", "meta");
|
|
212
|
+
meta.appendChild(el("span", "", KIND_LABEL[kind] || kind));
|
|
213
|
+
meta.appendChild(openButton(url, kind === "file" || kind === "model" || kind === "subtitle" ? "Open" : "Open / save"));
|
|
165
214
|
t.appendChild(meta);
|
|
166
215
|
return t;
|
|
167
216
|
}
|
|
@@ -191,10 +240,10 @@
|
|
|
191
240
|
body.appendChild(el("div", "err", String(d.error)));
|
|
192
241
|
setState("failed");
|
|
193
242
|
} else {
|
|
194
|
-
var
|
|
195
|
-
if (
|
|
196
|
-
var grid = el("div", "grid" + (
|
|
197
|
-
|
|
243
|
+
var outs = (d.outputs || []).filter(function (o) { return o !== null && o !== undefined && o !== ""; });
|
|
244
|
+
if (outs.length) {
|
|
245
|
+
var grid = el("div", "grid" + (outs.length === 1 ? " one" : ""));
|
|
246
|
+
outs.forEach(function (o) { grid.appendChild(tile(o)); });
|
|
198
247
|
body.appendChild(grid);
|
|
199
248
|
setState(d.status === "completed" || d.done ? "done" : (d.status || ""));
|
|
200
249
|
} else if (d.status && !d.done) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wavespeed/mcp",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "WaveSpeed MCP server — run any model on the live WaveSpeed catalog (image, video, audio, 3D) with schema introspection, local-file upload, and price quotes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|