gpteam 0.1.21 → 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/README.md CHANGED
@@ -27,7 +27,7 @@ The Image MCP exposes both a synchronous compatibility tool and a local async jo
27
27
 
28
28
  Image MCP results are returned as stable JSON text and MCP `structuredContent`. Successful results include final file path, model, action, size, format, quality, byte size, SHA-256, MIME type, image dimensions, duration, retry count, `job_id`, `trace_id`, and optional `idempotency_key`. Error results use stable `error.code`, `error.message`, `error.retryable`, `error.stage`, `error.upstream_status`, and `error.trace_id` fields while keeping compatibility fields such as `category` and `http_status`.
29
29
 
30
- The MCP supports normal text-to-image generation and image-to-image/edit inputs. Pass `images` as data URLs, HTTPS URLs, or local file paths. Pass `mask` the same way for masked edits. `input_fidelity` is accepted for compatibility but is not forwarded to the current GPTeam Image 2 bridge because upstream Codex image edits reject it. The MCP requests GPTeam image endpoints with `stream=true` and reads the final image event, so long image jobs get early stream bytes instead of sitting idle until the final JSON body. File writes create missing directories, avoid overwriting existing files by adding `-v2`, `-v3`, etc., and validate PNG/JPEG/WebP before returning success. `overwrite: true` is available for explicit replacement. `return_revised_prompt` controls whether the upstream revised prompt is included in the result.
30
+ The MCP supports normal text-to-image generation and image-to-image/edit inputs. Pass `images` as data URLs, HTTPS URLs, or local file paths. For easier tool calling, `image`, `image_path`, `image_paths`, `input_image`, and `input_images` are accepted as aliases. Pass `mask` or `mask_path` the same way for masked edits. `input_fidelity` is accepted for compatibility but is not forwarded to the current GPTeam Image 2 bridge because upstream Codex image edits reject it. The MCP requests GPTeam image endpoints with `stream=true` and reads the final image event, so long image jobs get early stream bytes instead of sitting idle until the final JSON body. File writes create missing directories, avoid overwriting existing files by adding `-v2`, `-v3`, etc., and validate PNG/JPEG/WebP before returning success. `overwrite: true` is available for explicit replacement. `return_revised_prompt` controls whether the upstream revised prompt is included in the result.
31
31
 
32
32
  Claude Code is written to `~/.claude/settings.json` under the `env` section, using the GPTeam `/anthropic` base URL. OpenClaw writes `models.providers.gpteam` and also selects `gpteam/<model>` under `agents.defaults.model`, so the chosen model is active without an extra manual step.
33
33
 
package/lib/help.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export const PACKAGE_NAME = 'gpteam';
2
- export const PACKAGE_VERSION = '0.1.21';
2
+ export const PACKAGE_VERSION = '0.1.23';
3
3
 
4
4
  export function getHelpText() {
5
5
  return [
@@ -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,15 +55,16 @@ 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: normalizeImageFormat(input.format || input.output_format || DEFAULT_IMAGE_FORMAT)
58
+ output_format: resolveImageOutputFormat(input)
36
59
  };
37
60
  const imageOptions = { ...options, home: options.home };
38
- const images = normalizeInputImages(input.images || input.image, imageOptions);
61
+ const images = normalizeInputImages(collectInputImageValues(input), imageOptions);
39
62
  if (images.length > 0) payload.images = images.map((imageURL) => ({ image_url: imageURL }));
40
- const mask = normalizeImageReference(input.mask, imageOptions);
63
+ const mask = normalizeImageReference(firstPresentImageReference(input.mask, input.mask_path), imageOptions);
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
- const prompt = String(input.prompt || '').trim();
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);
@@ -286,9 +307,20 @@ export function getCapabilities(options = {}) {
286
307
  supports_idempotency_key: true,
287
308
  supports_image_to_image: true,
288
309
  supports_mask: true,
289
- sizes: ['1024x1024', '1536x1024', '1024x1536', 'auto'],
290
- formats: ['png', 'jpeg', 'webp'],
291
- quality: ['low', 'medium', 'high', 'auto'],
310
+ image_input_fields: ['images', 'image', 'image_path', 'image_paths', 'input_image', 'input_images'],
311
+ mask_input_fields: ['mask', 'mask_path'],
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,
292
324
  max_prompt_length: 32000,
293
325
  statuses: ['queued', 'running', 'succeeded', 'failed', 'canceled', 'expired'],
294
326
  default_output_format: DEFAULT_IMAGE_FORMAT,
@@ -299,6 +331,22 @@ export function getCapabilities(options = {}) {
299
331
  };
300
332
  }
