@avclabs.ai/media-mcp 0.2.0 → 0.3.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/README.md +398 -184
- package/README_CN.md +633 -0
- package/config.json +1 -0
- package/dist/image-enhancement.d.ts +3 -0
- package/dist/image-enhancement.d.ts.map +1 -0
- package/dist/image-enhancement.js +185 -0
- package/dist/image-enhancement.js.map +1 -0
- package/dist/sam3.d.ts +7 -0
- package/dist/sam3.d.ts.map +1 -1
- package/dist/sam3.js +148 -104
- package/dist/sam3.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +80 -56
- package/dist/server.js.map +1 -1
- package/dist/service-config.d.ts +62 -0
- package/dist/service-config.d.ts.map +1 -0
- package/dist/service-config.js +58 -0
- package/dist/service-config.js.map +1 -0
- package/dist/tooling.d.ts +42 -0
- package/dist/tooling.d.ts.map +1 -0
- package/dist/tooling.js +153 -0
- package/dist/tooling.js.map +1 -0
- package/dist/tos.d.ts +35 -0
- package/dist/tos.d.ts.map +1 -0
- package/dist/tos.js +281 -0
- package/dist/tos.js.map +1 -0
- package/dist/upload.d.ts +79 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +190 -0
- package/dist/upload.js.map +1 -0
- package/dist/video-enhancement.d.ts.map +1 -1
- package/dist/video-enhancement.js +95 -175
- package/dist/video-enhancement.js.map +1 -1
- package/package.json +11 -6
- package/README_EN.md +0 -419
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { checkLocalFile, formatRequestError, parseTosSignature, unwrapEnvelope, uploadToTos, } from './tos.js';
|
|
5
|
+
import { classifyStatus, POLL_REQUEST_TIMEOUT_MS, pollUntilTerminal, registerTool } from './tooling.js';
|
|
6
|
+
const PollIntervalSchema = z.number().min(0.5).max(30).default(5).describe('Polling interval in seconds (0.5-30), default 5');
|
|
7
|
+
const SyncTimeoutSchema = z.number().min(1).max(45).default(45).describe('Synchronous wait timeout in seconds (1-45), default 45. Returns task_id early when exceeded, use get_image_task_status to continue polling');
|
|
8
|
+
// Schemas
|
|
9
|
+
const EnhanceImageSyncSchema = z.object({
|
|
10
|
+
image_source: z.string().describe('Image URL or local file path (URL must be publicly accessible, login or signed links are not supported)'),
|
|
11
|
+
type: z.enum(['url', 'local']).default('url').describe('Upload type: url=remote image, local=local file'),
|
|
12
|
+
scale: z.number().int().min(1).max(4).default(2).describe('Enhancement scale multiplier (1-4), default 2. Controls the upscaling factor for image enhancement (e.g. 2=2x, 4=4x)'),
|
|
13
|
+
poll_interval: PollIntervalSchema,
|
|
14
|
+
timeout: SyncTimeoutSchema,
|
|
15
|
+
});
|
|
16
|
+
const ColorizeImageSyncSchema = z.object({
|
|
17
|
+
image_source: z.string().describe('Image URL or local file path (URL must be publicly accessible, login or signed links are not supported)'),
|
|
18
|
+
type: z.enum(['url', 'local']).default('url').describe('Upload type: url=remote image, local=local file'),
|
|
19
|
+
poll_interval: PollIntervalSchema,
|
|
20
|
+
timeout: SyncTimeoutSchema,
|
|
21
|
+
});
|
|
22
|
+
const DenoiseImageSyncSchema = z.object({
|
|
23
|
+
image_source: z.string().describe('Image URL or local file path (URL must be publicly accessible, login or signed links are not supported)'),
|
|
24
|
+
type: z.enum(['url', 'local']).default('url').describe('Upload type: url=remote image, local=local file'),
|
|
25
|
+
poll_interval: PollIntervalSchema,
|
|
26
|
+
timeout: SyncTimeoutSchema,
|
|
27
|
+
});
|
|
28
|
+
// Schema - status query
|
|
29
|
+
const GetImageTaskStatusSchema = z.object({
|
|
30
|
+
task_id: z.string().describe('Task ID'),
|
|
31
|
+
});
|
|
32
|
+
export function setupImageEnhancementTools(server, baseUrl, apiKey) {
|
|
33
|
+
const client = axios.create({
|
|
34
|
+
baseURL: baseUrl.replace(/\/$/, ''),
|
|
35
|
+
headers: {
|
|
36
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
37
|
+
'Content-Type': 'application/json',
|
|
38
|
+
},
|
|
39
|
+
timeout: 60000,
|
|
40
|
+
});
|
|
41
|
+
// ========== Sync task tools ==========
|
|
42
|
+
registerTool(server, 'enhance_image_sync', `Enhance/upscale an image to improve quality (图片增强/放大/超分辨率). Use this tool ONLY for image enhancement and upscaling tasks.
|
|
43
|
+
|
|
44
|
+
Two upload methods are supported:
|
|
45
|
+
1. URL upload: provide an image URL
|
|
46
|
+
2. Local upload: provide a local file path, the MCP Server will auto-upload to TOS object storage
|
|
47
|
+
|
|
48
|
+
Best for images with estimated processing time < 1 minute. If the task is not completed within the timeout, the tool returns early with a task_id. Use get_image_task_status to continue polling.`, EnhanceImageSyncSchema.shape, async (args) => processImageSync(client, args.image_source, args.type, 'enhance', args.poll_interval, args.timeout, args.scale));
|
|
49
|
+
registerTool(server, 'colorize_image_sync', `Colorize a black-and-white photo (黑白照片上色/旧照片上色). Use this tool ONLY for adding color to grayscale or black-and-white images.
|
|
50
|
+
|
|
51
|
+
Two upload methods are supported:
|
|
52
|
+
1. URL upload: provide an image URL
|
|
53
|
+
2. Local upload: provide a local file path, the MCP Server will auto-upload to TOS object storage
|
|
54
|
+
|
|
55
|
+
Best for images with estimated processing time < 1 minute. If the task is not completed within the timeout, the tool returns early with a task_id. Use get_image_task_status to continue polling.`, ColorizeImageSyncSchema.shape, async (args) => processImageSync(client, args.image_source, args.type, 'colorize', args.poll_interval, args.timeout));
|
|
56
|
+
registerTool(server, 'denoise_image_sync', `Remove noise from an image (图片降噪/去噪). Use this tool ONLY for denoising noisy or grainy images.
|
|
57
|
+
|
|
58
|
+
Two upload methods are supported:
|
|
59
|
+
1. URL upload: provide an image URL
|
|
60
|
+
2. Local upload: provide a local file path, the MCP Server will auto-upload to TOS object storage
|
|
61
|
+
|
|
62
|
+
Best for images with estimated processing time < 1 minute. If the task is not completed within the timeout, the tool returns early with a task_id. Use get_image_task_status to continue polling.`, DenoiseImageSyncSchema.shape, async (args) => processImageSync(client, args.image_source, args.type, 'denoise', args.poll_interval, args.timeout));
|
|
63
|
+
// ========== Status query tool ==========
|
|
64
|
+
registerTool(server, 'get_image_task_status', 'Query image processing task status. The status field can be: processing, completed, or failed. If status is processing, wait a few seconds and call this tool again to poll.', GetImageTaskStatusSchema.shape, async (args) => {
|
|
65
|
+
const result = await getImageTaskStatus(client, args.task_id);
|
|
66
|
+
return {
|
|
67
|
+
...result,
|
|
68
|
+
// registerTool marks isError on success===false: a terminal failed
|
|
69
|
+
// status is a failed query outcome, not a healthy poll tick.
|
|
70
|
+
success: classifyStatus(result.status) !== 'failed',
|
|
71
|
+
message: result.status === 'processing' ? 'Task is still processing, please check again later' : undefined,
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async function getImageTosSignature(client, fileName) {
|
|
76
|
+
const response = await client.post('/api/v3/contents/generations/tos-signature', {
|
|
77
|
+
file_type: 'image',
|
|
78
|
+
file_name: fileName,
|
|
79
|
+
});
|
|
80
|
+
const unwrapped = unwrapEnvelope(response);
|
|
81
|
+
if (!unwrapped.ok) {
|
|
82
|
+
throw new Error(unwrapped.error);
|
|
83
|
+
}
|
|
84
|
+
return unwrapped.data;
|
|
85
|
+
}
|
|
86
|
+
function getEndpointByTaskType(taskType) {
|
|
87
|
+
switch (taskType) {
|
|
88
|
+
case 'enhance':
|
|
89
|
+
return '/api/v3/contents/generations/image/enhance';
|
|
90
|
+
case 'colorize':
|
|
91
|
+
return '/api/v3/contents/generations/image/colorize';
|
|
92
|
+
case 'denoise':
|
|
93
|
+
return '/api/v3/contents/generations/image/denoise';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function getModelByTaskType(taskType) {
|
|
97
|
+
switch (taskType) {
|
|
98
|
+
case 'enhance':
|
|
99
|
+
return 'avc-image-enhance';
|
|
100
|
+
case 'colorize':
|
|
101
|
+
return 'avc-image-colorize';
|
|
102
|
+
case 'denoise':
|
|
103
|
+
return 'avc-image-denoise';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function createImageTask(client, imageSource, sourceType, taskType, scale) {
|
|
107
|
+
let contentItem;
|
|
108
|
+
if (sourceType === 'local') {
|
|
109
|
+
const fileInfo = checkLocalFile(imageSource, 'image');
|
|
110
|
+
// Step 1: Get TOS signature
|
|
111
|
+
let target;
|
|
112
|
+
try {
|
|
113
|
+
target = parseTosSignature(await getImageTosSignature(client, fileInfo.fileName));
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new Error(`[Step 1: TOS signature failed] ${formatRequestError(error)}`);
|
|
117
|
+
}
|
|
118
|
+
// Step 2: Upload to TOS
|
|
119
|
+
try {
|
|
120
|
+
await uploadToTos(target, fs.createReadStream(imageSource), fileInfo.fileName);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
throw new Error(`[Step 2: TOS upload failed] ${error.message}`);
|
|
124
|
+
}
|
|
125
|
+
contentItem = { type: 'image_file', file_id: target.fileId, file_name: fileInfo.fileName };
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
contentItem = { type: 'image_url', image_url: { url: imageSource } };
|
|
129
|
+
}
|
|
130
|
+
// Step 3: Call image API
|
|
131
|
+
const endpoint = getEndpointByTaskType(taskType);
|
|
132
|
+
const payload = { model: getModelByTaskType(taskType), content: [contentItem] };
|
|
133
|
+
if (scale !== undefined) {
|
|
134
|
+
payload.scale = scale;
|
|
135
|
+
}
|
|
136
|
+
let response;
|
|
137
|
+
try {
|
|
138
|
+
response = await client.post(endpoint, payload);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw new Error(`[Step 3: API call failed] endpoint=${endpoint} ${formatRequestError(error)}`);
|
|
142
|
+
}
|
|
143
|
+
const unwrapped = unwrapEnvelope(response);
|
|
144
|
+
if (!unwrapped.ok) {
|
|
145
|
+
return { success: false, error: unwrapped.error };
|
|
146
|
+
}
|
|
147
|
+
return { success: true, task_id: unwrapped.data.task_id, status: unwrapped.data.status };
|
|
148
|
+
}
|
|
149
|
+
async function getImageTaskStatus(client, taskId, signal) {
|
|
150
|
+
const response = await client.get(`/api/v3/contents/generations/tasks/${encodeURIComponent(taskId)}`, {
|
|
151
|
+
timeout: POLL_REQUEST_TIMEOUT_MS,
|
|
152
|
+
signal,
|
|
153
|
+
});
|
|
154
|
+
const unwrapped = unwrapEnvelope(response);
|
|
155
|
+
if (!unwrapped.ok) {
|
|
156
|
+
throw new Error(unwrapped.error);
|
|
157
|
+
}
|
|
158
|
+
const result = unwrapped.data;
|
|
159
|
+
return {
|
|
160
|
+
task_id: result.task_id,
|
|
161
|
+
status: result.status,
|
|
162
|
+
progress: result.progress ?? 0,
|
|
163
|
+
image_url: result.image_url,
|
|
164
|
+
error_message: result.error_message,
|
|
165
|
+
created_at: result.created_at,
|
|
166
|
+
updated_at: result.updated_at,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
async function processImageSync(client, imageSource, sourceType, taskType, pollInterval, timeout, scale) {
|
|
170
|
+
const createResult = await createImageTask(client, imageSource, sourceType, taskType, scale);
|
|
171
|
+
if (!createResult.success) {
|
|
172
|
+
return createResult;
|
|
173
|
+
}
|
|
174
|
+
return pollUntilTerminal({
|
|
175
|
+
taskId: createResult.task_id,
|
|
176
|
+
timeoutSeconds: timeout,
|
|
177
|
+
pollIntervalSeconds: pollInterval,
|
|
178
|
+
continueHint: 'get_image_task_status',
|
|
179
|
+
fetchStatus: async (signal) => {
|
|
180
|
+
const { task_id, status, ...payload } = await getImageTaskStatus(client, createResult.task_id, signal);
|
|
181
|
+
return { status, payload };
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=image-enhancement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-enhancement.js","sourceRoot":"","sources":["../src/image-enhancement.ts"],"names":[],"mappings":"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"}
|
package/dist/sam3.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
export declare function setupSam3Tools(server: McpServer, baseUrl: string, apiKey: string, pollInterval: number, pollMaxAttempts: number): void;
|
|
3
|
+
/**
|
|
4
|
+
* Last-hop fetch for a completed SAM3 task. Never throws: a download failure
|
|
5
|
+
* becomes a structured object that keeps task_id and the terminal status, so
|
|
6
|
+
* the caller can resume via get_sam3_task_status. A download failure is not
|
|
7
|
+
* a truncated wait and never rewrites the remote status to failed/processing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function fetchSam3ResultPayload(taskId: string, resultUrl: unknown): Promise<Record<string, any>>;
|
|
3
10
|
//# sourceMappingURL=sam3.d.ts.map
|
package/dist/sam3.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sam3.d.ts","sourceRoot":"","sources":["../src/sam3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"sam3.d.ts","sourceRoot":"","sources":["../src/sam3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4BpE,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,IAAI,CA8CN;AAkED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAwB7G"}
|
package/dist/sam3.js
CHANGED
|
@@ -2,12 +2,17 @@ import axios from 'axios';
|
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
import
|
|
5
|
+
import { checkLocalFile, decodeBase64Image, downloadToBuffer, parseTosSignature, unwrapEnvelope, uploadToTos, } from './tos.js';
|
|
6
|
+
import { classifyStatus, POLL_REQUEST_TIMEOUT_MS, pollUntilTerminal, registerTool } from './tooling.js';
|
|
7
|
+
const SAM3_SUCCESS_CODES = new Set([0]);
|
|
6
8
|
const Sam3PredictSchema = z.object({
|
|
7
9
|
imagePath: z.string().optional().describe('Absolute path of a local image file (e.g. C:\\\\Users\\\\xxx\\\\photo.png)'),
|
|
8
10
|
imageUrl: z.string().url().optional().describe('Publicly accessible URL of the image to process'),
|
|
9
|
-
imageBase64: z.string().optional().describe('Base64-encoded image data. Use this when the image is provided as an attachment without a local path'),
|
|
10
|
-
prompt: z.string().describe('Text prompt for mask generation. Must be in English. If the user provides Chinese or other non-English text, translate it to English before calling this tool'),
|
|
11
|
+
imageBase64: z.string().optional().describe('Base64-encoded image data (a data: URL prefix is also accepted). Use this when the image is provided as an attachment without a local path'),
|
|
12
|
+
prompt: z.string().min(1).max(500).describe('Text prompt for mask generation. Must be in English. If the user provides Chinese or other non-English text, translate it to English before calling this tool'),
|
|
13
|
+
});
|
|
14
|
+
const GetSam3TaskStatusSchema = z.object({
|
|
15
|
+
task_id: z.string().describe('SAM3 task ID returned by sam3_predict'),
|
|
11
16
|
});
|
|
12
17
|
export function setupSam3Tools(server, baseUrl, apiKey, pollInterval, pollMaxAttempts) {
|
|
13
18
|
const client = axios.create({
|
|
@@ -18,150 +23,189 @@ export function setupSam3Tools(server, baseUrl, apiKey, pollInterval, pollMaxAtt
|
|
|
18
23
|
},
|
|
19
24
|
timeout: 60000,
|
|
20
25
|
});
|
|
21
|
-
server
|
|
26
|
+
registerTool(server, 'sam3_predict', `Analyze an image using the SAM3 segmentation API to generate inference results (masks, boxes, scores).
|
|
22
27
|
The image can be provided in one of three ways:
|
|
23
28
|
1. imagePath: Absolute path of a local image file (e.g. C:\\Users\\xxx\\photo.png). Use this when the user provides a local file path.
|
|
24
29
|
2. imageUrl: Publicly accessible URL of the image (e.g. https://example.com/photo.jpg). Use this when the user provides a web link.
|
|
25
30
|
3. imageBase64: Base64-encoded image data. Use this when the user uploads or drags-and-drops an image as an attachment and no local path is available.
|
|
26
31
|
In this case, encode the image content as base64 and pass it via this parameter.
|
|
27
32
|
If the user mentions an uploaded image but does not provide a path, URL, or base64 data, ask the user for the local absolute path.
|
|
28
|
-
Prompt must be in English. If the user provides Chinese or other non-English text, translate it to English before calling this tool.`, Sam3PredictSchema.shape, async (args) =>
|
|
33
|
+
Prompt must be in English. If the user provides Chinese or other non-English text, translate it to English before calling this tool.`, Sam3PredictSchema.shape, async (args) => sam3PredictTool(client, pollInterval, pollMaxAttempts, args));
|
|
34
|
+
registerTool(server, 'get_sam3_task_status', 'Query SAM3 image segmentation task status by task_id. Status can be: processing, completed, or failed. If completed, the result URL is returned.', GetSam3TaskStatusSchema.shape, async (args) => {
|
|
29
35
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
const result = await sam3PredictTool(client, pollInterval, pollMaxAttempts, args);
|
|
34
|
-
return {
|
|
35
|
-
content: [{ type: 'text', text: result }],
|
|
36
|
-
};
|
|
36
|
+
const data = await getSam3Result(client, args.task_id);
|
|
37
|
+
return normalizeSam3Status(args.task_id, data);
|
|
37
38
|
}
|
|
38
39
|
catch (error) {
|
|
39
|
-
|
|
40
|
+
// Keep task_id in every failure exit of the status tool, consistent
|
|
41
|
+
// with the polling failure shape.
|
|
40
42
|
return {
|
|
41
|
-
|
|
43
|
+
success: false,
|
|
44
|
+
task_id: args.task_id,
|
|
45
|
+
status: 'unknown',
|
|
46
|
+
error: error instanceof Error ? error.message : String(error),
|
|
42
47
|
};
|
|
43
48
|
}
|
|
44
49
|
});
|
|
45
50
|
}
|
|
51
|
+
function normalizeSam3Status(taskId, data) {
|
|
52
|
+
const kind = classifyStatus(data?.status);
|
|
53
|
+
if (kind === 'ok') {
|
|
54
|
+
return {
|
|
55
|
+
success: true,
|
|
56
|
+
task_id: taskId,
|
|
57
|
+
status: data.status,
|
|
58
|
+
result_url: data.result,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (kind === 'failed') {
|
|
62
|
+
return {
|
|
63
|
+
success: false,
|
|
64
|
+
task_id: taskId,
|
|
65
|
+
status: data.status,
|
|
66
|
+
error: data.error_message || 'Task failed',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (kind === 'unknown') {
|
|
70
|
+
return {
|
|
71
|
+
success: false,
|
|
72
|
+
task_id: taskId,
|
|
73
|
+
status: data?.status ?? 'unknown',
|
|
74
|
+
error: `Unrecognized task status: ${JSON.stringify(data?.status ?? null)}`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
success: true,
|
|
79
|
+
task_id: taskId,
|
|
80
|
+
status: data.status,
|
|
81
|
+
message: 'Task is still processing, please check again later.',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
46
84
|
async function getSam3PostSignature(client, fileName) {
|
|
47
85
|
const response = await client.post('/get_postsignature_url', {
|
|
48
86
|
file_type: 'image',
|
|
49
87
|
file_name: fileName,
|
|
50
88
|
});
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
53
|
-
throw new Error(`get_postsignature_url error: ${
|
|
54
|
-
}
|
|
55
|
-
return data.data;
|
|
56
|
-
}
|
|
57
|
-
async function uploadImageToTos(url, sigData, tosKey, buffer, fileName) {
|
|
58
|
-
const formData = new FormData();
|
|
59
|
-
formData.append('key', tosKey);
|
|
60
|
-
formData.append('policy', sigData.policy);
|
|
61
|
-
formData.append('x-tos-algorithm', sigData.algorithm);
|
|
62
|
-
formData.append('x-tos-credential', sigData.credential);
|
|
63
|
-
formData.append('x-tos-date', sigData.date);
|
|
64
|
-
formData.append('x-tos-signature', sigData.signature);
|
|
65
|
-
formData.append('file', buffer, fileName);
|
|
66
|
-
const response = await axios.post(url, formData, {
|
|
67
|
-
headers: formData.getHeaders(),
|
|
68
|
-
maxBodyLength: Infinity,
|
|
69
|
-
maxContentLength: Infinity,
|
|
70
|
-
});
|
|
71
|
-
if (response.status >= 400) {
|
|
72
|
-
throw new Error(`TOS upload failed: ${response.status} ${response.statusText}`);
|
|
89
|
+
const unwrapped = unwrapEnvelope(response, SAM3_SUCCESS_CODES);
|
|
90
|
+
if (!unwrapped.ok) {
|
|
91
|
+
throw new Error(`get_postsignature_url error: ${unwrapped.error}`);
|
|
73
92
|
}
|
|
93
|
+
return unwrapped.data;
|
|
74
94
|
}
|
|
75
95
|
async function sam3Predict(client, fileId, prompt) {
|
|
76
96
|
const response = await client.post('/predict', { file_id: fileId, prompt });
|
|
77
|
-
|
|
97
|
+
const body = response.data;
|
|
98
|
+
if (!body || typeof body !== 'object' || typeof body.task_id !== 'string' || !body.task_id) {
|
|
99
|
+
const preview = typeof body === 'string' ? body.slice(0, 200) : JSON.stringify(body)?.slice(0, 200);
|
|
100
|
+
throw new Error(`Unexpected /predict response: ${preview}`);
|
|
101
|
+
}
|
|
102
|
+
return body.task_id;
|
|
78
103
|
}
|
|
79
104
|
async function downloadSam3Result(url) {
|
|
80
|
-
const response = await axios.get(url);
|
|
105
|
+
const response = await axios.get(url, { timeout: 30000 });
|
|
81
106
|
return response.data;
|
|
82
107
|
}
|
|
108
|
+
const SAM3_RESULT_DOWNLOAD_NOTE = 'The task has completed; only the result download failed. Do not resubmit. Use get_sam3_task_status with this task_id to recover the result.';
|
|
109
|
+
/**
|
|
110
|
+
* Last-hop fetch for a completed SAM3 task. Never throws: a download failure
|
|
111
|
+
* becomes a structured object that keeps task_id and the terminal status, so
|
|
112
|
+
* the caller can resume via get_sam3_task_status. A download failure is not
|
|
113
|
+
* a truncated wait and never rewrites the remote status to failed/processing.
|
|
114
|
+
*/
|
|
115
|
+
export async function fetchSam3ResultPayload(taskId, resultUrl) {
|
|
116
|
+
if (typeof resultUrl !== 'string' || resultUrl.trim() === '') {
|
|
117
|
+
return {
|
|
118
|
+
success: false,
|
|
119
|
+
task_id: taskId,
|
|
120
|
+
status: 'completed',
|
|
121
|
+
error: `Task ${taskId} completed but has no usable result_url; use get_sam3_task_status with this task_id to recover.`,
|
|
122
|
+
note: SAM3_RESULT_DOWNLOAD_NOTE,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const data = await downloadSam3Result(resultUrl);
|
|
127
|
+
return { success: true, task_id: taskId, status: 'completed', result_url: resultUrl, result: data };
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
131
|
+
return {
|
|
132
|
+
success: false,
|
|
133
|
+
task_id: taskId,
|
|
134
|
+
status: 'completed',
|
|
135
|
+
result_url: resultUrl,
|
|
136
|
+
error: `Failed to download the completed result for task ${taskId}: ${message}`,
|
|
137
|
+
note: SAM3_RESULT_DOWNLOAD_NOTE,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
83
141
|
async function prepareImageBuffer(args) {
|
|
84
142
|
const { imagePath, imageUrl, imageBase64 } = args;
|
|
85
|
-
if (!imagePath && !imageUrl && !imageBase64) {
|
|
86
|
-
throw new Error('Missing image input: must provide one of imagePath, imageUrl, or imageBase64');
|
|
87
|
-
}
|
|
88
|
-
let buffer;
|
|
89
|
-
let fileName;
|
|
90
143
|
if (imagePath) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
fileName = path.basename(imagePath);
|
|
95
|
-
buffer = fs.readFileSync(imagePath);
|
|
96
|
-
}
|
|
97
|
-
else if (imageUrl) {
|
|
98
|
-
const response = await axios.get(imageUrl, { responseType: 'arraybuffer' });
|
|
99
|
-
buffer = Buffer.from(response.data);
|
|
100
|
-
fileName = path.basename(new URL(imageUrl).pathname) || 'image.png';
|
|
144
|
+
checkLocalFile(imagePath, 'image');
|
|
145
|
+
return { buffer: fs.readFileSync(imagePath), fileName: path.basename(imagePath) };
|
|
101
146
|
}
|
|
102
|
-
|
|
103
|
-
buffer =
|
|
104
|
-
fileName = 'image.png';
|
|
147
|
+
if (imageUrl) {
|
|
148
|
+
const buffer = await downloadToBuffer(imageUrl);
|
|
149
|
+
const fileName = path.basename(new URL(imageUrl).pathname) || 'image.png';
|
|
150
|
+
return { buffer, fileName };
|
|
105
151
|
}
|
|
106
|
-
|
|
107
|
-
|
|
152
|
+
if (imageBase64) {
|
|
153
|
+
return decodeBase64Image(imageBase64);
|
|
108
154
|
}
|
|
109
|
-
|
|
155
|
+
throw new Error('Missing image input: must provide one of imagePath, imageUrl, or imageBase64');
|
|
110
156
|
}
|
|
111
157
|
async function sam3CreateTask(client, buffer, fileName, prompt) {
|
|
112
158
|
const signatureData = await getSam3PostSignature(client, fileName);
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
const keyObj = JSON.parse(origin_policy).conditions.find((c) => 'key' in c);
|
|
118
|
-
const tosKey = keyObj ? keyObj.key : new URL(url).pathname.slice(1);
|
|
119
|
-
const fileId = new URL(url).pathname.split('/').pop();
|
|
120
|
-
if (!fileId) {
|
|
121
|
-
throw new Error('Could not extract file_id from upload URL');
|
|
122
|
-
}
|
|
123
|
-
await uploadImageToTos(url, signatureData, tosKey, buffer, fileName);
|
|
124
|
-
const taskId = await sam3Predict(client, fileId, prompt);
|
|
125
|
-
return taskId;
|
|
126
|
-
}
|
|
127
|
-
async function getSam3Result(client, taskId) {
|
|
128
|
-
const response = await client.get(`/predict/result/${encodeURIComponent(taskId)}`);
|
|
129
|
-
return response.data;
|
|
159
|
+
const target = parseTosSignature(signatureData);
|
|
160
|
+
await uploadToTos(target, buffer, fileName);
|
|
161
|
+
return sam3Predict(client, target.fileId, prompt);
|
|
130
162
|
}
|
|
131
|
-
async function
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
163
|
+
async function getSam3Result(client, taskId, signal) {
|
|
164
|
+
const response = await client.get(`/predict/result/${encodeURIComponent(taskId)}`, {
|
|
165
|
+
timeout: POLL_REQUEST_TIMEOUT_MS,
|
|
166
|
+
signal,
|
|
167
|
+
});
|
|
168
|
+
const data = response.data;
|
|
169
|
+
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
|
170
|
+
throw new Error(`Unexpected task status response (HTTP ${response.status})`);
|
|
171
|
+
}
|
|
172
|
+
// The endpoint's success body shape is not confirmed against a live backend
|
|
173
|
+
// (envelope {code:0,data:{...}} or bare {status,...}); unwrap only when the
|
|
174
|
+
// body is shaped like an envelope, so auth/business errors surface with
|
|
175
|
+
// their real message instead of degrading to "Unrecognized task status".
|
|
176
|
+
if ('code' in data) {
|
|
177
|
+
const unwrapped = unwrapEnvelope(response, SAM3_SUCCESS_CODES);
|
|
178
|
+
if (!unwrapped.ok) {
|
|
179
|
+
throw new Error(`Task status request failed: ${unwrapped.error}`);
|
|
139
180
|
}
|
|
140
|
-
|
|
181
|
+
return unwrapped.data;
|
|
141
182
|
}
|
|
142
|
-
return
|
|
143
|
-
success: true,
|
|
144
|
-
status: 'processing',
|
|
145
|
-
task_id: taskId,
|
|
146
|
-
message: `Task is still processing (waited about ${Math.round(pollMaxAttempts * pollInterval / 1000)} seconds). Please retry later or record this task_id for manual follow-up.`,
|
|
147
|
-
note: 'The synchronous wait for this long-running task has been truncated.',
|
|
148
|
-
};
|
|
183
|
+
return data;
|
|
149
184
|
}
|
|
150
185
|
async function sam3PredictTool(client, pollInterval, pollMaxAttempts, args) {
|
|
151
|
-
if (!args.prompt) {
|
|
152
|
-
throw new Error('Missing argument: prompt');
|
|
153
|
-
}
|
|
154
186
|
const { buffer, fileName } = await prepareImageBuffer(args);
|
|
155
187
|
const taskId = await sam3CreateTask(client, buffer, fileName, args.prompt);
|
|
156
|
-
const taskResult = await
|
|
157
|
-
|
|
158
|
-
|
|
188
|
+
const taskResult = await pollUntilTerminal({
|
|
189
|
+
taskId,
|
|
190
|
+
timeoutSeconds: (pollInterval * pollMaxAttempts) / 1000,
|
|
191
|
+
pollIntervalSeconds: pollInterval / 1000,
|
|
192
|
+
maxAttempts: pollMaxAttempts,
|
|
193
|
+
continueHint: 'get_sam3_task_status',
|
|
194
|
+
fetchStatus: async (signal) => {
|
|
195
|
+
const data = await getSam3Result(client, taskId, signal);
|
|
196
|
+
return {
|
|
197
|
+
status: data.status,
|
|
198
|
+
payload: { result_url: data.result, error_message: data.error_message },
|
|
199
|
+
};
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
if (!taskResult.success || taskResult.status === 'processing') {
|
|
203
|
+
return taskResult;
|
|
159
204
|
}
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
205
|
+
const outcome = await fetchSam3ResultPayload(taskResult.task_id, taskResult.result_url);
|
|
206
|
+
if (!outcome.success) {
|
|
207
|
+
return outcome;
|
|
208
|
+
}
|
|
209
|
+
return JSON.stringify(outcome.result, null, 2);
|
|
166
210
|
}
|
|
167
211
|
//# sourceMappingURL=sam3.js.map
|
package/dist/sam3.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sam3.js","sourceRoot":"","sources":["../src/sam3.ts"],"names":[],"mappings":"AACA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,
|
|
1
|
+
{"version":3,"file":"sam3.js","sourceRoot":"","sources":["../src/sam3.ts"],"names":[],"mappings":"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"}
|