@kolbo/mcp 1.75.3 → 1.75.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/tools/generate.js +56 -22
package/package.json
CHANGED
package/src/tools/generate.js
CHANGED
|
@@ -77,22 +77,35 @@ async function submitBatch(rawItems, submitOne) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// Blocking path for text-only hosts: wait for every batch member, aggregate.
|
|
80
|
-
|
|
80
|
+
// This is the exact path Kolbo Code takes for a `prompts`-array batch call
|
|
81
|
+
// (ui() is false there, so the uiGenerating branch above never runs) — it was
|
|
82
|
+
// text-only, no structuredContent, so a batch of N prompts rendered as a bare
|
|
83
|
+
// JSON dump instead of N cards. Same class of bug as get_generation_status's
|
|
84
|
+
// multi-id branch, same fix: always ship structuredContent via the shared
|
|
85
|
+
// kind:'status' grid, which already renders any mix of completed/processing
|
|
86
|
+
// items correctly.
|
|
87
|
+
async function pollBatch(client, batch, { interval, timeout }, toolName) {
|
|
81
88
|
const polls = await Promise.all(batch.ids.map((id) => pollOrTimedOut(client, id, { interval, timeout })));
|
|
82
89
|
const generations = polls.map((p, i) => p.timedOut
|
|
83
90
|
? { prompt: batch.ok[i].prompt, generation_id: batch.ids[i], status: 'processing', note: 'Still running — call get_generation_status with wait=true to collect it.' }
|
|
84
91
|
: { prompt: batch.ok[i].prompt, generation_id: batch.ids[i], status: 'completed', ...creditFields(polls[i].result), urls: p.result.result.urls });
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
92
|
+
const text = JSON.stringify({
|
|
93
|
+
batch: true,
|
|
94
|
+
session_id: batch.ok[0].gen.session_id,
|
|
95
|
+
generations,
|
|
96
|
+
failed_submissions: batch.failed.length ? batch.failed : undefined
|
|
97
|
+
}, null, 2);
|
|
98
|
+
return uiCompleted({
|
|
99
|
+
tool: toolName, kind: 'status', client,
|
|
100
|
+
model: 'Generations', gen: { generation_id: batch.ids[0], session_id: batch.ok[0].gen.session_id },
|
|
101
|
+
settings: {},
|
|
102
|
+
items: generations.map(g => ({
|
|
103
|
+
id: g.generation_id,
|
|
104
|
+
state: g.status,
|
|
105
|
+
title: g.prompt,
|
|
106
|
+
url: Array.isArray(g.urls) ? g.urls[0] : undefined,
|
|
107
|
+
})),
|
|
108
|
+
}, text);
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
// ─── Widget settings block ──────────────────────────────────────────────────
|
|
@@ -205,7 +218,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
205
218
|
status_args: { generation_ids: batch.ids, wait: true },
|
|
206
219
|
reference_images
|
|
207
220
|
});
|
|
208
|
-
return pollBatch(client, batch, { interval: (batch.ok[0].gen.poll_interval_hint || 3) * 1000, timeout: 240000 });
|
|
221
|
+
return pollBatch(client, batch, { interval: (batch.ok[0].gen.poll_interval_hint || 3) * 1000, timeout: 240000 }, 'generate_image');
|
|
209
222
|
}
|
|
210
223
|
|
|
211
224
|
const gen = await client.post('/v1/generate/image', { ...shared, prompt, num_images });
|
|
@@ -288,7 +301,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
288
301
|
status_args: { generation_ids: batch.ids, wait: true },
|
|
289
302
|
reference_images: source_images
|
|
290
303
|
});
|
|
291
|
-
return pollBatch(client, batch, { interval: (batch.ok[0].gen.poll_interval_hint || 3) * 1000, timeout: 240000 });
|
|
304
|
+
return pollBatch(client, batch, { interval: (batch.ok[0].gen.poll_interval_hint || 3) * 1000, timeout: 240000 }, 'generate_image_edit');
|
|
292
305
|
}
|
|
293
306
|
|
|
294
307
|
const gen = await client.post('/v1/generate/image-edit', { ...shared, prompt, num_images });
|
|
@@ -519,7 +532,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
519
532
|
status_args: { generation_ids: batch.ids, wait: true },
|
|
520
533
|
reference_images
|
|
521
534
|
});
|
|
522
|
-
return pollBatch(client, batch, { interval: (batch.ok[0].gen.poll_interval_hint || 8) * 1000, timeout: 900000 });
|
|
535
|
+
return pollBatch(client, batch, { interval: (batch.ok[0].gen.poll_interval_hint || 8) * 1000, timeout: 900000 }, 'generate_video');
|
|
523
536
|
}
|
|
524
537
|
|
|
525
538
|
const gen = await client.post('/v1/generate/video', { ...shared, prompt });
|
|
@@ -606,7 +619,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
606
619
|
status_args: { generation_ids: batch.ids, wait: true },
|
|
607
620
|
reference_images: items.map((item) => item.image_url)
|
|
608
621
|
});
|
|
609
|
-
return pollBatch(client, batch, { interval: (batch.ok[0].gen.poll_interval_hint || 8) * 1000, timeout: 900000 });
|
|
622
|
+
return pollBatch(client, batch, { interval: (batch.ok[0].gen.poll_interval_hint || 8) * 1000, timeout: 900000 }, 'generate_video_from_image');
|
|
610
623
|
}
|
|
611
624
|
|
|
612
625
|
const gen = await client.post('/v1/generate/video/from-image', { ...shared, image_url, prompt });
|
|
@@ -965,17 +978,38 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
965
978
|
: '';
|
|
966
979
|
const pendingHint = stillRunningHint(idsPhrase);
|
|
967
980
|
|
|
968
|
-
// Single-id calls keep the original flat shape —
|
|
969
|
-
//
|
|
970
|
-
// state/result at the
|
|
981
|
+
// Single-id calls keep the original flat TEXT shape — a live uiGenerating
|
|
982
|
+
// widget (ui()==true, still open from the original generate_* call) polls
|
|
983
|
+
// this tool directly from its own iframe JS and reads state/result at the
|
|
984
|
+
// top level, so `text` must stay exactly what it always was.
|
|
985
|
+
//
|
|
986
|
+
// But a single id checked here often has NO live widget behind it at all:
|
|
987
|
+
// Kolbo Code never opens one (ui() is false there), and even on hosts that
|
|
988
|
+
// do, the original call can have returned poll.timedOut before uiGenerating
|
|
989
|
+
// ever ran (see pollOrTimedOut) — a parallel batch is exactly when that
|
|
990
|
+
// happens, since every concurrent generation competes for the same
|
|
991
|
+
// per-call poll window. Either way this is then a FRESH, standalone tool
|
|
992
|
+
// response that needs its own renderable card, same reasoning as the
|
|
993
|
+
// multi-id fix just above. Reuse the same kind:'status' single-item grid
|
|
994
|
+
// rather than inventing per-media-type rendering here.
|
|
971
995
|
if (!generation_ids || generation_ids.length === 0) {
|
|
972
996
|
const single = results[0];
|
|
973
997
|
single._hint = pending.length === 0
|
|
974
998
|
? 'This generation is in a FINAL state — do not poll it again.'
|
|
975
999
|
: pendingHint;
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1000
|
+
const singleText = JSON.stringify(single, null, 2);
|
|
1001
|
+
const res = single.result || {};
|
|
1002
|
+
return uiCompleted({
|
|
1003
|
+
tool: 'get_generation_status', kind: 'status', client,
|
|
1004
|
+
model: 'Generations', gen: { generation_id: single.generation_id },
|
|
1005
|
+
settings: {},
|
|
1006
|
+
items: [{
|
|
1007
|
+
id: single.generation_id,
|
|
1008
|
+
state: single.state,
|
|
1009
|
+
title: res.prompt_used || res.prompt || undefined,
|
|
1010
|
+
url: Array.isArray(res.urls) ? res.urls[0] : undefined,
|
|
1011
|
+
}],
|
|
1012
|
+
}, singleText);
|
|
979
1013
|
}
|
|
980
1014
|
|
|
981
1015
|
const text = JSON.stringify({
|