@flatkey-ai/cli 0.3.3 → 0.3.5
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 +4 -0
- package/package.json +1 -1
- package/src/api.js +24 -6
package/README.md
CHANGED
|
@@ -123,6 +123,10 @@ flatkey image generate \
|
|
|
123
123
|
-o cover.png
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
Reference images (`--file` / `--image-url`) are sent as an image edit: gpt
|
|
127
|
+
models go through `/v1/images/edits`, Gemini models receive them as native
|
|
128
|
+
`fileData` parts, so the input image is preserved instead of being ignored.
|
|
129
|
+
|
|
126
130
|
Upload a local image and get a temporary signed URL:
|
|
127
131
|
|
|
128
132
|
```bash
|
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -44,12 +44,10 @@ export function planImageRequest(options) {
|
|
|
44
44
|
if (mediaInputs.some((entry) => entry.kind === "video")) {
|
|
45
45
|
throw new Error("Image models only accept image inputs.");
|
|
46
46
|
}
|
|
47
|
-
const imageUrls = mediaInputs
|
|
48
|
-
.map((entry) => entry.url);
|
|
49
47
|
if (model.startsWith("gpt")) {
|
|
50
48
|
const responseFormat = options.response_format ?? options.responseFormat ?? "url";
|
|
51
49
|
const tempUrl = options.temp_url ?? options.tempUrl;
|
|
52
|
-
|
|
50
|
+
const payload = cleanObject({
|
|
53
51
|
model,
|
|
54
52
|
prompt: options.prompt,
|
|
55
53
|
size: options.size,
|
|
@@ -57,8 +55,16 @@ export function planImageRequest(options) {
|
|
|
57
55
|
quality: options.quality,
|
|
58
56
|
response_format: responseFormat,
|
|
59
57
|
temp_url: tempUrl ?? true,
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
});
|
|
59
|
+
if (mediaInputs.length === 0) {
|
|
60
|
+
return planJsonPost(options, "/v1/images/generations", payload);
|
|
61
|
+
}
|
|
62
|
+
// Reference images are only honoured on the edits endpoint; generations
|
|
63
|
+
// silently ignores them and runs a plain text-to-image.
|
|
64
|
+
return planJsonPost(options, "/v1/images/edits", {
|
|
65
|
+
...payload,
|
|
66
|
+
images: mediaInputs.map((entry) => ({ image_url: entry.url })),
|
|
67
|
+
});
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
const path = `/v1beta/models/${encodeURIComponent(model)}:generateContent?key=${encodeURIComponent(options.apiKey)}`;
|
|
@@ -72,7 +78,10 @@ export function planImageRequest(options) {
|
|
|
72
78
|
contents: [{
|
|
73
79
|
parts: [
|
|
74
80
|
{ text: options.prompt },
|
|
75
|
-
|
|
81
|
+
// Gemini native parts: an OpenAI-style image_url part is ignored upstream.
|
|
82
|
+
...mediaInputs.map((entry) => ({
|
|
83
|
+
fileData: { mimeType: imageMimeType(entry), fileUri: entry.url },
|
|
84
|
+
})),
|
|
76
85
|
],
|
|
77
86
|
}],
|
|
78
87
|
temp_url: true,
|
|
@@ -80,6 +89,15 @@ export function planImageRequest(options) {
|
|
|
80
89
|
});
|
|
81
90
|
}
|
|
82
91
|
|
|
92
|
+
function imageMimeType(entry) {
|
|
93
|
+
if (entry.mime) return entry.mime;
|
|
94
|
+
const path = String(entry.url ?? "").split(/[?#]/)[0].toLowerCase();
|
|
95
|
+
if (path.endsWith(".jpg") || path.endsWith(".jpeg")) return "image/jpeg";
|
|
96
|
+
if (path.endsWith(".webp")) return "image/webp";
|
|
97
|
+
if (path.endsWith(".gif")) return "image/gif";
|
|
98
|
+
return "image/png";
|
|
99
|
+
}
|
|
100
|
+
|
|
83
101
|
export function generateVideo(options) {
|
|
84
102
|
return requestJsonFromPlan(options, planVideoRequest(options));
|
|
85
103
|
}
|