Skip to content

Commit 3bcb3d2

Browse files
committed
feat: allow to customize tool's prompt
1 parent 97590df commit 3bcb3d2

File tree

18 files changed

+163
-40
lines changed

18 files changed

+163
-40
lines changed

assets/components/modai/mgr/css/modai.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@
1616
.modai-admin--invalid_row {
1717
background-color: #ffeaea;
1818
}
19+
20+
.modai-admin-label_button {
21+
background-color: transparent;
22+
padding: 0;
23+
border: none;
24+
cursor: pointer;
25+
}

assets/components/modai/mgr/js/tool/panel.js

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,95 @@ modAIAdmin.panel.Tool = function (config) {
2222
items: configItems,
2323
});
2424

25+
this.promptField = new Ext.form.TextArea({
26+
fieldLabel: _('modai.admin.tool.prompt'),
27+
name: 'prompt',
28+
msgTarget: 'under',
29+
value: config.record.prompt || config.record.defaultPrompt,
30+
disabled: !config.record.prompt,
31+
allowBlank: true,
32+
grow: true,
33+
defaultPrompt: config.record.defaultPrompt,
34+
editBtn: null,
35+
resetBtn: null,
36+
renderEditButton: function() {
37+
if (this.editBtn) {
38+
return;
39+
}
40+
41+
const btn = document.createElement('button');
42+
btn.type = 'button';
43+
btn.className = 'modai-admin-label_button';
44+
btn.title = 'Edit Prompt';
45+
btn.addEventListener('click', () => {
46+
this.enable();
47+
btn.remove();
48+
this.editBtn = null;
49+
50+
this.renderResetButton();
51+
});
52+
53+
const i = document.createElement('i');
54+
i.className = 'icon icon-edit';
55+
btn.appendChild(i);
56+
57+
this.editBtn = btn;
58+
this.label.dom.append(btn);
59+
},
60+
renderResetButton: function() {
61+
if (this.resetBtn) {
62+
return;
63+
}
64+
65+
const btn = document.createElement('button');
66+
btn.type = 'button';
67+
btn.className = 'modai-admin-label_button';
68+
btn.title = 'Reset to the default Prompt';
69+
btn.addEventListener('click', () => {
70+
this.setValue(this.defaultPrompt)
71+
this.disable();
72+
btn.remove();
73+
this.resetBtn = null;
74+
75+
this.renderEditButton();
76+
});
77+
78+
const i = document.createElement('i');
79+
i.className = 'icon icon-refresh';
80+
btn.appendChild(i);
81+
82+
this.resetBtn = btn;
83+
this.label.dom.append(btn);
84+
},
85+
initPrompt: function(prompt, defaultPrompt) {
86+
this.defaultPrompt = defaultPrompt;
87+
if (this.editBtn) {
88+
this.editBtn.remove();
89+
this.editBtn = null;
90+
}
91+
92+
if (this.resetBtn) {
93+
this.resetBtn.remove();
94+
this.resetBtn = null;
95+
}
96+
97+
if (prompt) {
98+
this.setValue(prompt);
99+
this.renderResetButton();
100+
return;
101+
}
102+
103+
this.disable();
104+
this.setValue(this.defaultPrompt);
105+
this.renderEditButton();
106+
},
107+
listeners: {
108+
afterrender: function () {
109+
this.initPrompt(config.record.prompt, config.record.defaultPrompt);
110+
}
111+
}
112+
});
113+
25114
Ext.applyIf(config, {
26115
border: false,
27116
cls: 'container',
@@ -44,6 +133,7 @@ modAIAdmin.panel.Tool = function (config) {
44133

45134
Ext.extend(modAIAdmin.panel.Tool, MODx.FormPanel, {
46135
configSection: null,
136+
promptField: null,
47137

48138
success: function (o, r) {
49139
if (this.config.isUpdate === false) {
@@ -136,6 +226,8 @@ Ext.extend(modAIAdmin.panel.Tool, MODx.FormPanel, {
136226
description.setValue(record.data.description);
137227
}
138228

229+
this.promptField.initPrompt(undefined, record.data.defaultPrompt);
230+
139231
this.configSection.removeAll();
140232
Object.entries(record.data.config).forEach(([key, config]) => {
141233
this.configSection.add(modAIAdmin.formatConfigItem(key, config));
@@ -154,13 +246,14 @@ Ext.extend(modAIAdmin.panel.Tool, MODx.FormPanel, {
154246
value: config.record.name,
155247
},
156248
{
157-
fieldLabel: _('modai.admin.context_provider.description'),
249+
fieldLabel: _('modai.admin.tool.description'),
158250
xtype: 'textarea',
159251
name: 'description',
160252
msgTarget: 'under',
161253
value: config.record.description,
162254
allowBlank: true,
163255
},
256+
this.promptField
164257
],
165258
},
166259

assets/components/modai/mgr/js/utils/combos.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ modAIAdmin.combo.ToolClass = function (config) {
162162
hiddenName: 'class',
163163
displayField: 'class',
164164
valueField: 'class',
165-
fields: ['class', 'config', 'suggestedName', 'description'],
165+
fields: ['class', 'config', 'suggestedName', 'description', 'defaultPrompt'],
166166
typeAhead: false,
167167
editable: true,
168168
forceSelection: true,

core/components/modai/controllers/tool/update.class.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public function process(array $scriptProperties = [])
2222

2323
$this->toolData = $tool->toArray();
2424
$this->toolData['classConfig'] = $this->toolData['class']::getConfig($this->modx);
25+
$this->toolData['defaultPrompt'] = $this->toolData['class']::getPrompt();
2526
}
2627

2728
public function getPageTitle()

core/components/modai/lexicon/en/default.inc.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
$_lang['modai.admin.tool.class'] = "Tool Class";
4646
$_lang['modai.admin.tool.tool'] = 'Tool';
4747
$_lang['modai.admin.tool.agents'] = 'Agents';
48+
$_lang['modai.admin.tool.prompt'] = 'Prompt';
4849

4950
$_lang['modai.admin.agent.name'] = 'Name';
5051
$_lang['modai.admin.agent.description'] = 'Description';

core/components/modai/schema/modai.mysql.schema.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<field key="class" dbtype="varchar" precision="200" phptype="string" null="false" />
6969
<field key="name" dbtype="varchar" precision="200" phptype="string" null="false" />
7070
<field key="description" dbtype="varchar" precision="500" phptype="string" null="true" default="" />
71+
<field key="prompt" dbtype="text" phptype="string" null="true" />
7172
<field key="config" dbtype="text" phptype="json" null="true" />
7273
<field key="enabled" dbtype="tinyint" precision="1" phptype="boolean" null="false" default="0" />
7374
<field key="default" dbtype="tinyint" precision="1" phptype="boolean" null="false" default="0" />

core/components/modai/src/Model/mysql/Tool.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Tool extends \modAI\Model\Tool
1919
'class' => NULL,
2020
'name' => NULL,
2121
'description' => '',
22+
'prompt' => NULL,
2223
'config' => NULL,
2324
'enabled' => 0,
2425
'default' => 0,
@@ -47,6 +48,12 @@ class Tool extends \modAI\Model\Tool
4748
'null' => true,
4849
'default' => '',
4950
),
51+
'prompt' =>
52+
array (
53+
'dbtype' => 'text',
54+
'phptype' => 'string',
55+
'null' => true,
56+
),
5057
'config' =>
5158
array (
5259
'dbtype' => 'text',

core/components/modai/src/Processors/Combos/ToolClass.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function process()
4646
'config' => $class::getConfig($this->modx),
4747
'suggestedName' => $class::getSuggestedName(),
4848
'description' => $class::getDescription(),
49+
'defaultPrompt' => $class::getPrompt(),
4950
];
5051
}, $classes), count($classes));
5152
}

core/components/modai/src/Processors/ContextProviders/Create.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function beforeSet()
3838
return false;
3939
}
4040

41-
$config = $class::getConfig();
41+
$config = $class::getConfig($this->modx);
4242
$configValues = [];
4343
foreach ($config as $key => $options) {
4444
$configValues[$key] = $this->getProperty("config_$key");

core/components/modai/src/Processors/ContextProviders/Update.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function beforeSet()
3838
return false;
3939
}
4040

41-
$config = $class::getConfig();
41+
$config = $class::getConfig($this->modx);
4242
$configValues = [];
4343
foreach ($config as $key => $options) {
4444
$configValues[$key] = $this->getProperty("config_$key");

core/components/modai/src/Processors/Tools/Create.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function beforeSet()
3838
return false;
3939
}
4040

41-
$config = $class::getConfig();
41+
$config = $class::getConfig($this->modx);
4242
$configValues = [];
4343
foreach ($config as $key => $options) {
4444
$configValues[$key] = $this->getProperty("config_$key");
@@ -50,6 +50,11 @@ public function beforeSet()
5050

5151
$this->setProperty('config', empty($configValues) ? null : $configValues);
5252

53+
$prompt = $this->getProperty('prompt');
54+
if (empty($prompt)) {
55+
$this->setProperty('prompt', null);
56+
}
57+
5358
return parent::beforeSet();
5459
}
5560
}

core/components/modai/src/Processors/Tools/Update.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function beforeSet()
3838
return false;
3939
}
4040

41-
$config = $class::getConfig();
41+
$config = $class::getConfig($this->modx);
4242
$configValues = [];
4343
foreach ($config as $key => $options) {
4444
$configValues[$key] = $this->getProperty("config_$key");
@@ -50,6 +50,11 @@ public function beforeSet()
5050

5151
$this->setProperty('config', empty($configValues) ? null : $configValues);
5252

53+
$prompt = $this->getProperty('prompt');
54+
if (empty($prompt)) {
55+
$this->setProperty('prompt', null);
56+
}
57+
5358
return parent::beforeSet();
5459
}
5560
}

core/components/modai/src/Services/Anthropic.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,8 @@ public function getCompletions(array $data, CompletionsConfig $config): AIRespon
192192
}
193193

194194
$tools = [];
195-
foreach ($config->getTools() as $toolName => $tool) {
196-
/** @var class-string<ToolInterface> $toolClass */
197-
$toolClass = $tool->get('class');
198-
$params = $toolClass::getParameters();
195+
foreach ($config->getTools() as $tool) {
196+
$params = $tool['parameters'];
199197

200198
if (empty($params)) {
201199
$params = [
@@ -205,8 +203,8 @@ public function getCompletions(array $data, CompletionsConfig $config): AIRespon
205203
}
206204

207205
$tools[] = [
208-
'name' => $toolName,
209-
'description' => $toolClass::getPrompt(),
206+
'name' => $tool['name'],
207+
'description' => $tool['description'],
210208
'input_schema' => (object)$params,
211209
];
212210
}

core/components/modai/src/Services/Config/CompletionsConfig.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace modAI\Services\Config;
44

55
use modAI\Model\Tool;
6+
use modAI\Tools\ToolInterface;
67

78
class CompletionsConfig
89
{
@@ -90,11 +91,24 @@ public function getMessages(): array
9091
}
9192

9293
/**
93-
* @return array<string, Tool>
94+
* @return array<int, array{name: string, description: string, parameters: array}>
9495
*/
9596
public function getTools(): array
9697
{
97-
return $this->tools;
98+
$tools = [];
99+
foreach ($this->tools as $toolName => $tool) {
100+
/** @var class-string<ToolInterface> $toolClass */
101+
$toolClass = $tool->get('class');
102+
103+
$prompt = $tool->get('prompt');
104+
$tools[] = [
105+
'name' => $toolName,
106+
'description' => !empty($prompt) ? $prompt : $toolClass::getPrompt(),
107+
'parameters' => $toolClass::getParameters(),
108+
];
109+
}
110+
111+
return $tools;
98112
}
99113

100114
public function getToolChoice(): string

core/components/modai/src/Services/CustomOpenAI.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,16 +166,14 @@ public function getCompletions(array $data, CompletionsConfig $config): AIRespon
166166
$input['messages'] = $messages;
167167

168168
$tools = [];
169-
foreach ($config->getTools() as $toolName => $tool) {
170-
/** @var class-string<ToolInterface> $toolClass */
171-
$toolClass = $tool->get('class');
169+
foreach ($config->getTools() as $tool) {
172170

173171
$tools[] = [
174172
'type' => 'function',
175173
'function' => [
176-
'name' => $toolName,
177-
'description' => $toolClass::getPrompt(),
178-
'parameters' => (object)$toolClass::getParameters(),
174+
'name' => $tool['name'],
175+
'description' => $tool['description'],
176+
'parameters' => (object)$tool['parameters'],
179177
]
180178
];
181179
}

core/components/modai/src/Services/Google.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,17 +212,15 @@ public function getCompletions(array $data, CompletionsConfig $config): AIRespon
212212
}
213213

214214
$tools = [];
215-
foreach ($config->getTools() as $toolName => $tool) {
216-
/** @var class-string<ToolInterface> $toolClass */
217-
$toolClass = $tool->get('class');
218-
$params = $toolClass::getParameters();
215+
foreach ($config->getTools() as $tool) {
216+
$params = $tool['parameters'];
219217
if (empty($params)) {
220218
$params = null;
221219
}
222220

223221
$tools[] = [
224-
'name' => $toolName,
225-
'description' => $toolClass::getPrompt(),
222+
'name' => $tool['name'],
223+
'description' => $tool['description'],
226224
'parameters' => $params,
227225
];
228226
}

core/components/modai/src/Services/OpenAI.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,16 +160,13 @@ public function getCompletions(array $data, CompletionsConfig $config): AIRespon
160160
$input['messages'] = $messages;
161161

162162
$tools = [];
163-
foreach ($config->getTools() as $toolName => $tool) {
164-
/** @var class-string<ToolInterface> $toolClass */
165-
$toolClass = $tool->get('class');
166-
163+
foreach ($config->getTools() as $tool) {
167164
$tools[] = [
168165
'type' => 'function',
169166
'function' => [
170-
'name' => $toolName,
171-
'description' => $toolClass::getPrompt(),
172-
'parameters' => (object)$toolClass::getParameters(),
167+
'name' => $tool['name'],
168+
'description' => $tool['description'],
169+
'parameters' => (object)$tool['parameters'],
173170
]
174171
];
175172
}

0 commit comments

Comments
 (0)