exif-ai
Version:
A powerful Node.js CLI and library that uses AI providers (OpenAI, Google Gemini, Anthropic Claude, Mistral, Ollama, Amazon Bedrock, Azure OpenAI, DeepInfra, Fireworks, XAI, OpenRouter, and more) to intelligently write image descriptions and tags to EXIF
73 lines • 2.46 kB
JavaScript
import { objectFromEntries } from "ts-extras";
/**
* Attempts to get a description from the provider
*/
async function fetchDescription({ module, buffer, model, prompt, providerArgs, path, file_id, provider, verbose, repeat = 0, }) {
let description;
for (let index = 0; index < repeat + 1; index++) {
try {
const result = await module.getDescription?.({
buffer,
model,
prompt,
providerArgs,
path,
file_id,
provider, // Pass the provider name to the AI SDK
});
description = result;
}
catch (error) {
if (verbose) {
console.error("Failed to get description from provider:", error);
}
}
const isValidDescription = description &&
description.trim().length > 10 &&
!/[*#>`]/.test(description);
if (isValidDescription && description) {
return description.trim().replaceAll("\n", "");
}
}
return undefined;
}
/**
* Creates a record of description tags based on existing tags
*/
function createDescriptionRecord(description, descriptionTags, existingTags) {
if (!description) {
return {};
}
if (!existingTags) {
return objectFromEntries(descriptionTags.map((d) => [d, description]));
}
return objectFromEntries(descriptionTags
.filter((d) => {
const existingTag = existingTags[d];
return (typeof existingTag === "string" && existingTag.trim().length === 0);
})
.map((d) => [d, description]));
}
export async function getDescription({ buffer, model, prompt, providerArgs, providerModule, descriptionTags, verbose = false, existingTags, path, file_id, repeat, provider, }) {
// Get description from provider
let description;
if (providerModule && typeof providerModule === "object") {
const module = providerModule;
description = await fetchDescription({
module,
buffer,
model,
prompt,
providerArgs,
path,
file_id,
provider,
verbose,
repeat,
});
}
if (verbose)
console.log("Description is:", description);
return createDescriptionRecord(description, descriptionTags, existingTags);
}
//# sourceMappingURL=description.js.map