Skip to content

Commit 1a94e4f

Browse files
committed
alt text autogeneration
1 parent 6f11ded commit 1a94e4f

20 files changed

+285
-924
lines changed

composer.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

includes/OpenAIApi.php

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function __construct($apiKey, $logger = NULL) {
2727
$this->client = $this->initializeClient($apiKey);
2828

2929
// Initialize the logger
30-
$this->logger = $logger ?: watchdog('openai', 'There was an issue obtaining a response from OpenAI.');
30+
$this->logger = $logger ?: watchdog('openai', 'There was an issue obtaining a response from OpenAI construct.');
3131
}
3232

3333
private function initializeClient($apiKey) {
@@ -68,7 +68,8 @@ public function getModels(): array {
6868
continue;
6969
}
7070

71-
if (!preg_match('/^(gpt|text|tts|whisper|dall-e)/i', $model['id'])) {
71+
if (!preg_match('/^(gpt|text|tts|whisper|dall-e|o1)/i',
72+
$model['id'])) {
7273
continue;
7374
}
7475

@@ -110,16 +111,6 @@ public function filterModels(array $model_type): array {
110111
return $models;
111112
}
112113

113-
/**
114-
* Get the latest embedding model.
115-
*
116-
* @return string
117-
* The embedding model in OpenAI.
118-
*/
119-
public function embeddingModel(): string {
120-
return 'text-embedding-ada-002';
121-
}
122-
123114
/**
124115
* Return a ready to use answer from the completion endpoint.
125116
*
@@ -176,7 +167,7 @@ public function completions(string $model, string $prompt, $temperature, $max_to
176167
return trim($result['choices'][0]['text']);
177168
}
178169
} catch (TransporterException | \Exception $e) {
179-
watchdog('openai', 'There was an issue obtaining a response from OpenAI. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
170+
watchdog('openai', 'There was an issue obtaining a response from OpenAI completions. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
180171
}
181172
}
182173

@@ -234,7 +225,7 @@ public function chat(string $model, array $messages, $temperature, $max_tokens =
234225
return trim($result['choices'][0]['message']['content']);
235226
}
236227
} catch (TransporterException | \Exception $e) {
237-
watchdog('openai', 'There was an issue obtaining a response from OpenAI. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
228+
watchdog('openai', 'There was an issue obtaining a response from OpenAI chat. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
238229
return '';
239230
}
240231
}
@@ -276,7 +267,7 @@ public function images(string $model, string $prompt, string $size, string $resp
276267
$response = $response->toArray();
277268
return $response['data'][0][$response_format];
278269
} catch (TransporterException | \Exception $e) {
279-
watchdog('openai', 'There was an issue obtaining a response from OpenAI. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
270+
watchdog('openai', 'There was an issue obtaining a response from OpenAI Images. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
280271
return '';
281272
}
282273
}
@@ -305,7 +296,7 @@ public function textToSpeech(string $model, string $input, string $voice, string
305296
'response_format' => $response_format,
306297
]);
307298
} catch (TransporterException | \Exception $e) {
308-
watchdog('openai', 'There was an issue obtaining a response from OpenAI. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
299+
watchdog('openai', 'There was an issue obtaining a response from OpenAI textToSpeech. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
309300
return '';
310301
}
311302
}
@@ -341,7 +332,7 @@ public function speechToText(string $model, string $file, string $task = 'transc
341332
$result = $response->toArray();
342333
return $result['text'];
343334
} catch (TransporterException | \Exception $e) {
344-
watchdog('openai', 'There was an issue obtaining a response from OpenAI. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
335+
watchdog('openai', 'There was an issue obtaining a response from OpenAI speechToText. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
345336
return '';
346337
}
347338
}
@@ -359,14 +350,14 @@ public function moderation(string $input): array {
359350
try {
360351
$response = $this->client->moderations()->create(
361352
[
362-
'model' => 'text-moderation-latest',
353+
'model' => 'omni-moderation-latest',
363354
'input' => trim($input),
364355
],
365356
);
366357

367358
return $response->toArray();
368359
} catch (TransporterException | \Exception $e) {
369-
watchdog('openai', 'There was an issue obtaining a response from OpenAI. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
360+
watchdog('openai', 'There was an issue obtaining a response from OpenAI moderation. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
370361
return [];
371362
}
372363
}
@@ -375,23 +366,33 @@ public function moderation(string $input): array {
375366
* Generate a text embedding from an input.
376367
*
377368
* @param string $input
378-
* The input to check.
369+
* The input text to embed.
370+
* @param string $model
371+
* The model to use for embedding.
379372
*
380373
* @return array
381374
* The text embedding vector value from OpenAI.
375+
*
376+
* @throws \InvalidArgumentException
377+
* Thrown if no model is provided.
382378
*/
383-
public function embedding(string $input): array {
379+
public function embedding(string $input, string $model): array {
380+
if (empty($model)) {
381+
throw new \InvalidArgumentException('A model must be provided for generating embeddings.');
382+
}
383+
384384
try {
385385
$response = $this->client->embeddings()->create([
386-
'model' => 'text-embedding-ada-002',
386+
'model' => $model, // Model is now strictly passed
387387
'input' => $input,
388388
]);
389389

390390
$result = $response->toArray();
391-
392391
return $result['data'][0]['embedding'];
393392
} catch (TransporterException | \Exception $e) {
394-
watchdog('openai', 'There was an issue obtaining a response from OpenAI. The error was @error.', array('@error' => $e->getMessage()), WATCHDOG_ERROR);
393+
watchdog('openai', 'There was an issue obtaining a response from OpenAI embedding. The error was @error.', [
394+
'@error' => $e->getMessage(),
395+
], WATCHDOG_ERROR);
395396
return [];
396397
}
397398
}
@@ -421,7 +422,6 @@ public function describeImage(string $imageUrl, bool $sendImageData = TRUE): str
421422
if ($sendImageData) {
422423
$imageData = base64_encode(file_get_contents($imageUrl));
423424
$imageUrl = "data:image/jpeg;base64,{$imageData}";
424-
watchdog('openai_alt', 'Image data prepared for OpenAI: @url', ['@url' => $imageUrl], WATCHDOG_INFO);
425425
}
426426

427427
try {
@@ -440,7 +440,6 @@ public function describeImage(string $imageUrl, bool $sendImageData = TRUE): str
440440
]);
441441

442442
$result = $response->toArray();
443-
watchdog('openai_alt', 'OpenAI response: @response', ['@response' => print_r($result, TRUE)], WATCHDOG_INFO);
444443

445444
return isset($result["choices"][0]["message"]["content"])
446445
? trim($result["choices"][0]["message"]["content"])
Lines changed: 86 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,89 @@
1-
$(document).ready(function () {
2-
if (Backdrop.settings.openaiAlt) {
3-
var fid = Backdrop.settings.openaiAlt.fid;
4-
var fieldName = Backdrop.settings.openaiAlt.field_name;
5-
var delta = Backdrop.settings.openaiAlt.delta;
6-
var wrapperId = Backdrop.settings.openaiAlt.wrapper_id;
7-
8-
console.log("✅ Auto-generation script running...");
9-
console.log("🖼️ File ID:", fid);
10-
console.log("📂 Field Name:", fieldName);
11-
console.log("🔄 Wrapper ID:", wrapperId);
12-
13-
$.ajax({
14-
url: Backdrop.settings.basePath + 'openai-alt/generate-alt-text',
15-
type: 'POST',
16-
data: {
17-
fid: fid,
18-
field_name: fieldName,
19-
delta: delta,
20-
},
21-
success: function (response) {
22-
console.log("✅ AJAX request successful! Full response:", response);
23-
if (response.status === "success" && response.alt_text) {
24-
$("input[name='" + fieldName + "[und][" + delta + "][alt]']").val(response.alt_text);
25-
console.log("✅ Alt text successfully inserted.");
26-
} else {
27-
console.error("❌ No valid alt text received.");
1+
(function ($) {
2+
$(document).ready(function () {
3+
/**
4+
* Ensure the correct alt field is wrapped properly.
5+
*/
6+
function wrapAltTextFields() {
7+
$("input[name^='field_image'][name$='[alt]']").each(function () {
8+
var $altField = $(this).closest(".form-item");
9+
if (!$altField.parent().hasClass("ai-alt-field-wrapper")) {
10+
$altField.wrap('<div class="ai-alt-field-wrapper"></div>');
11+
}
12+
});
13+
}
14+
15+
/**
16+
* Automatically trigger alt text generation on page load if needed.
17+
*/
18+
function triggerAutoGenerationIfNeeded() {
19+
if (Backdrop.settings.openaiAlt) {
20+
var fid = Backdrop.settings.openaiAlt.fid;
21+
var fieldName = Backdrop.settings.openaiAlt.field_name;
22+
var delta = Backdrop.settings.openaiAlt.delta;
23+
24+
// Trigger AJAX call to generate Alt text
25+
$.ajax({
26+
url: Backdrop.settings.basePath + "openai-alt/generate-alt-text",
27+
type: "POST",
28+
data: { fid: fid, field_name: fieldName, delta: delta },
29+
success: function (response) {
30+
if (response.status === "success" && response.alt_text) {
31+
var $altField = $("input[name='" + fieldName + "[und][" + delta + "][alt]']");
32+
$altField.val(response.alt_text).trigger("change");
33+
34+
// Ensure Backdrop recognizes the update
35+
setTimeout(function () {
36+
Backdrop.attachBehaviors();
37+
}, 500);
38+
}
39+
},
40+
error: function (xhr, status, error) {
41+
console.error("❌ AJAX request failed:", status, error);
42+
},
43+
});
44+
}
45+
}
46+
47+
/**
48+
* Handle AJAX responses for file uploads & alt text generation.
49+
*/
50+
$(document).ajaxComplete(function (event, xhr, settings) {
51+
if (settings.url.includes("file/ajax")) {
52+
setTimeout(function () {
53+
if (Backdrop.settings.openaiAlt) {
54+
triggerAutoGenerationIfNeeded();
55+
}
56+
}, 500);
57+
}
58+
59+
// Handling response from alt text generation
60+
if (settings.url.includes("openai-alt/generate-alt-text")) {
61+
try {
62+
var response = JSON.parse(xhr.responseText);
63+
if (response.status === "success" && response.alt_text) {
64+
var $altField = $("input[name^='field_image'][name$='[alt]']");
65+
$altField.val(response.alt_text).trigger("change");
66+
67+
// Ensure Backdrop recognizes the update
68+
setTimeout(function () {
69+
Backdrop.attachBehaviors();
70+
}, 500);
71+
}
72+
} catch (e) {
73+
console.error("Error processing OpenAI alt text response:", e);
2874
}
29-
},
30-
error: function (xhr, status, error) {
31-
console.error("❌ AJAX request failed:", status, error);
3275
}
3376
});
34-
}
35-
});
77+
78+
/**
79+
* Handle image removal events.
80+
*/
81+
$(document).on("click", ".file-remove-button", function () {
82+
Backdrop.settings.openaiAlt = null; // Reset settings to allow new uploads
83+
});
84+
85+
// **Run initial setup**
86+
wrapAltTextFields();
87+
triggerAutoGenerationIfNeeded(); // Ensure auto-generation is triggered if needed
88+
});
89+
})(jQuery);

modules/openai_alt/js/openai_alt_autogenerate_ckeditor.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ $(document).ready(function () {
6262
});
6363

6464
function triggerAutoGenerate(fid, src, wrapperId) {
65-
$.ajax({
65+
/*$.ajax({
6666
url: Backdrop.settings.basePath + 'openai-alt/ckeditor-autogenerate',
6767
type: 'POST',
6868
data: {
@@ -81,5 +81,5 @@ function triggerAutoGenerate(fid, src, wrapperId) {
8181
error: function (xhr, status, error) {
8282
console.error("❌ AJAX request failed:", status, error);
8383
}
84-
});
84+
});*/
8585
}

0 commit comments

Comments
 (0)