@xinizai/pi-image-gen 0.1.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 +337 -0
- package/dist/core/cache.d.ts +11 -0
- package/dist/core/cache.js +42 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/capabilities.d.ts +2 -0
- package/dist/core/capabilities.js +65 -0
- package/dist/core/capabilities.js.map +1 -0
- package/dist/core/errors.d.ts +11 -0
- package/dist/core/errors.js +71 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/global-config.d.ts +25 -0
- package/dist/core/global-config.js +172 -0
- package/dist/core/global-config.js.map +1 -0
- package/dist/core/image-service.d.ts +14 -0
- package/dist/core/image-service.js +42 -0
- package/dist/core/image-service.js.map +1 -0
- package/dist/core/model-browser.d.ts +5 -0
- package/dist/core/model-browser.js +76 -0
- package/dist/core/model-browser.js.map +1 -0
- package/dist/core/model-registry.d.ts +10 -0
- package/dist/core/model-registry.js +44 -0
- package/dist/core/model-registry.js.map +1 -0
- package/dist/core/provider.d.ts +2 -0
- package/dist/core/provider.js +8 -0
- package/dist/core/provider.js.map +1 -0
- package/dist/core/types.d.ts +122 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +490 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +16 -0
- package/dist/providers/openai-compatible.js +216 -0
- package/dist/providers/openai-compatible.js.map +1 -0
- package/dist/tools/shared.d.ts +42 -0
- package/dist/tools/shared.js +241 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/utils/config.d.ts +5 -0
- package/dist/utils/config.js +65 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/download.d.ts +8 -0
- package/dist/utils/download.js +139 -0
- package/dist/utils/download.js.map +1 -0
- package/dist/utils/files.d.ts +18 -0
- package/dist/utils/files.js +83 -0
- package/dist/utils/files.js.map +1 -0
- package/package.json +34 -0
- package/src/core/cache.ts +43 -0
- package/src/core/capabilities.ts +55 -0
- package/src/core/errors.ts +92 -0
- package/src/core/global-config.ts +167 -0
- package/src/core/image-service.ts +40 -0
- package/src/core/model-browser.ts +73 -0
- package/src/core/model-registry.ts +43 -0
- package/src/core/provider.ts +8 -0
- package/src/core/types.ts +135 -0
- package/src/index.ts +394 -0
- package/src/providers/openai-compatible.ts +198 -0
- package/src/tools/shared.ts +235 -0
- package/src/utils/config.ts +61 -0
- package/src/utils/download.ts +103 -0
- package/src/utils/files.ts +78 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, rename, writeFile, chmod } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { dirname, resolve } from "node:path";
|
|
5
|
+
import { ImageGenError } from "./errors.js";
|
|
6
|
+
import { normalizeBaseUrl, parseManualCapabilities } from "../utils/config.js";
|
|
7
|
+
export const GLOBAL_DIR = resolve(homedir(), ".pi", "agent", "pi-image-gen");
|
|
8
|
+
export const PROVIDERS_FILE = resolve(GLOBAL_DIR, "providers.json");
|
|
9
|
+
export class GlobalConfigStore {
|
|
10
|
+
filePath;
|
|
11
|
+
constructor(filePath = PROVIDERS_FILE) {
|
|
12
|
+
this.filePath = filePath;
|
|
13
|
+
}
|
|
14
|
+
async read() {
|
|
15
|
+
try {
|
|
16
|
+
const parsed = JSON.parse(await readFile(this.filePath, "utf8"));
|
|
17
|
+
if (!Array.isArray(parsed.providers))
|
|
18
|
+
throw new ImageGenError("invalid_json", "全局图片 Provider 配置缺少 providers 数组。", `检查或修复 ${this.filePath}。`);
|
|
19
|
+
const providers = parsed.providers.filter(isStoredProvider).map(normalizeStoredProvider);
|
|
20
|
+
const defaultProviderId = typeof parsed.defaultProviderId === "string" && providers.some((p) => p.id === parsed.defaultProviderId) ? parsed.defaultProviderId : providers[0]?.id;
|
|
21
|
+
return { version: 1, providers, defaultProviderId };
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
if (e instanceof Error && "code" in e && e.code === "ENOENT")
|
|
25
|
+
return { version: 1, providers: [] };
|
|
26
|
+
throw new ImageGenError("invalid_json", "全局图片 Provider 配置文件无效。", `检查或修复 ${this.filePath}。`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async write(config) {
|
|
30
|
+
await mkdir(dirname(this.filePath), { recursive: true });
|
|
31
|
+
const tmp = `${this.filePath}.${process.pid}.tmp`;
|
|
32
|
+
await writeFile(tmp, JSON.stringify(config, null, 2), { encoding: "utf8", mode: 0o600 });
|
|
33
|
+
await chmod(tmp, 0o600).catch(() => undefined);
|
|
34
|
+
await rename(tmp, this.filePath);
|
|
35
|
+
await chmod(this.filePath, 0o600).catch(() => undefined);
|
|
36
|
+
}
|
|
37
|
+
async addProvider(input) {
|
|
38
|
+
const config = await this.read();
|
|
39
|
+
const now = new Date().toISOString();
|
|
40
|
+
const id = stableProviderId(input.id ?? input.name, config.providers.map((p) => p.id));
|
|
41
|
+
const provider = {
|
|
42
|
+
id,
|
|
43
|
+
name: input.name.trim(),
|
|
44
|
+
providerType: "openai-compatible",
|
|
45
|
+
baseUrl: normalizeBaseUrl(input.baseUrl),
|
|
46
|
+
apiKey: input.apiKey,
|
|
47
|
+
defaultModel: input.defaultModel || undefined,
|
|
48
|
+
defaultEditModel: undefined,
|
|
49
|
+
defaultVariationModel: undefined,
|
|
50
|
+
responseFormat: input.responseFormat ?? "auto",
|
|
51
|
+
manualCapabilities: parseManualCapabilities(input.manualCapabilities),
|
|
52
|
+
createdAt: now,
|
|
53
|
+
updatedAt: now,
|
|
54
|
+
apiKeyUpdatedAt: now,
|
|
55
|
+
};
|
|
56
|
+
config.providers.push(provider);
|
|
57
|
+
if (!config.defaultProviderId)
|
|
58
|
+
config.defaultProviderId = provider.id;
|
|
59
|
+
await this.write(config);
|
|
60
|
+
return provider;
|
|
61
|
+
}
|
|
62
|
+
async updateProvider(id, patch) {
|
|
63
|
+
const config = await this.read();
|
|
64
|
+
const idx = config.providers.findIndex((p) => p.id === id);
|
|
65
|
+
if (idx < 0)
|
|
66
|
+
throw new ImageGenError("model_unavailable", `提供商 ${id} 不存在。`, "请运行 /image-config 查看可用提供商。 ");
|
|
67
|
+
const current = config.providers[idx];
|
|
68
|
+
const apiKeyChanged = typeof patch.apiKey === "string" && patch.apiKey !== current.apiKey;
|
|
69
|
+
const next = {
|
|
70
|
+
...current,
|
|
71
|
+
...patch,
|
|
72
|
+
baseUrl: patch.baseUrl ? normalizeBaseUrl(patch.baseUrl) : current.baseUrl,
|
|
73
|
+
updatedAt: new Date().toISOString(),
|
|
74
|
+
apiKeyUpdatedAt: apiKeyChanged ? new Date().toISOString() : current.apiKeyUpdatedAt,
|
|
75
|
+
};
|
|
76
|
+
config.providers[idx] = next;
|
|
77
|
+
await this.write(config);
|
|
78
|
+
return next;
|
|
79
|
+
}
|
|
80
|
+
async deleteProvider(id) {
|
|
81
|
+
const config = await this.read();
|
|
82
|
+
config.providers = config.providers.filter((p) => p.id !== id);
|
|
83
|
+
if (config.defaultProviderId === id)
|
|
84
|
+
config.defaultProviderId = config.providers[0]?.id;
|
|
85
|
+
await this.write(config);
|
|
86
|
+
}
|
|
87
|
+
async setDefaultProvider(id) {
|
|
88
|
+
const config = await this.read();
|
|
89
|
+
if (!config.providers.some((p) => p.id === id))
|
|
90
|
+
throw new ImageGenError("model_unavailable", `Provider ${id} 不存在。`, "先添加 Provider。 ");
|
|
91
|
+
config.defaultProviderId = id;
|
|
92
|
+
await this.write(config);
|
|
93
|
+
}
|
|
94
|
+
async resolveProvider(idOrName) {
|
|
95
|
+
const config = await this.read();
|
|
96
|
+
if (idOrName)
|
|
97
|
+
return config.providers.find((p) => p.id === idOrName || p.name.toLowerCase() === idOrName.toLowerCase());
|
|
98
|
+
if (config.defaultProviderId)
|
|
99
|
+
return config.providers.find((p) => p.id === config.defaultProviderId);
|
|
100
|
+
if (config.providers.length === 1)
|
|
101
|
+
return config.providers[0];
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
async toRuntimeConfig(provider, env = process.env) {
|
|
105
|
+
return {
|
|
106
|
+
providerId: provider.id,
|
|
107
|
+
providerName: provider.name,
|
|
108
|
+
baseUrl: provider.baseUrl,
|
|
109
|
+
apiKey: provider.apiKey,
|
|
110
|
+
model: provider.defaultModel,
|
|
111
|
+
editModel: provider.defaultEditModel,
|
|
112
|
+
variationModel: provider.defaultVariationModel,
|
|
113
|
+
responseFormat: provider.responseFormat ?? "auto",
|
|
114
|
+
providerType: provider.providerType,
|
|
115
|
+
timeoutMs: Number(env.IMAGE_TIMEOUT_SECONDS ?? 60) * 1000,
|
|
116
|
+
cacheTtlMs: Number(env.IMAGE_CACHE_TTL_SECONDS ?? 600) * 1000,
|
|
117
|
+
outputDir: env.IMAGE_OUTPUT_DIR ? resolve(env.IMAGE_OUTPUT_DIR) : resolve(homedir(), ".pi", "agent", "generated"),
|
|
118
|
+
maxResponseBytes: Number(env.IMAGE_MAX_RESPONSE_BYTES ?? 8_000_000),
|
|
119
|
+
maxDownloadBytes: Number(env.IMAGE_MAX_DOWNLOAD_BYTES ?? 25_000_000),
|
|
120
|
+
manualCapabilities: { ...provider.manualCapabilities, ...parseManualCapabilities(env.IMAGE_MODEL_CAPABILITIES) },
|
|
121
|
+
apiKeyUpdatedAt: provider.apiKeyUpdatedAt,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export function envFallbackProvider(env = process.env) {
|
|
126
|
+
if (!env.IMAGE_BASE_URL || !env.IMAGE_API_KEY)
|
|
127
|
+
return undefined;
|
|
128
|
+
const now = new Date().toISOString();
|
|
129
|
+
return {
|
|
130
|
+
id: "env",
|
|
131
|
+
name: "环境变量配置",
|
|
132
|
+
providerType: "openai-compatible",
|
|
133
|
+
baseUrl: normalizeBaseUrl(env.IMAGE_BASE_URL),
|
|
134
|
+
apiKey: env.IMAGE_API_KEY,
|
|
135
|
+
defaultModel: env.IMAGE_MODEL || undefined,
|
|
136
|
+
defaultEditModel: env.IMAGE_EDIT_MODEL || undefined,
|
|
137
|
+
defaultVariationModel: env.IMAGE_VARIATION_MODEL || undefined,
|
|
138
|
+
responseFormat: "auto",
|
|
139
|
+
manualCapabilities: parseManualCapabilities(env.IMAGE_MODEL_CAPABILITIES),
|
|
140
|
+
createdAt: now,
|
|
141
|
+
updatedAt: now,
|
|
142
|
+
apiKeyUpdatedAt: now,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export async function resolveRuntimeConfig(providerId, env = process.env, store = new GlobalConfigStore()) {
|
|
146
|
+
const provider = await store.resolveProvider(providerId);
|
|
147
|
+
if (provider)
|
|
148
|
+
return store.toRuntimeConfig(provider, env);
|
|
149
|
+
const fallback = envFallbackProvider(env);
|
|
150
|
+
if (fallback)
|
|
151
|
+
return store.toRuntimeConfig(fallback, env);
|
|
152
|
+
throw new ImageGenError("missing_config", "还没有配置图片生成提供商。", "运行 /image-config 添加全局图片提供商。 ");
|
|
153
|
+
}
|
|
154
|
+
function isStoredProvider(value) {
|
|
155
|
+
if (!value || typeof value !== "object")
|
|
156
|
+
return false;
|
|
157
|
+
const p = value;
|
|
158
|
+
return typeof p.id === "string" && typeof p.name === "string" && typeof p.baseUrl === "string" && typeof p.apiKey === "string";
|
|
159
|
+
}
|
|
160
|
+
function normalizeStoredProvider(provider) {
|
|
161
|
+
return { ...provider, providerType: "openai-compatible", responseFormat: provider.responseFormat ?? "auto", manualCapabilities: provider.manualCapabilities ?? {}, defaultModel: provider.defaultModel || undefined, defaultEditModel: provider.defaultEditModel || undefined, defaultVariationModel: provider.defaultVariationModel || undefined };
|
|
162
|
+
}
|
|
163
|
+
function stableProviderId(seed, existing) {
|
|
164
|
+
const base = (seed.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || `custom-${randomUUID().slice(0, 6)}`).slice(0, 40);
|
|
165
|
+
if (!existing.includes(base))
|
|
166
|
+
return base;
|
|
167
|
+
for (let i = 1; i < 1000; i += 1)
|
|
168
|
+
if (!existing.includes(`${base}-${i}`))
|
|
169
|
+
return `${base}-${i}`;
|
|
170
|
+
return `${base}-${randomUUID().slice(0, 6)}`;
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=global-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-config.js","sourceRoot":"","sources":["../../src/core/global-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ModelDiscoveryCache } from "./cache.js";
|
|
2
|
+
import { ModelRegistry } from "./model-registry.js";
|
|
3
|
+
import type { DiscoveryResult, EditParams, GenerateParams, ImageGenConfig, ImageOperationResult, ImageProvider, VariationParams } from "./types.js";
|
|
4
|
+
export declare class ImageService {
|
|
5
|
+
private readonly config;
|
|
6
|
+
private readonly provider;
|
|
7
|
+
private readonly cache;
|
|
8
|
+
constructor(config: ImageGenConfig, provider: ImageProvider, cache?: ModelDiscoveryCache);
|
|
9
|
+
discover(refresh?: boolean, signal?: AbortSignal): Promise<DiscoveryResult>;
|
|
10
|
+
registry(refresh?: boolean, signal?: AbortSignal): Promise<ModelRegistry>;
|
|
11
|
+
generate(params: GenerateParams, signal?: AbortSignal): Promise<ImageOperationResult>;
|
|
12
|
+
edit(params: EditParams, signal?: AbortSignal): Promise<ImageOperationResult>;
|
|
13
|
+
variation(params: VariationParams, signal?: AbortSignal): Promise<ImageOperationResult>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ModelDiscoveryCache } from "./cache.js";
|
|
2
|
+
import { ModelRegistry } from "./model-registry.js";
|
|
3
|
+
export class ImageService {
|
|
4
|
+
config;
|
|
5
|
+
provider;
|
|
6
|
+
cache;
|
|
7
|
+
constructor(config, provider, cache = new ModelDiscoveryCache()) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.provider = provider;
|
|
10
|
+
this.cache = cache;
|
|
11
|
+
}
|
|
12
|
+
async discover(refresh = false, signal) {
|
|
13
|
+
if (!refresh) {
|
|
14
|
+
const cached = await this.cache.get(this.config);
|
|
15
|
+
if (cached)
|
|
16
|
+
return cached;
|
|
17
|
+
}
|
|
18
|
+
const models = await this.provider.discoverModels(signal);
|
|
19
|
+
const result = { providerId: this.config.providerId, providerName: this.config.providerName, providerType: this.provider.type, baseUrl: this.config.baseUrl, models, discoveredAt: new Date().toISOString(), apiKeyFingerprint: this.cache.apiKeyFingerprint(this.config) };
|
|
20
|
+
await this.cache.set(this.config, result);
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
async registry(refresh = false, signal) {
|
|
24
|
+
return new ModelRegistry((await this.discover(refresh, signal)).models);
|
|
25
|
+
}
|
|
26
|
+
async generate(params, signal) {
|
|
27
|
+
const registry = await this.registry(false, signal);
|
|
28
|
+
const model = registry.select("image_generation", params.model, this.config.model);
|
|
29
|
+
return this.provider.generate({ ...params, model: model.id, modelCapabilities: model }, signal);
|
|
30
|
+
}
|
|
31
|
+
async edit(params, signal) {
|
|
32
|
+
const registry = await this.registry(false, signal);
|
|
33
|
+
const model = registry.select("image_edit", params.model, this.config.editModel ?? this.config.model);
|
|
34
|
+
return this.provider.edit({ ...params, model: model.id, modelCapabilities: model }, signal);
|
|
35
|
+
}
|
|
36
|
+
async variation(params, signal) {
|
|
37
|
+
const registry = await this.registry(false, signal);
|
|
38
|
+
const model = registry.select("image_variation", params.model, this.config.variationModel ?? this.config.model);
|
|
39
|
+
return this.provider.variation({ ...params, model: model.id, modelCapabilities: model }, signal);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=image-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-service.js","sourceRoot":"","sources":["../../src/core/image-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DiscoveryResult, ModelBrowserOptions } from "./types.js";
|
|
2
|
+
export declare const DEFAULT_MODEL_LIMIT = 20;
|
|
3
|
+
export declare const MAX_MODEL_LIMIT = 50;
|
|
4
|
+
export declare function renderModelBrowser(result: DiscoveryResult, options: ModelBrowserOptions): string;
|
|
5
|
+
export declare function renderRefreshSummary(result: DiscoveryResult): string;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ModelRegistry } from "./model-registry.js";
|
|
2
|
+
export const DEFAULT_MODEL_LIMIT = 20;
|
|
3
|
+
export const MAX_MODEL_LIMIT = 50;
|
|
4
|
+
export function renderModelBrowser(result, options) {
|
|
5
|
+
const limit = Math.min(Math.max(1, options.limit), MAX_MODEL_LIMIT);
|
|
6
|
+
const page = Math.max(1, options.page);
|
|
7
|
+
const registry = new ModelRegistry(result.models);
|
|
8
|
+
const all = registry.all();
|
|
9
|
+
const keyword = options.search?.trim().toLowerCase();
|
|
10
|
+
const filtered = keyword ? all.filter((m) => `${m.id} ${JSON.stringify(m.rawMetadata)}`.toLowerCase().includes(keyword)) : all;
|
|
11
|
+
const groups = [["image_generation", "图片生成"], ["image_edit", "图片编辑"], ["image_variation", "图片变体"], ["vision", "视觉理解"], ["unknown", "未知能力"]];
|
|
12
|
+
if (options.includeText || keyword)
|
|
13
|
+
groups.push(["text", "文本模型"]);
|
|
14
|
+
const lines = [
|
|
15
|
+
`提供商:${result.providerName} (${result.providerId})`,
|
|
16
|
+
`模型总数:${all.length}`,
|
|
17
|
+
keyword ? `搜索:${keyword}` : "默认视图:只显示图片相关模型",
|
|
18
|
+
`显示限制:每组 ${limit} 个,第 ${page} 页`,
|
|
19
|
+
"",
|
|
20
|
+
];
|
|
21
|
+
for (const [cap, label] of groups) {
|
|
22
|
+
const models = filtered.filter((m) => m.capabilities.includes(cap));
|
|
23
|
+
const start = (page - 1) * limit;
|
|
24
|
+
const shown = models.slice(start, start + limit);
|
|
25
|
+
const totalPages = Math.max(1, Math.ceil(models.length / limit));
|
|
26
|
+
lines.push(`${label}(${models.length})${models.length > limit ? ` - 第 ${Math.min(page, totalPages)} / ${totalPages} 页` : ""}`);
|
|
27
|
+
if (shown.length === 0)
|
|
28
|
+
lines.push("- 无");
|
|
29
|
+
else
|
|
30
|
+
shown.forEach((m, i) => lines.push(`${start + i + 1}. ${formatModel(m)}`));
|
|
31
|
+
if (models.length > start + shown.length)
|
|
32
|
+
lines.push(`... 还有 ${models.length - start - shown.length} 个。请在 /image-config 中使用“搜索模型”或调整分页查看。`);
|
|
33
|
+
lines.push("");
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
lines.push(`当前默认生图模型:${registry.select("image_generation").id}`);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
lines.push("当前默认生图模型:无");
|
|
40
|
+
}
|
|
41
|
+
if (all.length > filtered.length)
|
|
42
|
+
lines.push(`已过滤:${all.length - filtered.length}`);
|
|
43
|
+
if (!keyword)
|
|
44
|
+
lines.push("请在 /image-config 中使用“搜索模型”搜索完整模型列表。");
|
|
45
|
+
return truncateLines(lines, 180, 12_000);
|
|
46
|
+
}
|
|
47
|
+
export function renderRefreshSummary(result) {
|
|
48
|
+
const summary = new ModelRegistry(result.models).summary();
|
|
49
|
+
return [
|
|
50
|
+
`提供商已刷新:${result.providerName} (${result.providerId})`,
|
|
51
|
+
`模型总数:${result.models.length}`,
|
|
52
|
+
`图片生成:${summary.image_generation.length}`,
|
|
53
|
+
`图片编辑:${summary.image_edit.length}`,
|
|
54
|
+
`图片变体:${summary.image_variation.length}`,
|
|
55
|
+
`视觉理解:${summary.vision.length}`,
|
|
56
|
+
`未知能力:${summary.unknown.length}`,
|
|
57
|
+
].join("\n");
|
|
58
|
+
}
|
|
59
|
+
function formatModel(model) {
|
|
60
|
+
const source = model.capabilitySource === "heuristic" ? " [heuristic]" : model.capabilitySource === "manual" ? " [manual]" : "";
|
|
61
|
+
return `${model.id}${source}`;
|
|
62
|
+
}
|
|
63
|
+
function truncateLines(lines, maxLines, maxChars) {
|
|
64
|
+
const out = [];
|
|
65
|
+
let chars = 0;
|
|
66
|
+
for (const line of lines) {
|
|
67
|
+
if (out.length >= maxLines || chars + line.length + 1 > maxChars) {
|
|
68
|
+
out.push("... 输出已截断。请在 /image-config 中使用搜索、分页或选择提供商缩小结果。");
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
out.push(line);
|
|
72
|
+
chars += line.length + 1;
|
|
73
|
+
}
|
|
74
|
+
return out.join("\n");
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=model-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-browser.js","sourceRoot":"","sources":["../../src/core/model-browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ModelCapability, ModelInfo } from "./types.js";
|
|
2
|
+
export declare class ModelRegistry {
|
|
3
|
+
private readonly models;
|
|
4
|
+
constructor(models: ModelInfo[]);
|
|
5
|
+
all(): ModelInfo[];
|
|
6
|
+
byCapability(cap: ModelCapability): ModelInfo[];
|
|
7
|
+
get(id: string): ModelInfo | undefined;
|
|
8
|
+
select(capability: ModelCapability, explicit?: string, configured?: string): ModelInfo;
|
|
9
|
+
summary(): Record<ModelCapability, string[]>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ImageGenError } from "./errors.js";
|
|
2
|
+
export class ModelRegistry {
|
|
3
|
+
models;
|
|
4
|
+
constructor(models) {
|
|
5
|
+
this.models = models;
|
|
6
|
+
}
|
|
7
|
+
all() { return [...this.models].sort((a, b) => a.id.localeCompare(b.id)); }
|
|
8
|
+
byCapability(cap) { return this.all().filter((m) => m.capabilities.includes(cap)); }
|
|
9
|
+
get(id) { return this.models.find((m) => m.id === id); }
|
|
10
|
+
select(capability, explicit, configured) {
|
|
11
|
+
const preferred = explicit || configured;
|
|
12
|
+
if (preferred) {
|
|
13
|
+
const model = this.get(preferred);
|
|
14
|
+
if (!model)
|
|
15
|
+
throw new ImageGenError("model_unavailable", `模型 ${preferred} 不在已发现模型列表中。`, "请在 /image-config 中刷新模型,或确认模型名称。 ");
|
|
16
|
+
if (!model.capabilities.includes(capability) && !model.capabilities.includes("unknown")) {
|
|
17
|
+
throw new ImageGenError("model_unavailable", `模型 ${preferred} 未声明支持 ${capability}。`, "请在 /image-config 中查看可用模型,或用 IMAGE_MODEL_CAPABILITIES 手动声明能力。 ");
|
|
18
|
+
}
|
|
19
|
+
if (model.capabilities.includes("unknown")) {
|
|
20
|
+
throw new ImageGenError("capability_unknown", `无法自动判断模型 ${preferred} 是否支持 ${capability}。`, "请设置 IMAGE_MODEL_CAPABILITIES='model:image_generation' 之类的手动能力声明。 ");
|
|
21
|
+
}
|
|
22
|
+
return model;
|
|
23
|
+
}
|
|
24
|
+
const capable = this.byCapability(capability);
|
|
25
|
+
if (capable.length > 0)
|
|
26
|
+
return capable[0];
|
|
27
|
+
const unknown = this.byCapability("unknown");
|
|
28
|
+
if (unknown.length > 0) {
|
|
29
|
+
throw new ImageGenError("capability_unknown", `没有可确认支持 ${capability} 的模型,但发现 unknown 模型。`, `请在 /image-config 中查看模型,并用 IMAGE_MODEL 或 IMAGE_MODEL_CAPABILITIES 手动指定。`);
|
|
30
|
+
}
|
|
31
|
+
throw new ImageGenError("model_unavailable", `没有发现支持 ${capability} 的模型。`, "检查 API 是否支持图片接口,或手动配置对应模型。 ");
|
|
32
|
+
}
|
|
33
|
+
summary() {
|
|
34
|
+
return {
|
|
35
|
+
image_generation: this.byCapability("image_generation").map((m) => m.id),
|
|
36
|
+
image_edit: this.byCapability("image_edit").map((m) => m.id),
|
|
37
|
+
image_variation: this.byCapability("image_variation").map((m) => m.id),
|
|
38
|
+
vision: this.byCapability("vision").map((m) => m.id),
|
|
39
|
+
text: this.byCapability("text").map((m) => m.id),
|
|
40
|
+
unknown: this.byCapability("unknown").map((m) => m.id),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=model-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ImageGenError } from "./errors.js";
|
|
2
|
+
import { OpenAICompatibleProvider } from "../providers/openai-compatible.js";
|
|
3
|
+
export function resolveProvider(config) {
|
|
4
|
+
if (config.providerType === "openai-compatible")
|
|
5
|
+
return new OpenAICompatibleProvider(config);
|
|
6
|
+
throw new ImageGenError("unsupported_provider", `不支持的 Provider:${config.providerType}`, "当前版本只实现 OpenAI-compatible。 ");
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/core/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,MAAM,UAAU,eAAe,CAAC,MAAsB;IACpD,IAAI,MAAM,CAAC,YAAY,KAAK,mBAAmB;QAAE,OAAO,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC7F,MAAM,IAAI,aAAa,CAAC,sBAAsB,EAAE,iBAAiB,MAAM,CAAC,YAAY,EAAE,EAAE,6BAA6B,CAAC,CAAC;AACzH,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
export type ModelCapability = "text" | "vision" | "image_generation" | "image_edit" | "image_variation" | "unknown";
|
|
2
|
+
export interface ModelInfo {
|
|
3
|
+
id: string;
|
|
4
|
+
provider: string;
|
|
5
|
+
capabilities: ModelCapability[];
|
|
6
|
+
capabilitySource: "metadata" | "heuristic" | "manual" | "unknown";
|
|
7
|
+
inputModalities: string[];
|
|
8
|
+
outputModalities: string[];
|
|
9
|
+
supportsSize: boolean;
|
|
10
|
+
supportsQuality: boolean;
|
|
11
|
+
supportsAspectRatio: boolean;
|
|
12
|
+
supportsImageInput: boolean;
|
|
13
|
+
supportsMultipleImages: boolean;
|
|
14
|
+
rawMetadata: unknown;
|
|
15
|
+
}
|
|
16
|
+
export type ImageResponseFormat = "auto" | "url" | "b64_json";
|
|
17
|
+
export interface StoredProviderConfig {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
providerType: "openai-compatible";
|
|
21
|
+
baseUrl: string;
|
|
22
|
+
apiKey: string;
|
|
23
|
+
defaultModel?: string | undefined;
|
|
24
|
+
defaultEditModel?: string | undefined;
|
|
25
|
+
defaultVariationModel?: string | undefined;
|
|
26
|
+
/** auto: 优先 url,服务端明确拒绝时仅重试一次 b64_json。 */
|
|
27
|
+
responseFormat?: ImageResponseFormat | undefined;
|
|
28
|
+
manualCapabilities: Record<string, ModelCapability[]>;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
updatedAt: string;
|
|
31
|
+
apiKeyUpdatedAt: string;
|
|
32
|
+
}
|
|
33
|
+
export interface GlobalImageGenConfig {
|
|
34
|
+
version: 1;
|
|
35
|
+
defaultProviderId?: string | undefined;
|
|
36
|
+
providers: StoredProviderConfig[];
|
|
37
|
+
}
|
|
38
|
+
export interface ImageGenConfig {
|
|
39
|
+
providerId: string;
|
|
40
|
+
providerName: string;
|
|
41
|
+
baseUrl: string;
|
|
42
|
+
apiKey: string;
|
|
43
|
+
model?: string | undefined;
|
|
44
|
+
editModel?: string | undefined;
|
|
45
|
+
variationModel?: string | undefined;
|
|
46
|
+
responseFormat: ImageResponseFormat;
|
|
47
|
+
providerType: "openai-compatible";
|
|
48
|
+
timeoutMs: number;
|
|
49
|
+
cacheTtlMs: number;
|
|
50
|
+
outputDir: string;
|
|
51
|
+
maxResponseBytes: number;
|
|
52
|
+
maxDownloadBytes: number;
|
|
53
|
+
manualCapabilities: Record<string, ModelCapability[]>;
|
|
54
|
+
apiKeyUpdatedAt: string;
|
|
55
|
+
}
|
|
56
|
+
export interface DiscoveryResult {
|
|
57
|
+
providerId: string;
|
|
58
|
+
providerName: string;
|
|
59
|
+
providerType: string;
|
|
60
|
+
baseUrl: string;
|
|
61
|
+
models: ModelInfo[];
|
|
62
|
+
discoveredAt: string;
|
|
63
|
+
apiKeyFingerprint: string;
|
|
64
|
+
}
|
|
65
|
+
export interface GeneratedImage {
|
|
66
|
+
path: string;
|
|
67
|
+
url?: string;
|
|
68
|
+
mimeType: string;
|
|
69
|
+
index: number;
|
|
70
|
+
}
|
|
71
|
+
export interface ImageOperationResult {
|
|
72
|
+
provider: string;
|
|
73
|
+
providerId: string;
|
|
74
|
+
model: string;
|
|
75
|
+
images: GeneratedImage[];
|
|
76
|
+
rawInfo?: Record<string, unknown>;
|
|
77
|
+
}
|
|
78
|
+
export interface GenerateParams {
|
|
79
|
+
prompt: string;
|
|
80
|
+
provider?: string;
|
|
81
|
+
model?: string;
|
|
82
|
+
size?: string;
|
|
83
|
+
aspect_ratio?: string;
|
|
84
|
+
quality?: string;
|
|
85
|
+
output_format?: "png" | "jpeg" | "jpg" | "webp";
|
|
86
|
+
n?: number;
|
|
87
|
+
modelCapabilities?: Pick<ModelInfo, "supportsSize" | "supportsQuality" | "supportsAspectRatio" | "supportsMultipleImages">;
|
|
88
|
+
}
|
|
89
|
+
export interface EditParams {
|
|
90
|
+
image: string;
|
|
91
|
+
prompt: string;
|
|
92
|
+
provider?: string;
|
|
93
|
+
model?: string;
|
|
94
|
+
size?: string;
|
|
95
|
+
output_format?: "png" | "jpeg" | "jpg" | "webp";
|
|
96
|
+
modelCapabilities?: Pick<ModelInfo, "supportsSize">;
|
|
97
|
+
}
|
|
98
|
+
export interface VariationParams {
|
|
99
|
+
image: string;
|
|
100
|
+
provider?: string;
|
|
101
|
+
model?: string;
|
|
102
|
+
size?: string;
|
|
103
|
+
n?: number;
|
|
104
|
+
modelCapabilities?: Pick<ModelInfo, "supportsSize" | "supportsMultipleImages">;
|
|
105
|
+
}
|
|
106
|
+
export interface ModelBrowserOptions {
|
|
107
|
+
provider?: string;
|
|
108
|
+
search?: string;
|
|
109
|
+
page: number;
|
|
110
|
+
limit: number;
|
|
111
|
+
refresh: boolean;
|
|
112
|
+
refreshAll: boolean;
|
|
113
|
+
includeText: boolean;
|
|
114
|
+
}
|
|
115
|
+
export interface ImageProvider {
|
|
116
|
+
readonly type: string;
|
|
117
|
+
readonly name: string;
|
|
118
|
+
discoverModels(signal?: AbortSignal): Promise<ModelInfo[]>;
|
|
119
|
+
generate(params: GenerateParams, signal?: AbortSignal): Promise<ImageOperationResult>;
|
|
120
|
+
edit(params: EditParams, signal?: AbortSignal): Promise<ImageOperationResult>;
|
|
121
|
+
variation(params: VariationParams, signal?: AbortSignal): Promise<ImageOperationResult>;
|
|
122
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED