-
Notifications
You must be signed in to change notification settings - Fork 2
/
openai.module
233 lines (208 loc) · 6.86 KB
/
openai.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<?php
/**
* Implements hook_config_info().
*/
function openai_config_info() {
return [
'openai.settings' => [
'label' => t('OpenAI Settings'),
'group' => t('Configuration'),
],
];
}
/**
* Implements hook_autoload_info().
*/
function openai_autoload_info() {
return [
'OpenAIApi' => 'includes/OpenAIApi.php',
'StringHelper' => 'includes/StringHelper.php',
];
}
/**
* Implements hook_init().
*/
function openai_init() {
// Check if the current path is an admin path.
if (path_is_admin(current_path())) {
// Safely retrieve the API key configuration.
$api_key_config = config('openai.settings')->get('api_key');
// Check if the Key module is enabled.
if (module_exists('key')) {
// Validate the API key if a configuration value exists.
$api_key = !empty($api_key_config) ? key_get_key_value($api_key_config) : NULL;
if (empty($api_key)) {
$message = t('You have not provided an OpenAI API key yet. This is required for its functionality to work. Please obtain an API key from <a href="@account" target="_blank">your OpenAI account</a> and add it to the <a href="@settings">OpenAI settings configuration here</a>.',
[
'@account' => 'https://platform.openai.com/',
'@settings' => url('admin/config/openai/settings'),
]
);
backdrop_set_message($message, 'error');
}
}
else {
// Key module is not enabled, so the OpenAI module cannot work.
$message = t('The Key module is not enabled. The OpenAI module requires the Key module to securely manage API keys. Please enable it from the <a href="@modules">modules page</a>.',
[
'@modules' => url('admin/modules'),
]
);
backdrop_set_message($message, 'error');
}
}
}
/**
* Implements hook_menu().
*/
function openai_menu() {
$items = [];
// Parent item for all OpenAI related configuration pages.
$items['admin/config/openai'] = [
'title' => 'OpenAI',
'description' => 'Configure OpenAI integration.',
'page callback' => 'openai_admin_overview',
'access arguments' => ['administer site configuration'],
'type' => MENU_NORMAL_ITEM,
];
// Submenu for specific OpenAI settings.
$items['admin/config/openai/settings'] = [
'title' => 'Settings',
'description' => 'Manage OpenAI settings, API keys, and organization ID.',
'page callback' => 'backdrop_get_form',
'page arguments' => ['openai_settings_form'],
'access arguments' => ['administer site configuration'],
'type' => MENU_NORMAL_ITEM,
'parent' => 'admin/config/openai', // Parent item.
];
return $items;
}
/**
* Page callback for the OpenAI admin overview page.
*/
function openai_admin_overview() {
backdrop_goto('admin/config/openai/settings');
}
/**
* Settings form for OpenAI configuration.
*/
function openai_settings_form($form, &$form_state) {
$form = [];
$form['#config'] = 'openai.settings';
// Fetch available keys from the Key module.
$available_keys = key_get_key_names_as_options();
// Default to all keys if no specific key is set.
$default_api_key = config_get('openai.settings', 'api_key') ?: '';
$default_api_org = config_get('openai.settings', 'api_org') ?: '';
// Collapsible fieldset for API settings.
$form['api_settings'] = [
'#type' => 'fieldset',
'#title' => t('API Settings'),
'#description' => t('Use keys managed by the <a href="/admin/config/system/keys">Key module</a>.'),
];
// API Key field (dropdown from the Key module).
$form['api_settings']['api_key'] = [
'#type' => 'key_select',
'#title' => t('OpenAI API Key'),
'#default_value' => $default_api_key,
'#options' => $available_keys,
'#key_filters' => ['type' => 'authentication'],
'#description' => t(
'Select the API key to use for accessing OpenAI services. Keys are managed through the <a href="/admin/config/system/keys">Key module</a>.'
),
'#required' => FALSE,
];
// Organization ID field (optional).
$form['api_settings']['api_org'] = [
'#type' => 'key_select',
'#title' => t('Organization ID'),
'#default_value' => $default_api_org,
'#options' => $available_keys,
'#key_filters' => ['type' => 'authentication'],
'#description' => t(
'The organization ID on your OpenAI account. This is required for some OpenAI services to work correctly.'
),
];
// Submit button.
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => t('Save configuration'),
'#submit' => ['openai_settings_form_submit'],
];
// Fetch available models only if the API key is configured.
if (!empty($default_api_key)) {
$models = openai_fetch_available_models($default_api_key);
if (!empty($models)) {
$model_list = '<ul>';
foreach ($models as $model) {
$model_list .= '<li>' . check_plain($model) . '</li>';
}
$model_list .= '</ul>';
$form['models'] = [
'#type' => 'markup',
'#markup' => t('<h3>Available Models</h3>' . $model_list),
];
}
else {
$form['models'] = [
'#type' => 'markup',
'#markup' => t('Failed to fetch models or no models available.'),
];
}
}
else {
$form['models'] = [
'#type' => 'markup',
'#markup' => t('Configure your API key to view available models.'),
];
}
// Link to OpenAI documentation.
$form['docs_link'] = [
'#type' => 'markup',
'#markup' => t(
'For more detailed information, please visit the <a href="@link" target="_blank">OpenAI documentation</a>.',
['@link' => 'https://platform.openai.com/docs']
),
];
return system_settings_form($form);
}
/**
* Fetches available models from OpenAI.
*
* @return array
* A list of models or an empty array if unavailable.
*/
/**
* Fetches available models from OpenAI.
*
* @return array
* A list of models or an empty array if unavailable.
*/
function openai_fetch_available_models() {
try {
// Retrieve the API key identifier from the configuration.
$apiKey = key_get_key_value(config('openai.settings')->get('api_key'));
// Ensure the API key is valid.
if (empty($apiKey) || !is_string($apiKey)) {
watchdog(
'openai',
'The API key could not be retrieved or is invalid. Please configure the key in OpenAI settings.',
[],
WATCHDOG_ERROR
);
return [];
}
// Initialize the API client with the API key.
$api = new OpenAIApi($apiKey);
return $api->getModels();
}
catch (Exception $e) {
watchdog(
'openai',
'Failed to fetch models: @message',
['@message' => $e->getMessage()],
WATCHDOG_ERROR
);
return [];
}
}