@yanickxia/agent-vision 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 +137 -11
- package/dist/cli.js +51 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +79 -14
- package/dist/config.js.map +1 -1
- package/dist/generate.d.ts +16 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +167 -0
- package/dist/generate.js.map +1 -0
- package/dist/generation-provider.d.ts +24 -0
- package/dist/generation-provider.d.ts.map +1 -0
- package/dist/generation-provider.js +101 -0
- package/dist/generation-provider.js.map +1 -0
- package/dist/image.d.ts +1 -0
- package/dist/image.d.ts.map +1 -1
- package/dist/image.js +1 -1
- package/dist/image.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +36 -1
- package/dist/server.js.map +1 -1
- package/package.json +3 -2
- package/skills/agent-vision/SKILL.md +51 -8
- package/skills/agent-vision/references/configuration.md +107 -5
package/dist/generate.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { open, unlink } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { loadConfig } from "./config.js";
|
|
5
|
+
import { errorMessage, VisionError } from "./errors.js";
|
|
6
|
+
import { generationAdapter } from "./generation-provider.js";
|
|
7
|
+
import { mimeFromMagic } from "./image.js";
|
|
8
|
+
import { fetchRemoteBuffer } from "./network.js";
|
|
9
|
+
async function readResponse(response, maxBytes) {
|
|
10
|
+
if (!response.body)
|
|
11
|
+
return "";
|
|
12
|
+
const chunks = [];
|
|
13
|
+
let total = 0;
|
|
14
|
+
const reader = response.body.getReader();
|
|
15
|
+
while (true) {
|
|
16
|
+
const { done, value } = await reader.read();
|
|
17
|
+
if (done)
|
|
18
|
+
break;
|
|
19
|
+
total += value.byteLength;
|
|
20
|
+
if (total > maxBytes) {
|
|
21
|
+
await reader.cancel();
|
|
22
|
+
throw new VisionError("SOURCE_TOO_LARGE", "Image generation API response exceeds the configured limit");
|
|
23
|
+
}
|
|
24
|
+
chunks.push(Buffer.from(value));
|
|
25
|
+
}
|
|
26
|
+
return Buffer.concat(chunks, total).toString("utf8");
|
|
27
|
+
}
|
|
28
|
+
async function requestImageGeneration(options, config, target) {
|
|
29
|
+
const adapter = generationAdapter(target);
|
|
30
|
+
const { url, body } = adapter.createRequest(target, options);
|
|
31
|
+
const headers = new Headers(target.headers);
|
|
32
|
+
headers.set("content-type", "application/json");
|
|
33
|
+
if (target.apiKey && !headers.has("authorization")) {
|
|
34
|
+
headers.set("authorization", `Bearer ${target.apiKey}`);
|
|
35
|
+
}
|
|
36
|
+
const controller = new AbortController();
|
|
37
|
+
const timer = setTimeout(() => controller.abort(), config.timeoutMs);
|
|
38
|
+
let response;
|
|
39
|
+
let raw;
|
|
40
|
+
try {
|
|
41
|
+
response = await fetch(url, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers,
|
|
44
|
+
body: JSON.stringify(body),
|
|
45
|
+
signal: controller.signal,
|
|
46
|
+
});
|
|
47
|
+
// Allow base64 expansion and JSON metadata without an unbounded response.text().
|
|
48
|
+
raw = await readResponse(response, Math.ceil(config.maxImageBytes * 4 / 3) + 65_536);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (controller.signal.aborted) {
|
|
52
|
+
throw new VisionError("API_TIMEOUT", `Image generation API timed out after ${config.timeoutMs} ms`);
|
|
53
|
+
}
|
|
54
|
+
if (error instanceof VisionError)
|
|
55
|
+
throw error;
|
|
56
|
+
throw new VisionError("API_ERROR", "Could not reach the image generation API", { cause: error });
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
clearTimeout(timer);
|
|
60
|
+
}
|
|
61
|
+
const { source, ...metadata } = adapter.parseResponse(target, response, raw);
|
|
62
|
+
let buffer;
|
|
63
|
+
if (source.kind === "base64") {
|
|
64
|
+
const compact = source.value.replace(/\s/g, "");
|
|
65
|
+
if (compact.length % 4 !== 0 || /[^A-Za-z0-9+/=]/.test(compact)) {
|
|
66
|
+
throw new VisionError("API_RESPONSE_ERROR", "Image generation API returned invalid base64");
|
|
67
|
+
}
|
|
68
|
+
buffer = Buffer.from(compact, "base64");
|
|
69
|
+
if (buffer.toString("base64") !== compact) {
|
|
70
|
+
throw new VisionError("API_RESPONSE_ERROR", "Image generation API returned invalid base64");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// Provider URLs are untrusted too; never treat them as local file paths or
|
|
75
|
+
// forward API credentials to the image host.
|
|
76
|
+
const remote = await fetchRemoteBuffer({
|
|
77
|
+
url: source.value,
|
|
78
|
+
maxBytes: config.maxImageBytes,
|
|
79
|
+
timeoutMs: config.timeoutMs,
|
|
80
|
+
allowPrivateUrls: config.allowPrivateUrls,
|
|
81
|
+
});
|
|
82
|
+
buffer = remote.buffer;
|
|
83
|
+
}
|
|
84
|
+
if (buffer.length > config.maxImageBytes) {
|
|
85
|
+
throw new VisionError("SOURCE_TOO_LARGE", "Generated image exceeds the configured limit");
|
|
86
|
+
}
|
|
87
|
+
const mimeType = mimeFromMagic(buffer);
|
|
88
|
+
if (!mimeType) {
|
|
89
|
+
throw new VisionError("UNSUPPORTED_IMAGE", "Image generation API returned an unsupported or invalid image");
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
data: buffer.toString("base64"),
|
|
93
|
+
mimeType,
|
|
94
|
+
bytes: buffer.length,
|
|
95
|
+
...metadata,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async function tryGenerationTargets(options, config) {
|
|
99
|
+
const failures = [];
|
|
100
|
+
for (const target of config.generationTargets) {
|
|
101
|
+
try {
|
|
102
|
+
return await requestImageGeneration(options, config, target);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (config.generationTargets.length === 1)
|
|
106
|
+
throw error;
|
|
107
|
+
failures.push(`${target.label}: ${errorMessage(error)}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
throw new VisionError("API_ERROR", `All image generation model targets failed:\n${failures.join("\n")}`);
|
|
111
|
+
}
|
|
112
|
+
export async function generateImage(options) {
|
|
113
|
+
const prompt = options.prompt.trim();
|
|
114
|
+
if (!prompt)
|
|
115
|
+
throw new VisionError("INVALID_INPUT", "Image generation requires a non-empty prompt");
|
|
116
|
+
for (const key of ["size", "quality"]) {
|
|
117
|
+
if (options[key] !== undefined && !options[key]?.trim()) {
|
|
118
|
+
throw new VisionError("INVALID_INPUT", `${key} must be a non-empty string`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const config = options.config ?? loadConfig();
|
|
122
|
+
if (config.generationTargets.length === 0) {
|
|
123
|
+
throw new VisionError("CONFIG_ERROR", "No image generation model configured. Add generationProviders to the settings file or set AGENT_VISION_GENERATION_MODEL");
|
|
124
|
+
}
|
|
125
|
+
let outputPath;
|
|
126
|
+
let file;
|
|
127
|
+
if (options.outputPath !== undefined) {
|
|
128
|
+
if (!options.outputPath.trim()) {
|
|
129
|
+
throw new VisionError("INVALID_INPUT", "outputPath must be a non-empty local file path");
|
|
130
|
+
}
|
|
131
|
+
outputPath = options.outputPath.startsWith("~/")
|
|
132
|
+
? path.join(homedir(), options.outputPath.slice(2))
|
|
133
|
+
: path.resolve(options.outputPath);
|
|
134
|
+
try {
|
|
135
|
+
// Reserve the destination before a paid API call. Never overwrite an
|
|
136
|
+
// existing file or follow a symlink; the parent directory must exist.
|
|
137
|
+
file = await open(outputPath, "wx", 0o600);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
throw new VisionError("OUTPUT_ERROR", `Cannot create output file ${outputPath}: ${errorMessage(error)}`, { cause: error });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
let saved = false;
|
|
144
|
+
try {
|
|
145
|
+
const result = await tryGenerationTargets({
|
|
146
|
+
prompt,
|
|
147
|
+
...(options.size ? { size: options.size.trim() } : {}),
|
|
148
|
+
...(options.quality ? { quality: options.quality.trim() } : {}),
|
|
149
|
+
}, config);
|
|
150
|
+
if (file) {
|
|
151
|
+
try {
|
|
152
|
+
await file.writeFile(Buffer.from(result.data, "base64"));
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw new VisionError("OUTPUT_ERROR", `Could not write generated image to ${outputPath}`, { cause: error });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
saved = true;
|
|
159
|
+
return { ...result, ...(outputPath ? { outputPath } : {}) };
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
await file?.close();
|
|
163
|
+
if (outputPath && !saved)
|
|
164
|
+
await unlink(outputPath);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type GenerationTarget } from "./config.js";
|
|
2
|
+
export interface GenerationOptions {
|
|
3
|
+
prompt: string;
|
|
4
|
+
size?: string;
|
|
5
|
+
quality?: string;
|
|
6
|
+
}
|
|
7
|
+
interface GenerationResponse {
|
|
8
|
+
source: {
|
|
9
|
+
kind: "base64" | "url";
|
|
10
|
+
value: string;
|
|
11
|
+
};
|
|
12
|
+
model: string;
|
|
13
|
+
revisedPrompt?: string;
|
|
14
|
+
}
|
|
15
|
+
interface GenerationAdapter {
|
|
16
|
+
createRequest(target: GenerationTarget, options: GenerationOptions): {
|
|
17
|
+
url: string;
|
|
18
|
+
body: Record<string, unknown>;
|
|
19
|
+
};
|
|
20
|
+
parseResponse(target: GenerationTarget, response: Response, raw: string): GenerationResponse;
|
|
21
|
+
}
|
|
22
|
+
export declare function generationAdapter(target: GenerationTarget): GenerationAdapter;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=generation-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation-provider.d.ts","sourceRoot":"","sources":["../src/generation-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGzE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,kBAAkB;IAC1B,MAAM,EAAE;QAAE,IAAI,EAAE,QAAQ,GAAG,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,iBAAiB;IACzB,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,iBAAiB,GAAG;QACnE,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC/B,CAAC;IACF,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAC;CAC9F;AAsGD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,CAO7E"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { imageGenerationsUrl } from "./config.js";
|
|
2
|
+
import { VisionError } from "./errors.js";
|
|
3
|
+
function asRecord(value) {
|
|
4
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
5
|
+
? value
|
|
6
|
+
: undefined;
|
|
7
|
+
}
|
|
8
|
+
function errorDetail(value, includeCode) {
|
|
9
|
+
const error = asRecord(value);
|
|
10
|
+
const code = includeCode && typeof error?.code === "string" ? error.code : undefined;
|
|
11
|
+
const message = typeof error?.message === "string" ? error.message : undefined;
|
|
12
|
+
return [code, message].filter(Boolean).join(": ") || undefined;
|
|
13
|
+
}
|
|
14
|
+
// Both protocols use a data[] envelope. Keep response normalization here,
|
|
15
|
+
// separate from image decoding, downloading, limits and output file handling.
|
|
16
|
+
function parseImagesResponse(target, response, raw, ark = false) {
|
|
17
|
+
const name = ark ? "Volcengine Ark API" : "Image generation API";
|
|
18
|
+
let payload;
|
|
19
|
+
try {
|
|
20
|
+
payload = JSON.parse(raw);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
payload = undefined;
|
|
24
|
+
}
|
|
25
|
+
const record = asRecord(payload);
|
|
26
|
+
if (!response.ok) {
|
|
27
|
+
const detail = errorDetail(record?.error, ark) ?? (raw.slice(0, 500) || response.statusText);
|
|
28
|
+
throw new VisionError("API_ERROR", `${name} returned HTTP ${response.status}: ${detail}`);
|
|
29
|
+
}
|
|
30
|
+
if (!record) {
|
|
31
|
+
throw new VisionError("API_RESPONSE_ERROR", `${name} returned invalid JSON`);
|
|
32
|
+
}
|
|
33
|
+
const first = Array.isArray(record.data) ? asRecord(record.data[0]) : undefined;
|
|
34
|
+
// Ark may report generation failures in a successful HTTP response, at the
|
|
35
|
+
// top level or on data[0]. Do not lose its diagnostic code and message.
|
|
36
|
+
if (ark && (record.error || first?.error)) {
|
|
37
|
+
const detail = errorDetail(record.error ?? first?.error, true) ?? "Unknown image generation error";
|
|
38
|
+
throw new VisionError("API_ERROR", `${name}: ${detail}`);
|
|
39
|
+
}
|
|
40
|
+
let source;
|
|
41
|
+
if (typeof first?.b64_json === "string" && first.b64_json.trim()) {
|
|
42
|
+
source = { kind: "base64", value: first.b64_json };
|
|
43
|
+
}
|
|
44
|
+
else if (typeof first?.url === "string" && first.url.trim()) {
|
|
45
|
+
source = { kind: "url", value: first.url };
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
throw new VisionError("API_RESPONSE_ERROR", `${name} response is missing data[0].b64_json or data[0].url`);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
source,
|
|
52
|
+
model: typeof record.model === "string" ? record.model : target.model,
|
|
53
|
+
...(typeof first?.revised_prompt === "string" ? { revisedPrompt: first.revised_prompt } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const openaiImages = {
|
|
57
|
+
createRequest(target, options) {
|
|
58
|
+
return {
|
|
59
|
+
url: imageGenerationsUrl(target.baseUrl),
|
|
60
|
+
body: {
|
|
61
|
+
model: target.model,
|
|
62
|
+
prompt: options.prompt,
|
|
63
|
+
n: 1,
|
|
64
|
+
...(options.size ? { size: options.size } : {}),
|
|
65
|
+
...(options.quality ? { quality: options.quality } : {}),
|
|
66
|
+
// Some image models reject response_format. Accept either response form.
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
parseResponse: (target, response, raw) => parseImagesResponse(target, response, raw),
|
|
71
|
+
};
|
|
72
|
+
const volcengineArk = {
|
|
73
|
+
createRequest(target, options) {
|
|
74
|
+
if (options.quality !== undefined) {
|
|
75
|
+
throw new VisionError("INVALID_INPUT", "volcengine-ark does not support quality; omit --quality / quality and use a model-supported size instead");
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
url: imageGenerationsUrl(target.baseUrl),
|
|
79
|
+
body: {
|
|
80
|
+
model: target.model,
|
|
81
|
+
prompt: options.prompt,
|
|
82
|
+
response_format: "b64_json",
|
|
83
|
+
...(options.size ? { size: options.size } : {}),
|
|
84
|
+
// Ark defaults to one image and non-streaming output. Do not send n,
|
|
85
|
+
// quality, or model-specific sequential_image_generation / stream flags:
|
|
86
|
+
// newer Seedream models and opaque ep-* IDs need the same safe payload.
|
|
87
|
+
// Leave watermark and output_format at the provider's defaults.
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
parseResponse: (target, response, raw) => parseImagesResponse(target, response, raw, true),
|
|
92
|
+
};
|
|
93
|
+
export function generationAdapter(target) {
|
|
94
|
+
const type = target.type ?? "openai-images";
|
|
95
|
+
switch (type) {
|
|
96
|
+
case "openai-images": return openaiImages;
|
|
97
|
+
case "volcengine-ark": return volcengineArk;
|
|
98
|
+
default: throw new VisionError("CONFIG_ERROR", `Unsupported image generation provider type: ${type}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=generation-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation-provider.js","sourceRoot":"","sources":["../src/generation-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAyB,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAsB1C,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAChE,CAAC,CAAC,KAAgC;QAClC,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,KAAc,EAAE,WAAoB;IACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,WAAW,IAAI,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACrF,MAAM,OAAO,GAAG,OAAO,KAAK,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;AACjE,CAAC;AAED,0EAA0E;AAC1E,8EAA8E;AAC9E,SAAS,mBAAmB,CAC1B,MAAwB,EACxB,QAAkB,EAClB,GAAW,EACX,GAAG,GAAG,KAAK;IAEX,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,sBAAsB,CAAC;IACjE,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,SAAS,CAAC;IACtB,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC7F,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,GAAG,IAAI,kBAAkB,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,WAAW,CAAC,oBAAoB,EAAE,GAAG,IAAI,wBAAwB,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,2EAA2E;IAC3E,wEAAwE;IACxE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,gCAAgC,CAAC;QACnG,MAAM,IAAI,WAAW,CAAC,WAAW,EAAE,GAAG,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,MAAoC,CAAC;IACzC,IAAI,OAAO,KAAK,EAAE,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QACjE,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;IACrD,CAAC;SAAM,IAAI,OAAO,KAAK,EAAE,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9D,MAAM,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,WAAW,CAAC,oBAAoB,EAAE,GAAG,IAAI,sDAAsD,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO;QACL,MAAM;QACN,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK;QACrE,GAAG,CAAC,OAAO,KAAK,EAAE,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9F,CAAC;AACJ,CAAC;AAED,MAAM,YAAY,GAAsB;IACtC,aAAa,CAAC,MAAM,EAAE,OAAO;QAC3B,OAAO;YACL,GAAG,EAAE,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC;YACxC,IAAI,EAAE;gBACJ,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,CAAC,EAAE,CAAC;gBACJ,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/C,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxD,yEAAyE;aAC1E;SACF,CAAC;IACJ,CAAC;IACD,aAAa,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC;CACrF,CAAC;AAEF,MAAM,aAAa,GAAsB;IACvC,aAAa,CAAC,MAAM,EAAE,OAAO;QAC3B,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClC,MAAM,IAAI,WAAW,CACnB,eAAe,EACf,0GAA0G,CAC3G,CAAC;QACJ,CAAC;QACD,OAAO;YACL,GAAG,EAAE,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC;YACxC,IAAI,EAAE;gBACJ,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,eAAe,EAAE,UAAU;gBAC3B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/C,qEAAqE;gBACrE,yEAAyE;gBACzE,wEAAwE;gBACxE,gEAAgE;aACjE;SACF,CAAC;IACJ,CAAC;IACD,aAAa,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC;CAC3F,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,MAAwB;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,eAAe,CAAC;IAC5C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,eAAe,CAAC,CAAC,OAAO,YAAY,CAAC;QAC1C,KAAK,gBAAgB,CAAC,CAAC,OAAO,aAAa,CAAC;QAC5C,OAAO,CAAC,CAAC,MAAM,IAAI,WAAW,CAAC,cAAc,EAAE,+CAA+C,IAAI,EAAE,CAAC,CAAC;IACxG,CAAC;AACH,CAAC"}
|
package/dist/image.d.ts
CHANGED
|
@@ -5,5 +5,6 @@ export interface LoadedImage {
|
|
|
5
5
|
bytes: number;
|
|
6
6
|
label: string;
|
|
7
7
|
}
|
|
8
|
+
export declare function mimeFromMagic(buffer: Buffer): string | undefined;
|
|
8
9
|
export declare function loadImage(source: string, config: VisionConfig): Promise<LoadedImage>;
|
|
9
10
|
//# sourceMappingURL=image.d.ts.map
|
package/dist/image.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAUD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAoBhE;AAgDD,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,WAAW,CAAC,CAqCtB"}
|
package/dist/image.js
CHANGED
|
@@ -10,7 +10,7 @@ const SUPPORTED_MIME_TYPES = new Set([
|
|
|
10
10
|
"image/gif",
|
|
11
11
|
"image/bmp",
|
|
12
12
|
]);
|
|
13
|
-
function mimeFromMagic(buffer) {
|
|
13
|
+
export function mimeFromMagic(buffer) {
|
|
14
14
|
if (buffer.length >= 3 && buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff) {
|
|
15
15
|
return "image/jpeg";
|
|
16
16
|
}
|
package/dist/image.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.js","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AASjD,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,WAAW;IACX,WAAW;CACZ,CAAC,CAAC;AAEH,
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
export declare const SERVER_VERSION = "0.
|
|
2
|
+
export declare const SERVER_VERSION = "0.3.0";
|
|
3
3
|
export declare function createServer(): McpServer;
|
|
4
4
|
export declare function startStdioServer(): Promise<void>;
|
|
5
5
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,eAAO,MAAM,cAAc,UAAU,CAAC;AAStC,wBAAgB,YAAY,IAAI,SAAS,CA6FxC;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD"}
|
package/dist/server.js
CHANGED
|
@@ -3,7 +3,8 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { analyzeImage, analyzeVideo } from "./analyze.js";
|
|
5
5
|
import { errorMessage } from "./errors.js";
|
|
6
|
-
|
|
6
|
+
import { generateImage } from "./generate.js";
|
|
7
|
+
export const SERVER_VERSION = "0.3.0";
|
|
7
8
|
function failure(error) {
|
|
8
9
|
return {
|
|
9
10
|
content: [{ type: "text", text: errorMessage(error) }],
|
|
@@ -52,6 +53,40 @@ export function createServer() {
|
|
|
52
53
|
return failure(error);
|
|
53
54
|
}
|
|
54
55
|
});
|
|
56
|
+
server.registerTool("generate_image", {
|
|
57
|
+
title: "Generate image",
|
|
58
|
+
description: "Generate one image from a text prompt using configured OpenAI-compatible or Volcengine Ark (Seedream) providers. Uses the same settings as the standalone CLI. Returns image content and metadata; optionally saves to a new local file. This is image creation, not image analysis, and works regardless of native vision capability.",
|
|
59
|
+
inputSchema: z.object({
|
|
60
|
+
prompt: z.string().trim().min(1).describe("Description of the image to create"),
|
|
61
|
+
output_path: z.string().trim().min(1).optional().describe("Optional local file path; parent must exist and file must not exist"),
|
|
62
|
+
size: z.string().trim().min(1).optional().describe("Provider-supported image size, e.g. 1024x1024 or 2K for Ark; omitted uses provider default"),
|
|
63
|
+
quality: z.string().trim().min(1).optional().describe("OpenAI-compatible quality; not supported by volcengine-ark, omit for Ark"),
|
|
64
|
+
}),
|
|
65
|
+
annotations: {
|
|
66
|
+
readOnlyHint: false,
|
|
67
|
+
destructiveHint: false,
|
|
68
|
+
idempotentHint: false,
|
|
69
|
+
openWorldHint: true,
|
|
70
|
+
},
|
|
71
|
+
}, async ({ prompt, output_path, size, quality }) => {
|
|
72
|
+
try {
|
|
73
|
+
const { data, ...metadata } = await generateImage({
|
|
74
|
+
prompt,
|
|
75
|
+
...(output_path ? { outputPath: output_path } : {}),
|
|
76
|
+
...(size ? { size } : {}),
|
|
77
|
+
...(quality ? { quality } : {}),
|
|
78
|
+
});
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{ type: "text", text: JSON.stringify(metadata) },
|
|
82
|
+
{ type: "image", data, mimeType: metadata.mimeType },
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return failure(error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
55
90
|
return server;
|
|
56
91
|
}
|
|
57
92
|
export async function startStdioServer() {
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yanickxia/agent-vision",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A small MCP server and Agent Skill for image and
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "A small MCP server and Agent Skill for image/video understanding and image generation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cli.js",
|
|
7
7
|
"bin": {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"agent-skills",
|
|
30
30
|
"vision",
|
|
31
31
|
"image-understanding",
|
|
32
|
+
"image-generation",
|
|
32
33
|
"video-understanding",
|
|
33
34
|
"openai-compatible"
|
|
34
35
|
],
|
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-vision
|
|
3
|
-
description:
|
|
3
|
+
description: Generate images from text using configured image APIs; analyze videos through sampled frames; provide fallback image understanding when native vision is unavailable or failed. For image analysis only, if you can see the image natively, look directly instead of using this skill. Native vision does not replace image generation.
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: Node.js 20+ for the CLI; the MCP server is optional.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# agent-vision
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
The Skill runs the standalone CLI; no MCP server is required. CLI and MCP read
|
|
11
|
+
the same `agent-vision/settings.json` (`AGENT_VISION_CONFIG` can override its
|
|
12
|
+
location) and use the same provider adapters, including Volcengine Ark.
|
|
13
|
+
|
|
14
|
+
## Choose the capability
|
|
15
|
+
|
|
16
|
+
For **image generation**, skip the vision gate and use `generate` below.
|
|
17
|
+
This creates a new bitmap from text; it does not edit an existing image.
|
|
18
|
+
|
|
19
|
+
For **image analysis**, apply the following gate:
|
|
11
20
|
|
|
12
21
|
If you can read images natively (for example the Read tool in Claude Code or
|
|
13
22
|
built-in multimodal input), look at the image yourself and answer directly.
|
|
14
23
|
Do not load or run anything from this skill for an image you can already see.
|
|
15
|
-
|
|
16
|
-
native image reading failed.
|
|
24
|
+
Image analysis through this skill is a fallback for agents without native
|
|
25
|
+
vision or when native image reading failed.
|
|
17
26
|
|
|
18
27
|
Videos are the exception: no agent can watch a video natively. Video analysis
|
|
19
28
|
always goes through the CLI below.
|
|
20
29
|
|
|
21
|
-
##
|
|
30
|
+
## Analyze with the CLI
|
|
22
31
|
|
|
23
32
|
When you cannot see the input yourself (or it is a video), run the analysis
|
|
24
33
|
directly and read the plain-text output:
|
|
@@ -30,8 +39,11 @@ npx -y @yanickxia/agent-vision video "/absolute/path/to/demo.mp4" --prompt "Summ
|
|
|
30
39
|
|
|
31
40
|
If the package is installed locally, run `agent-vision image ...` instead of
|
|
32
41
|
`npx -y @yanickxia/agent-vision ...`.
|
|
42
|
+
For a source checkout, run `npm run build` in that checkout once, then use
|
|
43
|
+
`node /absolute/path/to/agent-vision/dist/cli.js ...` for any CLI command.
|
|
44
|
+
This uses the checkout's implementation rather than an older published package.
|
|
33
45
|
|
|
34
|
-
##
|
|
46
|
+
## Analysis calling rules
|
|
35
47
|
|
|
36
48
|
1. Pass the user's original question as `--prompt`. A focused question is
|
|
37
49
|
better than a generic request for a description.
|
|
@@ -44,5 +56,36 @@ If the package is installed locally, run `agent-vision image ...` instead of
|
|
|
44
56
|
5. Retry at most once for a transient API or timeout error. Configuration,
|
|
45
57
|
unsupported-format, and missing-file errors require correction, not retries.
|
|
46
58
|
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
## Generate an image
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx -y @yanickxia/agent-vision generate --prompt "A watercolor orange cat sitting by a window" --output "/absolute/path/to/cat.png"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
With a configured Volcengine Ark provider:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx -y @yanickxia/agent-vision generate --prompt "A watercolor orange cat sitting by a window" --output "/absolute/path/to/cat.jpg" --size 2K
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- Pass the requested image description as `--prompt` (or `-p`).
|
|
72
|
+
- Choose a new local file via `--output` (or `-o`); its parent directory must
|
|
73
|
+
exist. Existing files are never overwritten. Successful stdout is the saved
|
|
74
|
+
absolute path. The file keeps the provider's actual image format; the filename
|
|
75
|
+
extension does not convert it.
|
|
76
|
+
- `--size` and `--quality` are optional provider-specific values. Omit them
|
|
77
|
+
unless the task or model requires them.
|
|
78
|
+
- For Volcengine Ark Seedream, configure `type: "volcengine-ark"`; omit
|
|
79
|
+
`--quality` (unsupported). Use a supported size such as `2K`, or omit size.
|
|
80
|
+
See the configuration reference for its endpoint and `ARK_API_KEY` fallback.
|
|
81
|
+
- Generation providers are independent from vision providers and are tried
|
|
82
|
+
sequentially, stopping after the first success. Do not blindly repeat a
|
|
83
|
+
failed generation: a timeout may still incur a charge, and configured
|
|
84
|
+
fallback targets may already have been attempted.
|
|
85
|
+
- If using MCP instead, call `generate_image` with `prompt`, optional
|
|
86
|
+
`output_path`, `size`, and `quality`. It returns image content and metadata;
|
|
87
|
+
without `output_path` it does not save a local file.
|
|
88
|
+
|
|
89
|
+
Read [references/configuration.md](references/configuration.md) when configuring
|
|
90
|
+
providers or diagnosing a configuration error. Run `agent-vision doctor` to
|
|
91
|
+
inspect configured vision and generation targets without calling either API.
|