Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit ba934d0

Browse files
committed
REFACTOR: Migrate Personas' form to FormKit
We re-arranged fields into sections so we can better differentiate which options are specific to the AI bot.
1 parent 451f766 commit ba934d0

File tree

16 files changed

+786
-921
lines changed

16 files changed

+786
-921
lines changed
Lines changed: 51 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { tracked } from "@glimmer/tracking";
21
import { ajax } from "discourse/lib/ajax";
32
import RestModel from "discourse/models/rest";
43

@@ -63,40 +62,7 @@ const SYSTEM_ATTRIBUTES = [
6362
"allow_chat_direct_messages",
6463
];
6564

66-
class ToolOption {
67-
@tracked value = null;
68-
}
69-
7065
export default class AiPersona extends RestModel {
71-
// this code is here to convert the wire schema to easier to work with object
72-
// on the wire we pass in/out tools as an Array.
73-
// [[ToolName, {option1: value, option2: value}, force], ToolName2, ToolName3]
74-
// So we rework this into a "tools" property and nested toolOptions
75-
init(properties) {
76-
this.forcedTools = [];
77-
if (properties.tools) {
78-
properties.tools = properties.tools.map((tool) => {
79-
if (typeof tool === "string") {
80-
return tool;
81-
} else {
82-
let [toolId, options, force] = tool;
83-
for (let optionId in options) {
84-
if (!options.hasOwnProperty(optionId)) {
85-
continue;
86-
}
87-
this.getToolOption(toolId, optionId).value = options[optionId];
88-
}
89-
if (force) {
90-
this.forcedTools.push(toolId);
91-
}
92-
return toolId;
93-
}
94-
});
95-
}
96-
super.init(properties);
97-
this.tools = properties.tools;
98-
}
99-
10066
async createUser() {
10167
const result = await ajax(
10268
`/admin/plugins/discourse-ai/ai-personas/${this.id}/create-user.json`,
@@ -109,63 +75,79 @@ export default class AiPersona extends RestModel {
10975
return this.user;
11076
}
11177

112-
getToolOption(toolId, optionId) {
113-
this.toolOptions ||= {};
114-
this.toolOptions[toolId] ||= {};
115-
return (this.toolOptions[toolId][optionId] ||= new ToolOption());
78+
flattenedToolStructure(data) {
79+
return data.tools.map((tName) => {
80+
return [tName, data.toolOptions[tName], data.forcedTools.includes(tName)];
81+
});
11682
}
11783

118-
populateToolOptions(attrs) {
119-
if (!attrs.tools) {
120-
return;
121-
}
122-
let toolsWithOptions = [];
123-
attrs.tools.forEach((toolId) => {
124-
if (typeof toolId !== "string") {
125-
toolId = toolId[0];
126-
}
84+
// this code is here to convert the wire schema to easier to work with object
85+
// on the wire we pass in/out tools as an Array.
86+
// [[ToolName, {option1: value, option2: value}, force], ToolName2, ToolName3]
87+
// We split it into tools, options and a list of forced ones.
88+
populateTools(attrs) {
89+
const forcedTools = [];
90+
const toolOptions = {};
91+
92+
const flatTools = attrs.tools?.map((tool) => {
93+
if (typeof tool === "string") {
94+
return tool;
95+
} else {
96+
let [toolId, options, force] = tool;
97+
const mappedOptions = {};
12798

128-
let force = this.forcedTools.includes(toolId);
129-
if (this.toolOptions && this.toolOptions[toolId]) {
130-
let options = this.toolOptions[toolId];
131-
let optionsWithValues = {};
132-
for (let optionId in options) {
99+
for (const optionId in options) {
133100
if (!options.hasOwnProperty(optionId)) {
134101
continue;
135102
}
136-
let option = options[optionId];
137-
optionsWithValues[optionId] = option.value;
103+
104+
mappedOptions[optionId] = options[optionId];
138105
}
139-
toolsWithOptions.push([toolId, optionsWithValues, force]);
140-
} else {
141-
toolsWithOptions.push([toolId, {}, force]);
106+
107+
if (Object.keys(mappedOptions).length > 0) {
108+
toolOptions[toolId] = mappedOptions;
109+
}
110+
111+
if (force) {
112+
forcedTools.push(toolId);
113+
}
114+
115+
return toolId;
142116
}
143117
});
144-
attrs.tools = toolsWithOptions;
118+
119+
attrs.tools = flatTools;
120+
attrs.forcedTools = forcedTools;
121+
attrs.toolOptions = toolOptions;
145122
}
146123

147124
updateProperties() {
148-
let attrs = this.system
125+
const attrs = this.system
149126
? this.getProperties(SYSTEM_ATTRIBUTES)
150127
: this.getProperties(CREATE_ATTRIBUTES);
151128
attrs.id = this.id;
152-
this.populateToolOptions(attrs);
129+
153130
return attrs;
154131
}
155132

156133
createProperties() {
157-
let attrs = this.getProperties(CREATE_ATTRIBUTES);
158-
this.populateToolOptions(attrs);
159-
return attrs;
134+
return this.getProperties(CREATE_ATTRIBUTES);
160135
}
161136

162-
workingCopy() {
163-
let attrs = this.getProperties(CREATE_ATTRIBUTES);
164-
this.populateToolOptions(attrs);
137+
fromPOJO(data) {
138+
const dataClone = JSON.parse(JSON.stringify(data));
139+
140+
const persona = AiPersona.create(dataClone);
141+
persona.tools = this.flattenedToolStructure(dataClone);
165142

166-
const persona = AiPersona.create(attrs);
167-
persona.forcedTools = (this.forcedTools || []).slice();
168-
persona.forced_tool_count = this.forced_tool_count || -1;
169143
return persona;
170144
}
145+
146+
toPOJO() {
147+
const attrs = this.getProperties(CREATE_ATTRIBUTES);
148+
this.populateTools(attrs);
149+
attrs.forced_tool_count = this.forced_tool_count || -1;
150+
151+
return attrs;
152+
}
171153
}

assets/javascripts/discourse/components/ai-forced-tool-strategy-selector.gjs

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { hash } from "@ember/helper";
2+
import ComboBox from "select-kit/components/combo-box";
3+
4+
const AiLlmSelector = <template>
5+
<ComboBox
6+
@value={{@value}}
7+
@content={{@llms}}
8+
@onChange={{@onChange}}
9+
@options={{hash
10+
filterable=true
11+
none="discourse_ai.ai_persona.no_llm_selected"
12+
}}
13+
class={{@class}}
14+
/>
15+
</template>;
16+
17+
export default AiLlmSelector;

assets/javascripts/discourse/components/ai-llm-selector.js

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)