gpteam 0.1.22 → 0.1.23
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/lib/help.js +1 -1
- package/lib/image-mcp/image.js +160 -13
- package/lib/image-mcp/server.js +59 -26
- package/package.json +1 -1
package/lib/help.js
CHANGED
package/lib/image-mcp/image.js
CHANGED
|
@@ -14,6 +14,29 @@ export const DEFAULT_BASE_URL = 'https://api.gpteamservices.com/v1';
|
|
|
14
14
|
export const DEFAULT_IMAGE_MODEL = 'gpt-image-2';
|
|
15
15
|
export { DEFAULT_IMAGE_FORMAT };
|
|
16
16
|
|
|
17
|
+
export const IMAGE_FORMATS = ['png', 'jpeg', 'webp'];
|
|
18
|
+
export const IMAGE_QUALITY_LEVELS = ['low', 'medium', 'high', 'auto'];
|
|
19
|
+
export const IMAGE_BACKGROUND_OPTIONS = ['auto', 'opaque'];
|
|
20
|
+
export const IMAGE_MODERATION_OPTIONS = ['auto', 'low'];
|
|
21
|
+
export const POPULAR_IMAGE_SIZES = [
|
|
22
|
+
{ label: '1K 方图', size: '1024x1024', aspect_ratio: '1:1' },
|
|
23
|
+
{ label: '1K 横图', size: '1536x1024', aspect_ratio: '3:2' },
|
|
24
|
+
{ label: '1K 竖图', size: '1024x1536', aspect_ratio: '2:3' },
|
|
25
|
+
{ label: '2K 方图', size: '2048x2048', aspect_ratio: '1:1' },
|
|
26
|
+
{ label: '2K 宽屏', size: '2048x1152', aspect_ratio: '16:9' },
|
|
27
|
+
{ label: '2K 竖幅', size: '1152x2048', aspect_ratio: '9:16' },
|
|
28
|
+
{ label: '4K 横图', size: '3840x2160', aspect_ratio: '16:9' },
|
|
29
|
+
{ label: '4K 竖图', size: '2160x3840', aspect_ratio: '9:16' },
|
|
30
|
+
{ label: '自动', size: 'auto', aspect_ratio: 'auto' }
|
|
31
|
+
];
|
|
32
|
+
export const IMAGE_SIZE_CONSTRAINTS = {
|
|
33
|
+
max_edge_px: 3840,
|
|
34
|
+
edge_multiple_px: 16,
|
|
35
|
+
max_long_to_short_ratio: 3,
|
|
36
|
+
min_total_pixels: 655360,
|
|
37
|
+
max_total_pixels: 8294400
|
|
38
|
+
};
|
|
39
|
+
|
|
17
40
|
const defaultMaxAttempts = 3;
|
|
18
41
|
const defaultRetryDelayMs = 800;
|
|
19
42
|
const defaultRequestTimeoutMs = 5 * 60 * 1000;
|
|
@@ -32,7 +55,7 @@ export function buildImageGenerationPayload(input = {}, options = {}) {
|
|
|
32
55
|
stream: true,
|
|
33
56
|
size: String(input.size || '1024x1024'),
|
|
34
57
|
quality: String(input.quality || 'high'),
|
|
35
|
-
output_format:
|
|
58
|
+
output_format: resolveImageOutputFormat(input)
|
|
36
59
|
};
|
|
37
60
|
const imageOptions = { ...options, home: options.home };
|
|
38
61
|
const images = normalizeInputImages(collectInputImageValues(input), imageOptions);
|
|
@@ -41,6 +64,7 @@ export function buildImageGenerationPayload(input = {}, options = {}) {
|
|
|
41
64
|
if (mask) payload.mask = { image_url: mask };
|
|
42
65
|
copyOptionalImageToolOption(payload, input, 'background');
|
|
43
66
|
copyOptionalImageToolOption(payload, input, 'moderation');
|
|
67
|
+
copyOptionalImageToolOption(payload, input, 'output_compression');
|
|
44
68
|
return payload;
|
|
45
69
|
}
|
|
46
70
|
|
|
@@ -88,15 +112,7 @@ export function normalizeBaseUrl(value) {
|
|
|
88
112
|
|
|
89
113
|
export async function generateImage(input = {}, options = {}) {
|
|
90
114
|
const startedAt = now(options);
|
|
91
|
-
|
|
92
|
-
if (!prompt) {
|
|
93
|
-
throw new ImageMCPError('prompt 不能为空', {
|
|
94
|
-
code: 'prompt_required',
|
|
95
|
-
category: 'parameter',
|
|
96
|
-
stage: 'validate',
|
|
97
|
-
retryable: false
|
|
98
|
-
});
|
|
99
|
-
}
|
|
115
|
+
validateImageInput(input, { requirePrompt: true });
|
|
100
116
|
const credentials = loadGPTeamCredentials(options);
|
|
101
117
|
const payload = buildImageGenerationPayload(input, options);
|
|
102
118
|
const fetchImpl = options.fetch || globalThis.fetch;
|
|
@@ -147,6 +163,11 @@ export function createImageJobStore(options = {}) {
|
|
|
147
163
|
}
|
|
148
164
|
|
|
149
165
|
export function createImageJob(input = {}, options = {}) {
|
|
166
|
+
try {
|
|
167
|
+
validateImageInput(input, { requirePrompt: true });
|
|
168
|
+
} catch (error) {
|
|
169
|
+
return resultFromError(error);
|
|
170
|
+
}
|
|
150
171
|
const store = options.store || defaultJobStore;
|
|
151
172
|
configureJobStore(store, options);
|
|
152
173
|
cleanupImageJobs(store);
|
|
@@ -288,9 +309,18 @@ export function getCapabilities(options = {}) {
|
|
|
288
309
|
supports_mask: true,
|
|
289
310
|
image_input_fields: ['images', 'image', 'image_path', 'image_paths', 'input_image', 'input_images'],
|
|
290
311
|
mask_input_fields: ['mask', 'mask_path'],
|
|
291
|
-
sizes:
|
|
292
|
-
|
|
293
|
-
|
|
312
|
+
sizes: POPULAR_IMAGE_SIZES.map((item) => item.size),
|
|
313
|
+
popular_sizes: POPULAR_IMAGE_SIZES,
|
|
314
|
+
size_presets: ['1K', '2K', '4K', 'auto'],
|
|
315
|
+
size_constraints: IMAGE_SIZE_CONSTRAINTS,
|
|
316
|
+
aspect_ratios: ['1:1', '3:2', '2:3', '16:9', '9:16', 'custom'],
|
|
317
|
+
supports_custom_size: true,
|
|
318
|
+
formats: IMAGE_FORMATS,
|
|
319
|
+
output_formats: IMAGE_FORMATS,
|
|
320
|
+
quality: IMAGE_QUALITY_LEVELS,
|
|
321
|
+
background: IMAGE_BACKGROUND_OPTIONS,
|
|
322
|
+
moderation: IMAGE_MODERATION_OPTIONS,
|
|
323
|
+
supports_output_compression: true,
|
|
294
324
|
max_prompt_length: 32000,
|
|
295
325
|
statuses: ['queued', 'running', 'succeeded', 'failed', 'canceled', 'expired'],
|
|
296
326
|
default_output_format: DEFAULT_IMAGE_FORMAT,
|
|
@@ -301,6 +331,22 @@ export function getCapabilities(options = {}) {
|
|
|
301
331
|
};
|
|
302
332
|
}
|
|
303
333
|
|
|
334
|
+
export function validateImageInput(input = {}, options = {}) {
|
|
335
|
+
if (options.requirePrompt && !String(input.prompt || '').trim()) {
|
|
336
|
+
throw imageParamError('prompt_required', 'prompt 不能为空', 'prompt', input.prompt, {
|
|
337
|
+
hint: '请先让用户提供图片提示词。'
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
validateImageSize(input.size);
|
|
341
|
+
validateEnumImageParam('quality', input.quality, IMAGE_QUALITY_LEVELS);
|
|
342
|
+
validateImageFormatParam(input);
|
|
343
|
+
validateEnumImageParam('background', input.background, IMAGE_BACKGROUND_OPTIONS, {
|
|
344
|
+
hint: 'gpt-image-2 不支持 transparent,请使用 auto 或 opaque。'
|
|
345
|
+
});
|
|
346
|
+
validateEnumImageParam('moderation', input.moderation, IMAGE_MODERATION_OPTIONS);
|
|
347
|
+
validateOutputCompression(input.output_compression);
|
|
348
|
+
}
|
|
349
|
+
|
|
304
350
|
async function fetchImageWithRetry(fetchImpl, credentials, payload, options) {
|
|
305
351
|
const maxAttempts = resolveBoundedInt(1, options.maxAttempts, options.env && options.env.GPTEAM_IMAGE_MAX_ATTEMPTS, defaultMaxAttempts);
|
|
306
352
|
const retryDelayMs = resolveBoundedInt(0, options.retryDelayMs, options.env && options.env.GPTEAM_IMAGE_RETRY_DELAY_MS, defaultRetryDelayMs);
|
|
@@ -722,6 +768,107 @@ function resolveRevisedPromptFlag(input) {
|
|
|
722
768
|
return true;
|
|
723
769
|
}
|
|
724
770
|
|
|
771
|
+
function validateImageSize(value) {
|
|
772
|
+
if (value === undefined || value === null || value === '') return;
|
|
773
|
+
const text = String(value).trim().toLowerCase();
|
|
774
|
+
if (text === 'auto') return;
|
|
775
|
+
const match = text.match(/^(\d{2,5})x(\d{2,5})$/);
|
|
776
|
+
if (!match) {
|
|
777
|
+
throw imageParamError('invalid_size', 'size 必须是 auto 或类似 1024x1024 的宽高格式。', 'size', value, {
|
|
778
|
+
supported_values: POPULAR_IMAGE_SIZES.map((item) => item.size),
|
|
779
|
+
hint: '常用:1024x1024、1536x1024、1024x1536、2048x2048、2048x1152、1152x2048、3840x2160、2160x3840。'
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
const width = Number(match[1]);
|
|
783
|
+
const height = Number(match[2]);
|
|
784
|
+
const longSide = Math.max(width, height);
|
|
785
|
+
const shortSide = Math.min(width, height);
|
|
786
|
+
const pixels = width * height;
|
|
787
|
+
const valid = width % IMAGE_SIZE_CONSTRAINTS.edge_multiple_px === 0 &&
|
|
788
|
+
height % IMAGE_SIZE_CONSTRAINTS.edge_multiple_px === 0 &&
|
|
789
|
+
longSide <= IMAGE_SIZE_CONSTRAINTS.max_edge_px &&
|
|
790
|
+
longSide / shortSide <= IMAGE_SIZE_CONSTRAINTS.max_long_to_short_ratio &&
|
|
791
|
+
pixels >= IMAGE_SIZE_CONSTRAINTS.min_total_pixels &&
|
|
792
|
+
pixels <= IMAGE_SIZE_CONSTRAINTS.max_total_pixels;
|
|
793
|
+
if (!valid) {
|
|
794
|
+
throw imageParamError('invalid_size', 'size 超出 gpt-image-2 支持范围。', 'size', value, {
|
|
795
|
+
constraints: IMAGE_SIZE_CONSTRAINTS,
|
|
796
|
+
supported_values: POPULAR_IMAGE_SIZES.map((item) => item.size),
|
|
797
|
+
hint: '宽高需为 16 的倍数,长边不超过 3840,长短边比例不超过 3:1。'
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
function validateEnumImageParam(field, value, supportedValues, extra = {}) {
|
|
803
|
+
if (value === undefined || value === null || value === '') return;
|
|
804
|
+
const normalized = String(value).trim().toLowerCase();
|
|
805
|
+
if (supportedValues.includes(normalized)) return;
|
|
806
|
+
throw imageParamError(`invalid_${field}`, `${field} 参数不支持。`, field, value, {
|
|
807
|
+
supported_values: supportedValues,
|
|
808
|
+
...extra
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
function validateImageFormatParam(input) {
|
|
813
|
+
const formatValue = input.format;
|
|
814
|
+
const outputFormatValue = input.output_format;
|
|
815
|
+
const format = normalizeDeclaredImageFormat(formatValue);
|
|
816
|
+
const outputFormat = normalizeDeclaredImageFormat(outputFormatValue);
|
|
817
|
+
if (formatValue !== undefined && formatValue !== null && formatValue !== '' && !IMAGE_FORMATS.includes(format)) {
|
|
818
|
+
throw invalidImageFormatError('format', formatValue);
|
|
819
|
+
}
|
|
820
|
+
if (outputFormatValue !== undefined && outputFormatValue !== null && outputFormatValue !== '' && !IMAGE_FORMATS.includes(outputFormat)) {
|
|
821
|
+
throw invalidImageFormatError('output_format', outputFormatValue);
|
|
822
|
+
}
|
|
823
|
+
if (format && outputFormat && format !== outputFormat) {
|
|
824
|
+
throw imageParamError('invalid_format_conflict', 'format 和 output_format 不一致。', 'output_format', outputFormatValue, {
|
|
825
|
+
format,
|
|
826
|
+
output_format: outputFormat,
|
|
827
|
+
hint: '两个字段同时传入时必须表示同一种格式,例如 jpg 和 jpeg 可以同时使用。'
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
function validateOutputCompression(value) {
|
|
833
|
+
if (value === undefined || value === null || value === '') return;
|
|
834
|
+
const amount = Number(value);
|
|
835
|
+
if (Number.isInteger(amount) && amount >= 0 && amount <= 100) return;
|
|
836
|
+
throw imageParamError('invalid_output_compression', 'output_compression 必须是 0 到 100 的整数。', 'output_compression', value, {
|
|
837
|
+
supported_values: ['0-100']
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
function resolveImageOutputFormat(input = {}) {
|
|
842
|
+
return normalizeImageFormat(input.output_format || input.format || DEFAULT_IMAGE_FORMAT);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
function normalizeDeclaredImageFormat(value) {
|
|
846
|
+
if (value === undefined || value === null || value === '') return '';
|
|
847
|
+
const normalized = String(value).trim().toLowerCase();
|
|
848
|
+
return normalized === 'jpg' ? 'jpeg' : normalized;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
function invalidImageFormatError(field, received) {
|
|
852
|
+
return imageParamError('invalid_format', 'format/output_format 参数不支持。', field, received, {
|
|
853
|
+
supported_values: IMAGE_FORMATS,
|
|
854
|
+
hint: '支持 png、jpeg、webp,jpg 会按 jpeg 处理。'
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
function imageParamError(code, message, field, received, details = {}) {
|
|
859
|
+
return new ImageMCPError(message, {
|
|
860
|
+
code,
|
|
861
|
+
category: 'parameter',
|
|
862
|
+
stage: 'validate',
|
|
863
|
+
retryable: false,
|
|
864
|
+
details: {
|
|
865
|
+
field,
|
|
866
|
+
received,
|
|
867
|
+
...details
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
|
|
725
872
|
function resolveCodexHome(env, home) {
|
|
726
873
|
return expandHome(firstNonEmpty(env.GPTEAM_CODEX_HOME, env.CODEX_HOME, path.join(home, '.codex')), home);
|
|
727
874
|
}
|
package/lib/image-mcp/server.js
CHANGED
|
@@ -8,85 +8,118 @@ import {
|
|
|
8
8
|
downloadImageResult,
|
|
9
9
|
generateImage,
|
|
10
10
|
getCapabilities,
|
|
11
|
+
IMAGE_BACKGROUND_OPTIONS,
|
|
12
|
+
IMAGE_FORMATS,
|
|
13
|
+
IMAGE_MODERATION_OPTIONS,
|
|
14
|
+
IMAGE_QUALITY_LEVELS,
|
|
15
|
+
POPULAR_IMAGE_SIZES,
|
|
11
16
|
getImageJobStatus,
|
|
12
17
|
resultFromError,
|
|
13
18
|
structuredToolResult,
|
|
14
19
|
toolResultContent
|
|
15
20
|
} from './image.js';
|
|
16
21
|
|
|
22
|
+
const imageToolPromptingInstruction = '调用前请先确认用户真实需求:尺寸或比例、质量、输出格式、保存目录或文件名。缺少这些关键信息时应先追问,不要直接默认生成。';
|
|
23
|
+
|
|
17
24
|
const imageInputProperties = {
|
|
18
25
|
prompt: {
|
|
19
26
|
type: 'string',
|
|
20
|
-
description: '
|
|
27
|
+
description: '图片提示词。需要尽量具体,若用户只给模糊需求,应先追问风格、主体、场景和用途。'
|
|
21
28
|
},
|
|
22
29
|
size: {
|
|
23
30
|
type: 'string',
|
|
24
|
-
description:
|
|
25
|
-
default: '1024x1024'
|
|
31
|
+
description: `图片尺寸。支持 auto、常用尺寸 ${POPULAR_IMAGE_SIZES.map((item) => `${item.label} ${item.size}`).join('、')},也支持满足约束的自定义宽高,例如 9:16 可用 1152x2048 或 2160x3840。`
|
|
26
32
|
},
|
|
27
33
|
quality: {
|
|
28
34
|
type: 'string',
|
|
29
|
-
description: '
|
|
30
|
-
|
|
35
|
+
description: '图片质量。生图前应让用户确认速度优先还是质量优先。',
|
|
36
|
+
enum: IMAGE_QUALITY_LEVELS
|
|
31
37
|
},
|
|
32
38
|
format: {
|
|
33
39
|
type: 'string',
|
|
34
|
-
description: '
|
|
35
|
-
enum:
|
|
36
|
-
|
|
40
|
+
description: '输出图片格式。',
|
|
41
|
+
enum: IMAGE_FORMATS
|
|
42
|
+
},
|
|
43
|
+
output_format: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
description: '输出图片格式别名,和 format 等价。',
|
|
46
|
+
enum: IMAGE_FORMATS
|
|
37
47
|
},
|
|
38
48
|
output_path: {
|
|
39
49
|
type: 'string',
|
|
40
|
-
description: '
|
|
50
|
+
description: '保存路径,可以是目录或完整文件路径。缺少时建议先询问用户想保存到哪里。'
|
|
41
51
|
},
|
|
42
52
|
overwrite: {
|
|
43
53
|
type: 'boolean',
|
|
44
|
-
description: '
|
|
54
|
+
description: '文件已存在时是否覆盖。默认 false,会自动生成 -v2、-v3 等新文件名。',
|
|
45
55
|
default: false
|
|
46
56
|
},
|
|
47
57
|
idempotency_key: {
|
|
48
58
|
type: 'string',
|
|
49
|
-
description: '
|
|
59
|
+
description: '幂等键。客户端超时后用同一个 key 重试,会复用同一进程内的本地任务,避免重复生成。'
|
|
60
|
+
},
|
|
61
|
+
image: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
description: '单张输入图片,支持 data URL、HTTPS URL 或本地文件路径,用于图生图或编辑。'
|
|
50
64
|
},
|
|
51
65
|
images: {
|
|
52
66
|
type: 'array',
|
|
53
67
|
items: { type: 'string' },
|
|
54
|
-
description: '
|
|
68
|
+
description: '多张输入图片,支持 data URL、HTTPS URL 或本地文件路径,用于图生图或编辑。'
|
|
55
69
|
},
|
|
56
70
|
image_path: {
|
|
57
71
|
type: 'string',
|
|
58
|
-
description: '
|
|
72
|
+
description: '单张本地输入图片路径别名,用于图生图或编辑。'
|
|
59
73
|
},
|
|
60
74
|
image_paths: {
|
|
61
75
|
type: 'array',
|
|
62
76
|
items: { type: 'string' },
|
|
63
|
-
description: '
|
|
77
|
+
description: '多张本地输入图片路径别名,用于图生图或编辑。'
|
|
64
78
|
},
|
|
65
79
|
input_image: {
|
|
66
80
|
type: 'string',
|
|
67
|
-
description: '
|
|
81
|
+
description: '单张输入图片别名,支持 data URL、HTTPS URL 或本地文件路径。'
|
|
68
82
|
},
|
|
69
83
|
input_images: {
|
|
70
84
|
type: 'array',
|
|
71
85
|
items: { type: 'string' },
|
|
72
|
-
description: '
|
|
86
|
+
description: '多张输入图片别名,支持 data URL、HTTPS URL 或本地文件路径。'
|
|
73
87
|
},
|
|
74
88
|
mask: {
|
|
75
89
|
type: 'string',
|
|
76
|
-
description: '
|
|
90
|
+
description: '编辑遮罩图片,支持 data URL、HTTPS URL 或本地文件路径。'
|
|
77
91
|
},
|
|
78
92
|
mask_path: {
|
|
79
93
|
type: 'string',
|
|
80
|
-
description: '
|
|
94
|
+
description: '本地遮罩图片路径别名。'
|
|
81
95
|
},
|
|
82
96
|
input_fidelity: {
|
|
83
97
|
type: 'string',
|
|
84
|
-
description: '
|
|
98
|
+
description: '兼容字段。当前 GPTeam Image 2 桥接会忽略该字段,因为上游 Codex 图片工具会拒绝 edits 中的该参数。',
|
|
85
99
|
enum: ['low', 'high']
|
|
86
100
|
},
|
|
101
|
+
background: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
description: '背景策略。gpt-image-2 当前支持 auto 或 opaque。',
|
|
104
|
+
enum: IMAGE_BACKGROUND_OPTIONS
|
|
105
|
+
},
|
|
106
|
+
moderation: {
|
|
107
|
+
type: 'string',
|
|
108
|
+
description: '内容安全策略。通常保持 auto,需要更低过滤强度时可用 low。',
|
|
109
|
+
enum: IMAGE_MODERATION_OPTIONS
|
|
110
|
+
},
|
|
111
|
+
output_compression: {
|
|
112
|
+
type: 'integer',
|
|
113
|
+
description: '输出压缩比例,0 到 100 的整数。'
|
|
114
|
+
},
|
|
115
|
+
include_revised_prompt: {
|
|
116
|
+
type: 'boolean',
|
|
117
|
+
description: '是否返回上游修订后的提示词。',
|
|
118
|
+
default: true
|
|
119
|
+
},
|
|
87
120
|
return_revised_prompt: {
|
|
88
121
|
type: 'boolean',
|
|
89
|
-
description: '
|
|
122
|
+
description: '是否返回上游修订后的提示词,兼容旧字段。',
|
|
90
123
|
default: true
|
|
91
124
|
}
|
|
92
125
|
};
|
|
@@ -94,7 +127,7 @@ const imageInputProperties = {
|
|
|
94
127
|
const tools = [
|
|
95
128
|
{
|
|
96
129
|
name: 'create_image_job',
|
|
97
|
-
description:
|
|
130
|
+
description: `推荐常规使用。创建本地后台 GPTeam Image 2 任务并立即返回 job_id。${imageToolPromptingInstruction}`,
|
|
98
131
|
inputSchema: {
|
|
99
132
|
type: 'object',
|
|
100
133
|
properties: imageInputProperties,
|
|
@@ -104,22 +137,22 @@ const tools = [
|
|
|
104
137
|
},
|
|
105
138
|
{
|
|
106
139
|
name: 'get_image_job_status',
|
|
107
|
-
description: '
|
|
140
|
+
description: '查询本地 GPTeam Image 2 图片任务状态。',
|
|
108
141
|
inputSchema: jobIDSchema()
|
|
109
142
|
},
|
|
110
143
|
{
|
|
111
144
|
name: 'cancel_image_job',
|
|
112
|
-
description: '
|
|
145
|
+
description: '取消仍在 queued 或 running 的本地 GPTeam Image 2 图片任务。取消是 best-effort,上游已开始生成时不保证同步取消。',
|
|
113
146
|
inputSchema: jobIDSchema()
|
|
114
147
|
},
|
|
115
148
|
{
|
|
116
149
|
name: 'download_image_result',
|
|
117
|
-
description: '
|
|
150
|
+
description: '下载已完成图片任务的本地文件元数据和图片内容,可选择只返回 metadata。',
|
|
118
151
|
inputSchema: downloadSchema()
|
|
119
152
|
},
|
|
120
153
|
{
|
|
121
154
|
name: 'get_capabilities',
|
|
122
|
-
description: '
|
|
155
|
+
description: '返回 GPTeam Image MCP 能力,包括支持尺寸、格式、质量、异步任务、取消语义、队列上限和参数约束。',
|
|
123
156
|
inputSchema: {
|
|
124
157
|
type: 'object',
|
|
125
158
|
properties: {},
|
|
@@ -128,7 +161,7 @@ const tools = [
|
|
|
128
161
|
},
|
|
129
162
|
{
|
|
130
163
|
name: 'generate_image',
|
|
131
|
-
description:
|
|
164
|
+
description: `兼容同步工具。通过 GPTeam Image 2 生成图片,等待完成并保存到本地。${imageToolPromptingInstruction}耗时较长时优先使用 create_image_job。`,
|
|
132
165
|
inputSchema: {
|
|
133
166
|
type: 'object',
|
|
134
167
|
properties: imageInputProperties,
|