301
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
+
302
350
  async function fetchImageWithRetry(fetchImpl, credentials, payload, options) {
303
351
  const maxAttempts = resolveBoundedInt(1, options.maxAttempts, options.env && options.env.GPTEAM_IMAGE_MAX_ATTEMPTS, defaultMaxAttempts);
304
352
  const retryDelayMs = resolveBoundedInt(0, options.retryDelayMs, options.env && options.env.GPTEAM_IMAGE_RETRY_DELAY_MS, defaultRetryDelayMs);
@@ -632,6 +680,36 @@ function normalizeInputImages(value, options = {}) {
632
680
  return rawImages.map((item) => normalizeImageReference(item, options)).filter(Boolean);
633
681
  }
634
682
 
683
+ function collectInputImageValues(input = {}) {
684
+ const values = [];
685
+ appendImageAlias(values, input.images);
686
+ appendImageAlias(values, input.image);
687
+ appendImageAlias(values, input.image_path);
688
+ appendImageAlias(values, input.image_paths);
689
+ appendImageAlias(values, input.input_image);
690
+ appendImageAlias(values, input.input_images);
691
+ return values;
692
+ }
693
+
694
+ function appendImageAlias(target, value) {
695
+ if (Array.isArray(value)) {
696
+ for (const item of value) appendImageAlias(target, item);
697
+ return;
698
+ }
699
+ if (value) target.push(value);
700
+ }
701
+
702
+ function firstPresentImageReference(...values) {
703
+ for (const value of values) {
704
+ if (Array.isArray(value)) {
705
+ if (value.length > 0) return value[0];
706
+ continue;
707
+ }
708
+ if (value) return value;
709
+ }
710
+ return '';
711
+ }
712
+
635
713
  function normalizeImageReference(value, options = {}) {
636
714
  if (!value) return '';
637
715
  if (typeof value === 'object') {
@@ -690,6 +768,107 @@ function resolveRevisedPromptFlag(input) {
690
768
  return true;
691
769
  }
692
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
+
693
872
  function resolveCodexHome(env, home) {
694
873
  return expandHome(firstNonEmpty(env.GPTEAM_CODEX_HOME, env.CODEX_HOME, path.join(home, '.codex')), home);
695
874
  }
@@ -8,63 +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: 'Image prompt.'
27
+ description: '图片提示词。需要尽量具体,若用户只给模糊需求,应先追问风格、主体、场景和用途。'
21
28
  },
22
29
  size: {
23
30
  type: 'string',
24
- description: 'Image size, for example 1024x1024.',
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: 'Image quality.',
30
- default: 'high'
35
+ description: '图片质量。生图前应让用户确认速度优先还是质量优先。',
36
+ enum: IMAGE_QUALITY_LEVELS
31
37
  },
32
38
  format: {
33
39
  type: 'string',
34
- description: 'Output image format.',
35
- enum: ['png', 'jpeg', 'webp'],
36
- default: 'png'
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: 'Optional output file path or directory.'
50
+ description: '保存路径,可以是目录或完整文件路径。缺少时建议先询问用户想保存到哪里。'
41
51
  },
42
52
  overwrite: {
43
53
  type: 'boolean',
44
- description: 'Overwrite output_path when it already exists. Defaults to false.',
54
+ description: '文件已存在时是否覆盖。默认 false,会自动生成 -v2、-v3 等新文件名。',
45
55
  default: false
46
56
  },
47
57
  idempotency_key: {
48
58
  type: 'string',
49
- description: 'Optional idempotency key. Reusing it returns the same local job in this MCP process.'
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: 'Optional input images for image-to-image or edit. Values may be data URLs, HTTPS URLs, or local file paths.'
68
+ description: '多张输入图片,支持 data URL、HTTPS URL 或本地文件路径,用于图生图或编辑。'
69
+ },
70
+ image_path: {
71
+ type: 'string',
72
+ description: '单张本地输入图片路径别名,用于图生图或编辑。'
73
+ },
74
+ image_paths: {
75
+ type: 'array',
76
+ items: { type: 'string' },
77
+ description: '多张本地输入图片路径别名,用于图生图或编辑。'
78
+ },
79
+ input_image: {
80
+ type: 'string',
81
+ description: '单张输入图片别名,支持 data URL、HTTPS URL 或本地文件路径。'
82
+ },
83
+ input_images: {
84
+ type: 'array',
85
+ items: { type: 'string' },
86
+ description: '多张输入图片别名,支持 data URL、HTTPS URL 或本地文件路径。'
55
87
  },
56
88
  mask: {
57
89
  type: 'string',
58
- description: 'Optional mask image for image edit. Value may be a data URL, HTTPS URL, or local file path.'
90
+ description: '编辑遮罩图片,支持 data URLHTTPS URL 或本地文件路径。'
91
+ },
92
+ mask_path: {
93
+ type: 'string',
94
+ description: '本地遮罩图片路径别名。'
59
95
  },
60
96
  input_fidelity: {
61
97
  type: 'string',
62
- description: 'Accepted for compatibility. The GPTeam Image 2 bridge currently ignores this option because the upstream Codex image tool rejects it on edits.',
98
+ description: '兼容字段。当前 GPTeam Image 2 桥接会忽略该字段,因为上游 Codex 图片工具会拒绝 edits 中的该参数。',
63
99
  enum: ['low', 'high']
64
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
+ },
65
120
  return_revised_prompt: {
66
121
  type: 'boolean',
67
- description: 'Return upstream revised prompt when available.',
122
+ description: '是否返回上游修订后的提示词,兼容旧字段。',
68
123
  default: true
69
124
  }
70
125
  };
@@ -72,7 +127,7 @@ const imageInputProperties = {
72
127
  const tools = [
73
128
  {
74
129
  name: 'create_image_job',
75
- description: 'Recommended for normal use. Create a local background GPTeam Image 2 job and return immediately with a job_id.',
130
+ description: `推荐常规使用。创建本地后台 GPTeam Image 2 任务并立即返回 job_id。${imageToolPromptingInstruction}`,
76
131
  inputSchema: {
77
132
  type: 'object',
78
133
  properties: imageInputProperties,
@@ -82,22 +137,22 @@ const tools = [
82
137
  },
83
138
  {
84
139
  name: 'get_image_job_status',
85
- description: 'Get the status of a local GPTeam Image 2 job.',
140
+ description: '查询本地 GPTeam Image 2 图片任务状态。',
86
141
  inputSchema: jobIDSchema()
87
142
  },
88
143
  {
89
144
  name: 'cancel_image_job',
90
- description: 'Cancel a local GPTeam Image 2 job when it is still queued or running.',
145
+ description: '取消仍在 queued running 的本地 GPTeam Image 2 图片任务。取消是 best-effort,上游已开始生成时不保证同步取消。',
91
146
  inputSchema: jobIDSchema()
92
147
  },
93
148
  {
94
149
  name: 'download_image_result',
95
- description: 'Return the saved local file metadata and image content for a completed image job.',
150
+ description: '下载已完成图片任务的本地文件元数据和图片内容,可选择只返回 metadata',
96
151
  inputSchema: downloadSchema()
97
152
  },
98
153
  {
99
154
  name: 'get_capabilities',
100
- description: 'Return GPTeam Image MCP capabilities, supported sizes, formats, quality levels, async support, and queue limits.',
155
+ description: '返回 GPTeam Image MCP 能力,包括支持尺寸、格式、质量、异步任务、取消语义、队列上限和参数约束。',
101
156
  inputSchema: {
102
157
  type: 'object',
103
158
  properties: {},
@@ -106,7 +161,7 @@ const tools = [
106
161
  },
107
162
  {
108
163
  name: 'generate_image',
109
- description: 'Compatibility tool. Generate an image through GPTeam Image 2, wait for completion, and save it locally.',
164
+ description: `兼容同步工具。通过 GPTeam Image 2 生成图片,等待完成并保存到本地。${imageToolPromptingInstruction}耗时较长时优先使用 create_image_job。`,
110
165
  inputSchema: {
111
166
  type: 'object',
112
167
  properties: imageInputProperties,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gpteam",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "GPTeam API interactive client configurator and ingress benchmark CLI.",
5
5
  "type": "module",
6
6
  "bin": {