gpteam 0.1.31 → 0.1.33
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 +1 -1
- package/lib/config.js +58 -5
- package/lib/help.js +1 -1
- package/lib/image-mcp/image.js +1 -0
- package/lib/image-mcp/server.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ The Image MCP exposes an async-first local job flow plus a legacy compatibility
|
|
|
27
27
|
- `get_capabilities`: returns supported sizes, formats, quality values, async support, cancellation semantics, queue limits, and image-to-image support.
|
|
28
28
|
- `generate_image`: legacy compatibility alias. It now creates the same async job and returns `job_id` immediately instead of blocking until the image is complete.
|
|
29
29
|
|
|
30
|
-
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`.
|
|
30
|
+
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`. `2K` and `4K` are output size tiers; completed results report the final image width and height so clients can verify the delivered dimensions. 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`.
|
|
31
31
|
|
|
32
32
|
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.
|
|
33
33
|
|
package/lib/config.js
CHANGED
|
@@ -59,9 +59,9 @@ export function writeCodexConfig(settings) {
|
|
|
59
59
|
'requires_openai_auth = true',
|
|
60
60
|
'supports_websockets = true'
|
|
61
61
|
];
|
|
62
|
-
const
|
|
63
|
-
?
|
|
64
|
-
|
|
62
|
+
const restWithFeatures = mergeCodexFeatureLines(rest, {
|
|
63
|
+
responses_websockets_v2: settings.websocket === true ? 'true' : null
|
|
64
|
+
});
|
|
65
65
|
const mcpCommand = codexImageMCPCommand();
|
|
66
66
|
const mcpEnv = imageMCPEnv(settings);
|
|
67
67
|
const managedImageMCP = [
|
|
@@ -82,8 +82,7 @@ export function writeCodexConfig(settings) {
|
|
|
82
82
|
const next = joinTomlSections([
|
|
83
83
|
managedRoot.join('\n'),
|
|
84
84
|
rootLines.join('\n'),
|
|
85
|
-
|
|
86
|
-
websocketFeature.join('\n'),
|
|
85
|
+
restWithFeatures.join('\n'),
|
|
87
86
|
imageMCPEnabled(settings) ? managedImageMCP.join('\n') : '',
|
|
88
87
|
managedProvider.join('\n')
|
|
89
88
|
]);
|
|
@@ -520,11 +519,16 @@ function joinTomlSections(sections) {
|
|
|
520
519
|
|
|
521
520
|
function assertNoDuplicateTomlKeys(text) {
|
|
522
521
|
const seen = new Map();
|
|
522
|
+
const seenTables = new Set();
|
|
523
523
|
let section = '<root>';
|
|
524
524
|
for (const line of String(text || '').split(/\r?\n/)) {
|
|
525
525
|
const table = line.match(/^\s*\[([^\]]+)\]\s*$/);
|
|
526
526
|
if (table) {
|
|
527
527
|
section = table[1];
|
|
528
|
+
if (seenTables.has(section)) {
|
|
529
|
+
throw new Error(`生成的 Codex 配置存在重复表:${section},已停止写入`);
|
|
530
|
+
}
|
|
531
|
+
seenTables.add(section);
|
|
528
532
|
if (!seen.has(section)) seen.set(section, new Set());
|
|
529
533
|
continue;
|
|
530
534
|
}
|
|
@@ -566,10 +570,59 @@ function isManagedProviderLine(line) {
|
|
|
566
570
|
return /^\s*(name|base_url|wire_api|requires_openai_auth|supports_websockets)\s*=/.test(line);
|
|
567
571
|
}
|
|
568
572
|
|
|
573
|
+
function isFeaturesHeader(line) {
|
|
574
|
+
return /^\s*\[features\]\s*$/.test(line);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function isManagedFeatureLine(line) {
|
|
578
|
+
return /^\s*responses_websockets_v2\s*=/.test(line);
|
|
579
|
+
}
|
|
580
|
+
|
|
569
581
|
function isSalvageableRootLine(line) {
|
|
570
582
|
return /^\s*(js_repl_node_path|preferred_auth_method|personality|plan_mode_reasoning_effort|service_tier)\s*=/.test(line);
|
|
571
583
|
}
|
|
572
584
|
|
|
585
|
+
function mergeCodexFeatureLines(lines, features) {
|
|
586
|
+
const featureLines = Object.entries(features || {})
|
|
587
|
+
.filter(([, value]) => value !== null && value !== undefined)
|
|
588
|
+
.map(([key, value]) => `${key} = ${value}`);
|
|
589
|
+
const out = [];
|
|
590
|
+
let inFeatures = false;
|
|
591
|
+
let featuresTableSeen = false;
|
|
592
|
+
let managedLinesInserted = false;
|
|
593
|
+
|
|
594
|
+
for (const line of lines) {
|
|
595
|
+
if (isTableHeader(line)) {
|
|
596
|
+
if (inFeatures && !managedLinesInserted) {
|
|
597
|
+
appendManagedFeatureLines(out, featureLines);
|
|
598
|
+
if (out.length && out[out.length - 1].trim()) out.push('');
|
|
599
|
+
managedLinesInserted = true;
|
|
600
|
+
}
|
|
601
|
+
inFeatures = isFeaturesHeader(line);
|
|
602
|
+
if (inFeatures) featuresTableSeen = true;
|
|
603
|
+
out.push(line);
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
606
|
+
if (inFeatures && isManagedFeatureLine(line)) continue;
|
|
607
|
+
out.push(line);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if (inFeatures && !managedLinesInserted) {
|
|
611
|
+
appendManagedFeatureLines(out, featureLines);
|
|
612
|
+
managedLinesInserted = true;
|
|
613
|
+
}
|
|
614
|
+
if (!featuresTableSeen && featureLines.length > 0) {
|
|
615
|
+
if (out.length && out[out.length - 1].trim()) out.push('');
|
|
616
|
+
out.push('[features]', ...featureLines);
|
|
617
|
+
}
|
|
618
|
+
return trimEmptyEdges(out);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
function appendManagedFeatureLines(out, featureLines) {
|
|
622
|
+
while (out.length && !out[out.length - 1].trim()) out.pop();
|
|
623
|
+
out.push(...featureLines);
|
|
624
|
+
}
|
|
625
|
+
|
|
573
626
|
function backupIfExists(filePath) {
|
|
574
627
|
if (!fs.existsSync(filePath)) return;
|
|
575
628
|
const stamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\..+/, '').replace('T', '-');
|
package/lib/help.js
CHANGED
package/lib/image-mcp/image.js
CHANGED
|
@@ -314,6 +314,7 @@ export function getCapabilities(options = {}) {
|
|
|
314
314
|
popular_sizes: POPULAR_IMAGE_SIZES,
|
|
315
315
|
size_presets: ['1K', '2K', '4K', 'auto'],
|
|
316
316
|
size_constraints: IMAGE_SIZE_CONSTRAINTS,
|
|
317
|
+
output_size_contract: '2K and 4K are delivered output size tiers; successful results include final width and height.',
|
|
317
318
|
aspect_ratios: ['1:1', '3:2', '2:3', '16:9', '9:16', 'custom'],
|
|
318
319
|
supports_custom_size: true,
|
|
319
320
|
formats: IMAGE_FORMATS,
|
package/lib/image-mcp/server.js
CHANGED
|
@@ -27,7 +27,7 @@ const imageInputProperties = {
|
|
|
27
27
|
},
|
|
28
28
|
size: {
|
|
29
29
|
type: 'string',
|
|
30
|
-
description: `图片尺寸。支持 auto、常用尺寸 ${POPULAR_IMAGE_SIZES.map((item) => `${item.label} ${item.size}`).join('、')},也支持满足约束的自定义宽高,例如 9:16 可用 1152x2048 或 2160x3840
|
|
30
|
+
description: `图片尺寸。支持 auto、常用尺寸 ${POPULAR_IMAGE_SIZES.map((item) => `${item.label} ${item.size}`).join('、')},也支持满足约束的自定义宽高,例如 9:16 可用 1152x2048 或 2160x3840。2K/4K 是正式输出规格,完成结果会返回最终图片宽高。`
|
|
31
31
|
},
|
|
32
32
|
quality: {
|
|
33
33
|
type: 'string',
|