@evolinkai/mcp 0.0.0-stage → 1.4.0
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/LICENSE +178 -0
- package/README.md +67 -2
- package/dist/core/src/branding.d.ts +3 -0
- package/dist/core/src/branding.d.ts.map +1 -0
- package/dist/core/src/branding.js +8 -0
- package/dist/core/src/branding.js.map +1 -0
- package/dist/core/src/config.d.ts +19 -0
- package/dist/core/src/config.d.ts.map +1 -0
- package/dist/core/src/config.js +90 -0
- package/dist/core/src/config.js.map +1 -0
- package/dist/core/src/data/model-params.d.ts +49 -0
- package/dist/core/src/data/model-params.d.ts.map +1 -0
- package/dist/core/src/data/model-params.generated.d.ts +2 -0
- package/dist/core/src/data/model-params.generated.d.ts.map +1 -0
- package/dist/core/src/data/model-params.generated.js +3 -0
- package/dist/core/src/data/model-params.generated.js.map +1 -0
- package/dist/core/src/data/model-params.js +22 -0
- package/dist/core/src/data/model-params.js.map +1 -0
- package/dist/core/src/request-context.d.ts +79 -0
- package/dist/core/src/request-context.d.ts.map +1 -0
- package/dist/core/src/request-context.js +52 -0
- package/dist/core/src/request-context.js.map +1 -0
- package/dist/core/src/server.d.ts +36 -0
- package/dist/core/src/server.d.ts.map +1 -0
- package/dist/core/src/server.js +123 -0
- package/dist/core/src/server.js.map +1 -0
- package/dist/core/src/services/api-client.d.ts +142 -0
- package/dist/core/src/services/api-client.d.ts.map +1 -0
- package/dist/core/src/services/api-client.js +179 -0
- package/dist/core/src/services/api-client.js.map +1 -0
- package/dist/core/src/services/error-handler.d.ts +51 -0
- package/dist/core/src/services/error-handler.d.ts.map +1 -0
- package/dist/core/src/services/error-handler.js +403 -0
- package/dist/core/src/services/error-handler.js.map +1 -0
- package/dist/core/src/services/file-client.d.ts +54 -0
- package/dist/core/src/services/file-client.d.ts.map +1 -0
- package/dist/core/src/services/file-client.js +131 -0
- package/dist/core/src/services/file-client.js.map +1 -0
- package/dist/core/src/services/http-policy.d.ts +40 -0
- package/dist/core/src/services/http-policy.d.ts.map +1 -0
- package/dist/core/src/services/http-policy.js +120 -0
- package/dist/core/src/services/http-policy.js.map +1 -0
- package/dist/core/src/services/media-preview.d.ts +24 -0
- package/dist/core/src/services/media-preview.d.ts.map +1 -0
- package/dist/core/src/services/media-preview.js +155 -0
- package/dist/core/src/services/media-preview.js.map +1 -0
- package/dist/core/src/services/model-catalog.d.ts +24 -0
- package/dist/core/src/services/model-catalog.d.ts.map +1 -0
- package/dist/core/src/services/model-catalog.js +45 -0
- package/dist/core/src/services/model-catalog.js.map +1 -0
- package/dist/core/src/services/param-validator.d.ts +21 -0
- package/dist/core/src/services/param-validator.d.ts.map +1 -0
- package/dist/core/src/services/param-validator.js +164 -0
- package/dist/core/src/services/param-validator.js.map +1 -0
- package/dist/core/src/services/preview-download.d.ts +11 -0
- package/dist/core/src/services/preview-download.d.ts.map +1 -0
- package/dist/core/src/services/preview-download.js +106 -0
- package/dist/core/src/services/preview-download.js.map +1 -0
- package/dist/core/src/services/pricing-client.d.ts +95 -0
- package/dist/core/src/services/pricing-client.d.ts.map +1 -0
- package/dist/core/src/services/pricing-client.js +396 -0
- package/dist/core/src/services/pricing-client.js.map +1 -0
- package/dist/core/src/services/upload-policy.d.ts +19 -0
- package/dist/core/src/services/upload-policy.d.ts.map +1 -0
- package/dist/core/src/services/upload-policy.js +168 -0
- package/dist/core/src/services/upload-policy.js.map +1 -0
- package/dist/core/src/services/upload-slots.d.ts +63 -0
- package/dist/core/src/services/upload-slots.d.ts.map +1 -0
- package/dist/core/src/services/upload-slots.js +24 -0
- package/dist/core/src/services/upload-slots.js.map +1 -0
- package/dist/core/src/services/utm.d.ts +29 -0
- package/dist/core/src/services/utm.d.ts.map +1 -0
- package/dist/core/src/services/utm.js +64 -0
- package/dist/core/src/services/utm.js.map +1 -0
- package/dist/core/src/tool-guidance.d.ts +6 -0
- package/dist/core/src/tool-guidance.d.ts.map +1 -0
- package/dist/core/src/tool-guidance.js +49 -0
- package/dist/core/src/tool-guidance.js.map +1 -0
- package/dist/core/src/tools/check-balance.d.ts +4 -0
- package/dist/core/src/tools/check-balance.d.ts.map +1 -0
- package/dist/core/src/tools/check-balance.js +82 -0
- package/dist/core/src/tools/check-balance.js.map +1 -0
- package/dist/core/src/tools/estimate-cost.d.ts +4 -0
- package/dist/core/src/tools/estimate-cost.d.ts.map +1 -0
- package/dist/core/src/tools/estimate-cost.js +131 -0
- package/dist/core/src/tools/estimate-cost.js.map +1 -0
- package/dist/core/src/tools/generate.d.ts +4 -0
- package/dist/core/src/tools/generate.d.ts.map +1 -0
- package/dist/core/src/tools/generate.js +221 -0
- package/dist/core/src/tools/generate.js.map +1 -0
- package/dist/core/src/tools/get-model.d.ts +5 -0
- package/dist/core/src/tools/get-model.d.ts.map +1 -0
- package/dist/core/src/tools/get-model.js +117 -0
- package/dist/core/src/tools/get-model.js.map +1 -0
- package/dist/core/src/tools/get-task.d.ts +7 -0
- package/dist/core/src/tools/get-task.d.ts.map +1 -0
- package/dist/core/src/tools/get-task.js +56 -0
- package/dist/core/src/tools/get-task.js.map +1 -0
- package/dist/core/src/tools/list-tasks.d.ts +6 -0
- package/dist/core/src/tools/list-tasks.d.ts.map +1 -0
- package/dist/core/src/tools/list-tasks.js +149 -0
- package/dist/core/src/tools/list-tasks.js.map +1 -0
- package/dist/core/src/tools/prepare-upload.d.ts +6 -0
- package/dist/core/src/tools/prepare-upload.d.ts.map +1 -0
- package/dist/core/src/tools/prepare-upload.js +134 -0
- package/dist/core/src/tools/prepare-upload.js.map +1 -0
- package/dist/core/src/tools/search-models.d.ts +5 -0
- package/dist/core/src/tools/search-models.d.ts.map +1 -0
- package/dist/core/src/tools/search-models.js +97 -0
- package/dist/core/src/tools/search-models.js.map +1 -0
- package/dist/core/src/tools/shared.d.ts +55 -0
- package/dist/core/src/tools/shared.d.ts.map +1 -0
- package/dist/core/src/tools/shared.js +137 -0
- package/dist/core/src/tools/shared.js.map +1 -0
- package/dist/core/src/tools/task-format.d.ts +48 -0
- package/dist/core/src/tools/task-format.d.ts.map +1 -0
- package/dist/core/src/tools/task-format.js +212 -0
- package/dist/core/src/tools/task-format.js.map +1 -0
- package/dist/core/src/tools/upload-file.d.ts +17 -0
- package/dist/core/src/tools/upload-file.d.ts.map +1 -0
- package/dist/core/src/tools/upload-file.js +134 -0
- package/dist/core/src/tools/upload-file.js.map +1 -0
- package/dist/core/src/version.d.ts +3 -0
- package/dist/core/src/version.d.ts.map +1 -0
- package/dist/core/src/version.js +3 -0
- package/dist/core/src/version.js.map +1 -0
- package/dist/evolink-media/src/index.d.ts +3 -0
- package/dist/evolink-media/src/index.d.ts.map +1 -0
- package/dist/evolink-media/src/index.js +18 -0
- package/dist/evolink-media/src/index.js.map +1 -0
- package/package.json +46 -4
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { submitTask } from '../services/api-client.js';
|
|
3
|
+
import { resolveModel, suggestModels } from '../services/model-catalog.js';
|
|
4
|
+
import { formatIssues, validateInput } from '../services/param-validator.js';
|
|
5
|
+
import { estimateCost, formatEstimateRange } from '../services/pricing-client.js';
|
|
6
|
+
import { CLIENT_REQUEST_ID_PATTERN, newRunId } from '../services/http-policy.js';
|
|
7
|
+
import { formatUsd } from '../services/error-handler.js';
|
|
8
|
+
import { MEDIA_SECONDS_DESCRIPTION, MEDIA_SECONDS_MAX, PAID, errorResult, failure, money, ok, progressReporter, usdOf } from './shared.js';
|
|
9
|
+
import { RESULT_DELIVERY_GUIDANCE, TERMINAL_STATUSES, describeTask, waitForTask } from './task-format.js';
|
|
10
|
+
import { PAID_GENERATION_GUIDANCE } from '../tool-guidance.js';
|
|
11
|
+
const PATHS = {
|
|
12
|
+
image: '/v1/images/generations',
|
|
13
|
+
video: '/v1/videos/generations',
|
|
14
|
+
audio: '/v1/audios/generations',
|
|
15
|
+
};
|
|
16
|
+
/** Images usually finish in seconds, so the tool waits for them; video and audio return the task at once. */
|
|
17
|
+
const WAIT_MS = { image: 40_000, video: 0, audio: 0 };
|
|
18
|
+
const DESCRIPTIONS = {
|
|
19
|
+
image: 'Generate or edit images with an EvoLink image model. PAID: charges the user\'s EvoLink balance.',
|
|
20
|
+
video: 'Generate a video with an EvoLink video model (text-to-video, image-to-video, reference, edit, extend). PAID: charges the user\'s EvoLink balance.',
|
|
21
|
+
audio: 'Generate music, songs or speech with an EvoLink audio model. PAID: charges the user\'s EvoLink balance.',
|
|
22
|
+
};
|
|
23
|
+
const AFTER = {
|
|
24
|
+
image: 'Waits up to 40 s and returns the image links when ready; otherwise returns the task_id for get_task.',
|
|
25
|
+
video: 'Returns a task_id at once (videos take minutes); then call get_task, which can wait up to 45 s per call.',
|
|
26
|
+
audio: 'Returns a task_id at once; then call get_task, which can wait up to 45 s per call.',
|
|
27
|
+
};
|
|
28
|
+
function description(kind) {
|
|
29
|
+
return [
|
|
30
|
+
DESCRIPTIONS[kind],
|
|
31
|
+
PAID_GENERATION_GUIDANCE,
|
|
32
|
+
'Find models with search_models and their parameters with get_model; pass the parameters in input.',
|
|
33
|
+
AFTER[kind],
|
|
34
|
+
'Never call this again to check progress or to "retry" a running task: each call creates and charges a new task.',
|
|
35
|
+
'After a network error or timeout, reuse the same client_request_id to retry without being charged twice.',
|
|
36
|
+
RESULT_DELIVERY_GUIDANCE,
|
|
37
|
+
].join(' ');
|
|
38
|
+
}
|
|
39
|
+
/** Longest prompt accepted through the prompt shortcut. */
|
|
40
|
+
const PROMPT_SHORTCUT_MAX = 20_000;
|
|
41
|
+
function rangeText(estimate) {
|
|
42
|
+
return formatEstimateRange(estimate) ?? 'unknown';
|
|
43
|
+
}
|
|
44
|
+
/** Why max_cost_usd could not be checked, and what the assistant can do next. */
|
|
45
|
+
function uncheckedCap(estimate, pricingWarning) {
|
|
46
|
+
if (estimate.uncheckable_reason === 'reference_video') {
|
|
47
|
+
return [
|
|
48
|
+
'this per-second video request uses input.video_urls, input.video_url or input.source_task_id, and published prices do not fully cover input video seconds or video-dependent billing multipliers',
|
|
49
|
+
'media_seconds cannot resolve this billing gap. Ask the user whether to proceed without a cap.',
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
if (estimate.status === 'token_billed') {
|
|
53
|
+
return ['it is billed by tokens used, so its cost is only known afterwards', 'Ask the user whether to proceed without a cap.'];
|
|
54
|
+
}
|
|
55
|
+
if (estimate.missing === 'media_seconds') {
|
|
56
|
+
return [
|
|
57
|
+
'it is billed per second and has no duration parameter, so EvoLink measures the seconds when the task runs (usually the length of the input video or audio)',
|
|
58
|
+
'If you know that length, pass it as media_seconds; otherwise ask the user whether to proceed without a cap.',
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
if (estimate.missing === 'duration') {
|
|
62
|
+
return ['it is billed per second and input.duration is not set', 'Set input.duration, or ask the user whether to proceed without a cap.'];
|
|
63
|
+
}
|
|
64
|
+
// Notes end with a full stop; the sentence around the reason adds its own.
|
|
65
|
+
const note = estimate.notes[0] ?? pricingWarning ?? 'no price could be found for it';
|
|
66
|
+
return [note.replace(/[.\s]+$/, ''), 'Ask the user whether to proceed without a cap.'];
|
|
67
|
+
}
|
|
68
|
+
export function registerGenerateTools(server, config) {
|
|
69
|
+
for (const kind of ['image', 'video', 'audio'])
|
|
70
|
+
registerGenerate(server, config, kind);
|
|
71
|
+
}
|
|
72
|
+
function registerGenerate(server, config, kind) {
|
|
73
|
+
const name = `generate_${kind}`;
|
|
74
|
+
const title = `Generate ${kind} (paid)`;
|
|
75
|
+
server.registerTool(name, {
|
|
76
|
+
title,
|
|
77
|
+
description: description(kind),
|
|
78
|
+
inputSchema: {
|
|
79
|
+
model: z.string().min(1).max(128).describe(`${kind[0].toUpperCase()}${kind.slice(1)} model ID from search_models.`),
|
|
80
|
+
// The cap is checked in the handler: a schema limit makes the SDK answer with a bare validation error.
|
|
81
|
+
prompt: z.string().optional().describe(`Shortcut for input.prompt; up to ${PROMPT_SHORTCUT_MAX.toLocaleString('en-US')} characters (get_model lists the model's own limit).`),
|
|
82
|
+
input: z.record(z.unknown()).optional()
|
|
83
|
+
.describe('Model parameters exactly as listed by get_model, e.g. {"prompt":"…","quality":"1080p"}. Do not put model or callback_url here.'),
|
|
84
|
+
client_request_id: z.string().regex(CLIENT_REQUEST_ID_PATTERN).optional()
|
|
85
|
+
.describe('Optional idempotency key (16–96 characters: letters, digits, . _ -). Reuse the same value only to retry the same request after a network error or timeout.'),
|
|
86
|
+
max_cost_usd: z.number().positive().max(10_000).optional()
|
|
87
|
+
.describe('Optional estimate-based spending cap: refuses to submit when the estimate is higher or cannot cover the full request. Per-second video requests with video_urls, video_url or source_task_id cannot use this cap, even with media_seconds.'),
|
|
88
|
+
media_seconds: z.number().positive().max(MEDIA_SECONDS_MAX).optional().describe(MEDIA_SECONDS_DESCRIPTION),
|
|
89
|
+
},
|
|
90
|
+
annotations: { title, ...PAID },
|
|
91
|
+
}, async (args, extra) => {
|
|
92
|
+
const started = Date.now();
|
|
93
|
+
const input = { ...(args.input ?? {}) };
|
|
94
|
+
if (args.prompt !== undefined) {
|
|
95
|
+
if (input.prompt !== undefined && input.prompt !== args.prompt) {
|
|
96
|
+
return failure('prompt was given twice with different values (prompt and input.prompt). Pass it once. Nothing was submitted or charged.', {
|
|
97
|
+
error: { category: 'invalid_request', param: 'prompt' },
|
|
98
|
+
charged: 'no',
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (args.prompt.length > PROMPT_SHORTCUT_MAX) {
|
|
102
|
+
return failure(`The prompt is ${args.prompt.length.toLocaleString('en-US')} characters; the limit is ${PROMPT_SHORTCUT_MAX.toLocaleString('en-US')}. Shorten it and try again. Nothing was submitted or charged.`, {
|
|
103
|
+
error: { category: 'invalid_request', param: 'prompt' },
|
|
104
|
+
charged: 'no',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
input.prompt = args.prompt;
|
|
108
|
+
}
|
|
109
|
+
let clientRequestId;
|
|
110
|
+
try {
|
|
111
|
+
const { catalog, entry } = await resolveModel(args.model);
|
|
112
|
+
if (!entry) {
|
|
113
|
+
const suggestions = suggestModels(catalog, args.model, kind);
|
|
114
|
+
return failure(`Unknown ${kind} model "${args.model}".${suggestions.length ? ` Did you mean: ${suggestions.join(', ')}?` : ''} Use search_models to find model IDs. Nothing was submitted or charged.`, { error: { category: 'not_found', param: 'model' }, suggestions, charged: 'no' });
|
|
115
|
+
}
|
|
116
|
+
if (entry.kind !== kind) {
|
|
117
|
+
return failure(`${entry.id} is ${entry.kind === 'video' ? 'a' : 'an'} ${entry.kind} model; use generate_${entry.kind}. Nothing was submitted or charged.`, {
|
|
118
|
+
error: { category: 'invalid_request', param: 'model' },
|
|
119
|
+
use_tool: `generate_${entry.kind}`,
|
|
120
|
+
charged: 'no',
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const warnings = [];
|
|
124
|
+
if (entry.spec) {
|
|
125
|
+
const validation = validateInput(entry.spec, input);
|
|
126
|
+
if (validation.errors.length > 0) {
|
|
127
|
+
return failure([
|
|
128
|
+
`The input for ${entry.id} has problems; nothing was submitted or charged:`,
|
|
129
|
+
...formatIssues(validation.errors),
|
|
130
|
+
'get_model lists every parameter with its allowed values.',
|
|
131
|
+
].join('\n'), { error: { category: 'invalid_request' }, problems: validation.errors, charged: 'no' });
|
|
132
|
+
}
|
|
133
|
+
warnings.push(...validation.warnings.map(issue => `${issue.param} ${issue.problem}`));
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
warnings.push('This model\'s parameters are not documented here, so the input was not checked before sending.');
|
|
137
|
+
}
|
|
138
|
+
// media_seconds only prices the request; the body below is built from input alone.
|
|
139
|
+
const estimate = estimateCost(entry.priced, kind, input, entry.spec, { mediaSeconds: args.media_seconds });
|
|
140
|
+
if (args.max_cost_usd !== undefined) {
|
|
141
|
+
if (estimate.uncheckable_reason !== undefined || estimate.status !== 'estimated' || estimate.max_usd === undefined) {
|
|
142
|
+
const [reason, next] = uncheckedCap(estimate, catalog.pricingWarning);
|
|
143
|
+
return failure(`max_cost_usd cannot be checked for ${entry.id}: ${reason}. Nothing was submitted or charged. ${next}`, {
|
|
144
|
+
error: { category: 'invalid_request', param: 'max_cost_usd' },
|
|
145
|
+
estimate,
|
|
146
|
+
charged: 'no',
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (estimate.max_usd > args.max_cost_usd) {
|
|
150
|
+
return failure(`The estimated cost ${rangeText(estimate)} is above max_cost_usd $${formatUsd(args.max_cost_usd)}. Nothing was submitted or charged. Lower the duration, count or quality, or ask the user to raise the cap.`, {
|
|
151
|
+
error: { category: 'invalid_request', param: 'max_cost_usd' },
|
|
152
|
+
estimate,
|
|
153
|
+
charged: 'no',
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
clientRequestId = args.client_request_id ?? newRunId();
|
|
158
|
+
const body = { ...input, model: entry.id };
|
|
159
|
+
const submitted = await submitTask(config, {
|
|
160
|
+
path: entry.spec?.path ?? PATHS[kind],
|
|
161
|
+
body,
|
|
162
|
+
tool: name,
|
|
163
|
+
idempotencyKey: clientRequestId,
|
|
164
|
+
});
|
|
165
|
+
let task = submitted;
|
|
166
|
+
const waitUntil = started + WAIT_MS[kind];
|
|
167
|
+
if (!TERMINAL_STATUSES.has(task.status) && WAIT_MS[kind] > 0 && Date.now() + 3_000 < waitUntil) {
|
|
168
|
+
const report = progressReporter(extra, WAIT_MS[kind] / 1000);
|
|
169
|
+
try {
|
|
170
|
+
task = await waitForTask(config, submitted.id, {
|
|
171
|
+
deadline: waitUntil,
|
|
172
|
+
tool: name,
|
|
173
|
+
signal: extra.signal,
|
|
174
|
+
onPoll: current => report((Date.now() - started) / 1000, `${current.status}, ${current.progress ?? 0}%`),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// The task exists; a failed status read must not turn a successful submit into an error.
|
|
179
|
+
task = submitted;
|
|
180
|
+
}
|
|
181
|
+
task.usage = { ...submitted.usage, ...task.usage };
|
|
182
|
+
}
|
|
183
|
+
const view = describeTask({ ...task, request_id: task.request_id ?? submitted.request_id });
|
|
184
|
+
const header = submitted.idempotency_replayed
|
|
185
|
+
? `This client_request_id was used before: returning the original task (no new charge).`
|
|
186
|
+
: `Submitted ${entry.id}.`;
|
|
187
|
+
const lines = [header, ...view.lines];
|
|
188
|
+
const reserved = submitted.usage?.credits_reserved;
|
|
189
|
+
if (typeof reserved === 'number' && reserved > 0 && !lines.some(line => line.startsWith('Reserved:')) && task.status !== 'completed') {
|
|
190
|
+
lines.push(`Reserved: ${money(reserved)}`);
|
|
191
|
+
}
|
|
192
|
+
if (estimate.status === 'estimated')
|
|
193
|
+
lines.push(`Estimate before submitting: ${rangeText(estimate)}`);
|
|
194
|
+
if (estimate.status === 'partial') {
|
|
195
|
+
lines.push(`Partial estimate at published rates: ${rangeText(estimate)} (not a total or an upper bound).`);
|
|
196
|
+
for (const extra of estimate.possible_extras)
|
|
197
|
+
lines.push(`May also charge: ${extra}`);
|
|
198
|
+
for (const note of estimate.notes)
|
|
199
|
+
lines.push(`Note: ${note}`);
|
|
200
|
+
}
|
|
201
|
+
for (const warning of warnings)
|
|
202
|
+
lines.push(`Warning: ${warning}`);
|
|
203
|
+
lines.push(`client_request_id: ${clientRequestId}`);
|
|
204
|
+
return ok(lines.join('\n'), {
|
|
205
|
+
...view.structured,
|
|
206
|
+
submitted: { model: entry.id, input },
|
|
207
|
+
client_request_id: clientRequestId,
|
|
208
|
+
replayed: submitted.idempotency_replayed === true,
|
|
209
|
+
...(typeof reserved === 'number' ? { reserved_credits: reserved, reserved_usd: usdOf(reserved) } : {}),
|
|
210
|
+
...(estimate.status === 'estimated' ? { estimate: { min_usd: estimate.min_usd, max_usd: estimate.max_usd } } : {}),
|
|
211
|
+
...(estimate.status === 'partial' ? { estimate } : {}),
|
|
212
|
+
...(warnings.length ? { warnings } : {}),
|
|
213
|
+
}, view.resources);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
// clientRequestId is set right before the submit, so it also tells whether a request may have gone out.
|
|
217
|
+
return errorResult(error, { paid: clientRequestId !== undefined, clientRequestId });
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../../../core/src/tools/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { type ParamSpec } from '../data/model-params.js';
|
|
3
|
+
export declare function describeParam(name: string, spec: ParamSpec, indent?: string): string[];
|
|
4
|
+
export declare function registerGetModel(server: McpServer): void;
|
|
5
|
+
//# sourceMappingURL=get-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-model.d.ts","sourceRoot":"","sources":["../../../../../core/src/tools/get-model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAY1E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAK,GAAG,MAAM,EAAE,CAelF;AAQD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyExD"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { modelParamsMeta } from '../data/model-params.js';
|
|
3
|
+
import { resolveModel, suggestModels } from '../services/model-catalog.js';
|
|
4
|
+
import { billedByMediaLength, formatPrice } from '../services/pricing-client.js';
|
|
5
|
+
import { formatUsd } from '../services/error-handler.js';
|
|
6
|
+
import { trackedLink } from '../services/utm.js';
|
|
7
|
+
import { READ_ONLY, errorResult, failure, ok } from './shared.js';
|
|
8
|
+
import { modelTitle } from './search-models.js';
|
|
9
|
+
function value(v) {
|
|
10
|
+
return JSON.stringify(v);
|
|
11
|
+
}
|
|
12
|
+
export function describeParam(name, spec, indent = '') {
|
|
13
|
+
const facts = [spec.type, spec.required ? 'required' : undefined].filter(Boolean);
|
|
14
|
+
const details = [];
|
|
15
|
+
if (spec.enum?.length)
|
|
16
|
+
details.push(`one of ${spec.enum.map(value).join(', ')}`);
|
|
17
|
+
if (spec.default !== undefined)
|
|
18
|
+
details.push(`default ${value(spec.default)}`);
|
|
19
|
+
if (spec.minimum !== undefined || spec.maximum !== undefined)
|
|
20
|
+
details.push(`range ${spec.minimum ?? '…'}–${spec.maximum ?? '…'}`);
|
|
21
|
+
if (spec.minItems !== undefined || spec.maxItems !== undefined)
|
|
22
|
+
details.push(`${spec.minItems ?? 0}–${spec.maxItems ?? '…'} items`);
|
|
23
|
+
if (spec.maxLength !== undefined)
|
|
24
|
+
details.push(`up to ${spec.maxLength} characters`);
|
|
25
|
+
if (spec.items?.enum?.length)
|
|
26
|
+
details.push(`each one of ${spec.items.enum.map(value).join(', ')}`);
|
|
27
|
+
const head = `${indent}- ${name}${facts.length ? ` (${facts.join(', ')})` : ''}${details.length ? `: ${details.join('; ')}` : ''}`;
|
|
28
|
+
const lines = [spec.description ? `${head} — ${spec.description}` : head];
|
|
29
|
+
for (const [child, childSpec] of Object.entries(spec.properties ?? spec.items?.properties ?? {})) {
|
|
30
|
+
lines.push(...describeParam(child, childSpec, `${indent} `));
|
|
31
|
+
}
|
|
32
|
+
return lines;
|
|
33
|
+
}
|
|
34
|
+
function priceLine(price) {
|
|
35
|
+
const minimum = price.min_charge_usd !== undefined ? ` (minimum $${formatUsd(price.min_charge_usd)} per task)` : '';
|
|
36
|
+
const factors = price.multipliers ? ` (resolution factors ${Object.entries(price.multipliers).map(([k, v]) => `${k} ×${v}`).join(', ')})` : '';
|
|
37
|
+
return `${price.name}: ${formatPrice(price)}${minimum}${factors}`;
|
|
38
|
+
}
|
|
39
|
+
export function registerGetModel(server) {
|
|
40
|
+
server.registerTool('get_model', {
|
|
41
|
+
title: 'Get model parameters and pricing',
|
|
42
|
+
description: [
|
|
43
|
+
'Show what one model accepts and what it costs: every input parameter (required, allowed values, ranges, defaults), the published prices and an example input. Free.',
|
|
44
|
+
'Read this before calling generate_image, generate_video or generate_audio, and quote the price to the user.',
|
|
45
|
+
].join(' '),
|
|
46
|
+
inputSchema: {
|
|
47
|
+
model: z.string().min(1).max(128).describe('Model ID from search_models, e.g. "seedance-2.0-text-to-video".'),
|
|
48
|
+
},
|
|
49
|
+
annotations: { title: 'Get model parameters and pricing', ...READ_ONLY },
|
|
50
|
+
}, async ({ model }) => {
|
|
51
|
+
try {
|
|
52
|
+
const { catalog, entry } = await resolveModel(model);
|
|
53
|
+
if (!entry) {
|
|
54
|
+
const suggestions = suggestModels(catalog, model);
|
|
55
|
+
return failure(`Unknown model "${model}".${suggestions.length ? ` Did you mean: ${suggestions.join(', ')}?` : ''} Use search_models to find model IDs.`, { error: { category: 'not_found', param: 'model' }, suggestions });
|
|
56
|
+
}
|
|
57
|
+
const { spec, priced } = entry;
|
|
58
|
+
const title = modelTitle(entry);
|
|
59
|
+
const lines = [`${entry.id} (${entry.kind})${title ? ` — ${title}` : ''}`, `Generate with: generate_${entry.kind}`];
|
|
60
|
+
const structured = {
|
|
61
|
+
model: entry.id,
|
|
62
|
+
type: entry.kind,
|
|
63
|
+
tool: `generate_${entry.kind}`,
|
|
64
|
+
};
|
|
65
|
+
if (spec) {
|
|
66
|
+
const docs = trackedLink(spec.docs, 'model_docs');
|
|
67
|
+
lines.push(`Docs: ${docs}`, '', 'Input parameters (pass them in input):');
|
|
68
|
+
const names = Object.keys(spec.params).sort((a, b) => Number(!!spec.params[b].required) - Number(!!spec.params[a].required));
|
|
69
|
+
for (const name of names)
|
|
70
|
+
lines.push(...describeParam(name, spec.params[name]));
|
|
71
|
+
if (spec.example)
|
|
72
|
+
lines.push('', `Example input: ${JSON.stringify(spec.example)}`);
|
|
73
|
+
Object.assign(structured, {
|
|
74
|
+
endpoint: spec.path,
|
|
75
|
+
docs,
|
|
76
|
+
required: spec.required,
|
|
77
|
+
parameters: spec.params,
|
|
78
|
+
example_input: spec.example,
|
|
79
|
+
parameters_source: modelParamsMeta(),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
lines.push('', 'Parameters for this model are not documented here; the gateway checks the input when you submit.');
|
|
84
|
+
}
|
|
85
|
+
lines.push('', 'Pricing (USD; 68 credits ≈ $1):');
|
|
86
|
+
if (priced && priced.prices.length > 0) {
|
|
87
|
+
const groups = [['output', 'Main charge'], ['add_on', 'Extra charges'], ['token', 'Usage-based']];
|
|
88
|
+
for (const [role, label] of groups) {
|
|
89
|
+
const prices = priced.prices.filter(price => price.role === role);
|
|
90
|
+
if (prices.length === 0)
|
|
91
|
+
continue;
|
|
92
|
+
lines.push(`${label}:`);
|
|
93
|
+
for (const price of prices)
|
|
94
|
+
lines.push(`- ${priceLine(price)}`);
|
|
95
|
+
}
|
|
96
|
+
if (billedByMediaLength(priced, spec)) {
|
|
97
|
+
lines.push('This model has no duration parameter: EvoLink measures the billed seconds when the task runs (usually the length of the input video or audio). For an estimate before generating, pass that length as media_seconds to estimate_cost.');
|
|
98
|
+
structured.billed_by_media_length = true;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
lines.push('Use estimate_cost with your input for a total before generating.');
|
|
102
|
+
}
|
|
103
|
+
structured.prices = priced.prices;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
lines.push(catalog.pricingWarning ?? 'No price is published for this model.');
|
|
107
|
+
}
|
|
108
|
+
if (catalog.pricingWarning)
|
|
109
|
+
structured.pricing_warning = catalog.pricingWarning;
|
|
110
|
+
return ok(lines.join('\n'), structured);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return errorResult(error);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=get-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-model.js","sourceRoot":"","sources":["../../../../../core/src/tools/get-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ServerConfig } from '../config.js';
|
|
3
|
+
export declare const TASK_ID: RegExp;
|
|
4
|
+
/** Codex and Cursor drop a tool call after about 60 s; the reply also needs time to travel. */
|
|
5
|
+
export declare const MAX_WAIT_SECONDS = 45;
|
|
6
|
+
export declare function registerGetTask(server: McpServer, config: ServerConfig): void;
|
|
7
|
+
//# sourceMappingURL=get-task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-task.d.ts","sourceRoot":"","sources":["../../../../../core/src/tools/get-task.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAIjD,eAAO,MAAM,OAAO,QAA6B,CAAC;AAClD,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAInC,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA4C7E"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { READ_ONLY, errorResult, ok, progressReporter } from './shared.js';
|
|
3
|
+
import { RESULT_DELIVERY_GUIDANCE, TERMINAL_STATUSES, describeTask, waitForTask } from './task-format.js';
|
|
4
|
+
export const TASK_ID = /^[A-Za-z0-9._:-]{4,128}$/;
|
|
5
|
+
/** Codex and Cursor drop a tool call after about 60 s; the reply also needs time to travel. */
|
|
6
|
+
export const MAX_WAIT_SECONDS = 45;
|
|
7
|
+
const REPLY_MARGIN_MS = 2_000;
|
|
8
|
+
const PROGRESS_EVERY_SECONDS = 10;
|
|
9
|
+
export function registerGetTask(server, config) {
|
|
10
|
+
server.registerTool('get_task', {
|
|
11
|
+
title: 'Get task status and results',
|
|
12
|
+
description: [
|
|
13
|
+
'Check one generation task and, while it is still running, wait up to wait_seconds (max 45) for it to finish. Free.',
|
|
14
|
+
'Returns the status, progress, result links (they expire after 24 hours, so give them to the user right away), the final charge, or the error with a next step.',
|
|
15
|
+
'If the task is still running when this returns, call get_task again.',
|
|
16
|
+
'Never call generate_image, generate_video or generate_audio again to check progress: that creates and charges a new task.',
|
|
17
|
+
RESULT_DELIVERY_GUIDANCE,
|
|
18
|
+
].join(' '),
|
|
19
|
+
inputSchema: {
|
|
20
|
+
task_id: z.string().regex(TASK_ID).describe('task_id returned by generate_image, generate_video or generate_audio'),
|
|
21
|
+
wait_seconds: z.number().int().min(0).max(MAX_WAIT_SECONDS).default(30)
|
|
22
|
+
.describe('How long this call may wait for the task to finish (0–45 s, default 30). Use 0 for a quick check.'),
|
|
23
|
+
},
|
|
24
|
+
annotations: { title: 'Get task status and results', ...READ_ONLY },
|
|
25
|
+
}, async ({ task_id, wait_seconds }, extra) => {
|
|
26
|
+
const started = Date.now();
|
|
27
|
+
const waitSeconds = Math.min(wait_seconds ?? 30, MAX_WAIT_SECONDS);
|
|
28
|
+
const report = progressReporter(extra, waitSeconds);
|
|
29
|
+
let lastReport = -PROGRESS_EVERY_SECONDS;
|
|
30
|
+
try {
|
|
31
|
+
const task = await waitForTask(config, task_id, {
|
|
32
|
+
deadline: started + waitSeconds * 1000 - REPLY_MARGIN_MS,
|
|
33
|
+
tool: 'get_task',
|
|
34
|
+
signal: extra.signal,
|
|
35
|
+
onPoll: async (current) => {
|
|
36
|
+
const elapsed = (Date.now() - started) / 1000;
|
|
37
|
+
if (elapsed - lastReport < PROGRESS_EVERY_SECONDS)
|
|
38
|
+
return;
|
|
39
|
+
lastReport = elapsed;
|
|
40
|
+
await report(elapsed, `${current.status}, ${current.progress ?? 0}%`);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
const view = describeTask(task);
|
|
44
|
+
if (!TERMINAL_STATUSES.has(task.status) && waitSeconds > 0) {
|
|
45
|
+
const waited = Math.round((Date.now() - started) / 1000);
|
|
46
|
+
view.lines.splice(1, 0, `Still running after waiting ${waited} s.`);
|
|
47
|
+
view.structured.waited_seconds = waited;
|
|
48
|
+
}
|
|
49
|
+
return ok(view.lines.join('\n'), view.structured, view.resources);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return errorResult(error);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=get-task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-task.js","sourceRoot":"","sources":["../../../../../core/src/tools/get-task.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ServerConfig } from '../config.js';
|
|
3
|
+
/** ISO 8601, unix seconds, or relative such as 30m, 2h, 1d. */
|
|
4
|
+
export declare function parseSince(value: string, now?: number): number | undefined;
|
|
5
|
+
export declare function registerListTasks(server: McpServer, config: ServerConfig): void;
|
|
6
|
+
//# sourceMappingURL=list-tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-tasks.d.ts","sourceRoot":"","sources":["../../../../../core/src/tools/list-tasks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAQjD,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,MAAM,GAAG,SAAS,CAY9E;AAyCD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAsF/E"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { listTasks, queryTasks } from '../services/api-client.js';
|
|
3
|
+
import { READ_ONLY, errorResult, failure, money, ok, usdOf } from './shared.js';
|
|
4
|
+
import { TASK_ID } from './get-task.js';
|
|
5
|
+
import { RESULT_DELIVERY_GUIDANCE, RESULT_DELIVERY_INSTRUCTIONS, RESULT_LINK_HOURS, resultDeliveryMarkdown, resultLinks, resultResources } from './task-format.js';
|
|
6
|
+
const MAX_IDS = 50;
|
|
7
|
+
/** ISO 8601, unix seconds, or relative such as 30m, 2h, 1d. */
|
|
8
|
+
export function parseSince(value, now = Date.now()) {
|
|
9
|
+
const trimmed = value.trim();
|
|
10
|
+
const relative = /^(\d+)\s*(m|min|mins|minutes?|h|hours?|d|days?)$/i.exec(trimmed);
|
|
11
|
+
if (relative) {
|
|
12
|
+
const amount = Number(relative[1]);
|
|
13
|
+
const unit = relative[2][0].toLowerCase();
|
|
14
|
+
const factor = unit === 'm' ? 60_000 : unit === 'h' ? 3_600_000 : 86_400_000;
|
|
15
|
+
return now - amount * factor;
|
|
16
|
+
}
|
|
17
|
+
if (/^\d{9,11}$/.test(trimmed))
|
|
18
|
+
return Number(trimmed) * 1000;
|
|
19
|
+
const parsed = Date.parse(trimmed);
|
|
20
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
21
|
+
}
|
|
22
|
+
function rowFromTask(task) {
|
|
23
|
+
const row = { task_id: task.id, status: task.status, model: task.model, type: task.type, progress: task.progress };
|
|
24
|
+
if (task.created)
|
|
25
|
+
row.created_at = new Date(task.created * 1000).toISOString();
|
|
26
|
+
const links = resultLinks(task);
|
|
27
|
+
if (links.length > 0)
|
|
28
|
+
row.results = links;
|
|
29
|
+
if (task.status === 'completed' && links.length > 0)
|
|
30
|
+
row.delivery_markdown = resultDeliveryMarkdown(task.id, links);
|
|
31
|
+
const used = task.usage?.credits_used ?? task.usage?.cost?.credits;
|
|
32
|
+
if (task.status === 'completed' && typeof used === 'number') {
|
|
33
|
+
row.charged_credits = used;
|
|
34
|
+
row.charged_usd = task.usage?.cost?.usd ?? usdOf(used);
|
|
35
|
+
}
|
|
36
|
+
if (task.error?.code)
|
|
37
|
+
row.error_code = task.error.code;
|
|
38
|
+
return row;
|
|
39
|
+
}
|
|
40
|
+
function rowLine(row) {
|
|
41
|
+
const parts = [`- ${row.task_id}`, row.status === 'completed' || row.status === 'failed' ? row.status : `${row.status} ${row.progress ?? 0}%`, row.model];
|
|
42
|
+
if (row.created_at)
|
|
43
|
+
parts.push(row.created_at);
|
|
44
|
+
if (row.charged_credits !== undefined)
|
|
45
|
+
parts.push(`charged ${money(row.charged_credits)}`);
|
|
46
|
+
if (row.error_code)
|
|
47
|
+
parts.push(`error ${row.error_code}`);
|
|
48
|
+
const lines = [parts.join(' · ')];
|
|
49
|
+
for (const link of row.results ?? [])
|
|
50
|
+
lines.push(` ${link.kind}: ${link.url}`);
|
|
51
|
+
return lines.join('\n');
|
|
52
|
+
}
|
|
53
|
+
export function registerListTasks(server, config) {
|
|
54
|
+
server.registerTool('list_tasks', {
|
|
55
|
+
title: 'List generation tasks',
|
|
56
|
+
description: [
|
|
57
|
+
'Read several tasks at once by task_ids (up to 50, with result links), or find recent tasks by status, type and since. Free.',
|
|
58
|
+
'Use it to recover tasks after a lost connection or a timed-out submit before submitting anything again.',
|
|
59
|
+
'Recent tasks cover the whole EvoLink account, newest first.',
|
|
60
|
+
RESULT_DELIVERY_GUIDANCE,
|
|
61
|
+
].join(' '),
|
|
62
|
+
inputSchema: {
|
|
63
|
+
task_ids: z.array(z.string().regex(TASK_ID)).min(1).max(MAX_IDS).optional()
|
|
64
|
+
.describe('Task IDs to read in one call (max 50).'),
|
|
65
|
+
status: z.enum(['processing', 'completed', 'failed', 'cancelled']).optional()
|
|
66
|
+
.describe('Without task_ids: only tasks in this state ("processing" includes queued tasks).'),
|
|
67
|
+
type: z.enum(['image', 'video', 'audio']).optional()
|
|
68
|
+
.describe('Without task_ids: only this kind of task.'),
|
|
69
|
+
since: z.string().max(40).optional()
|
|
70
|
+
.describe('Without task_ids: only tasks created after this time, as ISO 8601 (2026-10-05T08:00:00Z) or relative (30m, 2h, 1d).'),
|
|
71
|
+
limit: z.number().int().min(1).max(MAX_IDS).default(20)
|
|
72
|
+
.describe('Without task_ids: how many recent tasks to return (1–50, default 20).'),
|
|
73
|
+
},
|
|
74
|
+
annotations: { title: 'List generation tasks', ...READ_ONLY },
|
|
75
|
+
}, async ({ task_ids, status, type, since, limit }) => {
|
|
76
|
+
try {
|
|
77
|
+
if (task_ids && task_ids.length > 0) {
|
|
78
|
+
const unique = [...new Set(task_ids)];
|
|
79
|
+
const tasks = await queryTasks(config, unique);
|
|
80
|
+
const rows = tasks.map(rowFromTask);
|
|
81
|
+
const found = new Set(rows.map(row => row.task_id));
|
|
82
|
+
const missing = unique.filter(id => !found.has(id));
|
|
83
|
+
const lines = [`${rows.length} of ${unique.length} tasks found.`, ...rows.map(rowLine)];
|
|
84
|
+
if (missing.length > 0)
|
|
85
|
+
lines.push(`Not found (wrong ID, expired, or another account): ${missing.join(', ')}`);
|
|
86
|
+
if (rows.some(row => row.results))
|
|
87
|
+
lines.push(`Result links expire after ${RESULT_LINK_HOURS} hours.`);
|
|
88
|
+
if (rows.some(row => row.results))
|
|
89
|
+
lines.push(`Next step: ${RESULT_DELIVERY_INSTRUCTIONS}`);
|
|
90
|
+
return ok(lines.join('\n'), { tasks: rows, missing }, rows.flatMap(row => resultResources(row.task_id, row.results ?? [])));
|
|
91
|
+
}
|
|
92
|
+
let sinceMs;
|
|
93
|
+
if (since) {
|
|
94
|
+
sinceMs = parseSince(since);
|
|
95
|
+
if (sinceMs === undefined) {
|
|
96
|
+
return failure(`since "${since}" is not a time. Use ISO 8601 (2026-10-05T08:00:00Z) or a relative value such as 30m, 2h or 1d.`, {
|
|
97
|
+
error: { category: 'invalid_request', param: 'since' },
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const pageSize = limit ?? 20;
|
|
102
|
+
const page = await listTasks(config, { status, type, pageSize });
|
|
103
|
+
let items = page.data;
|
|
104
|
+
if (sinceMs !== undefined)
|
|
105
|
+
items = items.filter(item => item.created_at * 1000 >= sinceMs);
|
|
106
|
+
// The list endpoint omits result links; read finished tasks in one batch to include them.
|
|
107
|
+
const finished = items.filter(item => item.status === 'completed' && item.has_results).map(item => item.id).slice(0, MAX_IDS);
|
|
108
|
+
const details = new Map();
|
|
109
|
+
if (finished.length > 0) {
|
|
110
|
+
for (const task of await queryTasks(config, finished))
|
|
111
|
+
details.set(task.id, task);
|
|
112
|
+
}
|
|
113
|
+
const rows = items.map(item => {
|
|
114
|
+
const detailed = details.get(item.id);
|
|
115
|
+
if (detailed)
|
|
116
|
+
return rowFromTask(detailed);
|
|
117
|
+
const row = {
|
|
118
|
+
task_id: item.id,
|
|
119
|
+
status: item.status,
|
|
120
|
+
model: item.model,
|
|
121
|
+
type: item.type,
|
|
122
|
+
progress: item.progress,
|
|
123
|
+
created_at: new Date(item.created_at * 1000).toISOString(),
|
|
124
|
+
};
|
|
125
|
+
if (typeof item.credits_used === 'number' && item.status === 'completed') {
|
|
126
|
+
row.charged_credits = item.credits_used;
|
|
127
|
+
row.charged_usd = usdOf(item.credits_used);
|
|
128
|
+
}
|
|
129
|
+
if (item.has_error)
|
|
130
|
+
row.error_code = 'failed';
|
|
131
|
+
return row;
|
|
132
|
+
});
|
|
133
|
+
const filters = [status && `status ${status}`, type && `type ${type}`, since && `since ${since}`].filter(Boolean).join(', ');
|
|
134
|
+
const lines = [`${rows.length} recent task${rows.length === 1 ? '' : 's'} on this account${filters ? ` (${filters})` : ''}, newest first:`];
|
|
135
|
+
lines.push(...(rows.length > 0 ? rows.map(rowLine) : ['(none)']));
|
|
136
|
+
if (page.total > page.data.length)
|
|
137
|
+
lines.push(`${page.total} tasks match in total; raise limit or narrow the filters to see others.`);
|
|
138
|
+
if (rows.some(row => row.results))
|
|
139
|
+
lines.push(`Result links expire after ${RESULT_LINK_HOURS} hours.`);
|
|
140
|
+
if (rows.some(row => row.results))
|
|
141
|
+
lines.push(`Next step: ${RESULT_DELIVERY_INSTRUCTIONS}`);
|
|
142
|
+
return ok(lines.join('\n'), { tasks: rows, total: page.total }, rows.flatMap(row => resultResources(row.task_id, row.results ?? [])));
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
return errorResult(error);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=list-tasks.js.map
|