mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-03-02 23:39:30 +00:00
* FEATURE: allow personas to supply top_p and temperature params Code assistance generally are more focused at a lower temperature This amends it so SQL Helper runs at 0.2 temperature vs the more common default across LLMs of 1.0. Reduced temperature leads to more focused, concise and predictable answers for the SQL Helper * fix tests * This is not perfect, but far better than what we do today Instead of fishing for 1. Draft sequence 2. Draft body We skip (2), this means the composer "only" needs 1 http request to open, we also want to eliminate (1) but it is a bit of a trickier core change, may figure out how to pull it off (defer it to first draft save) Value of bot drafts < value of opening bot conversations really fast
98 lines
2.6 KiB
JavaScript
98 lines
2.6 KiB
JavaScript
import { tracked } from "@glimmer/tracking";
|
|
import RestModel from "discourse/models/rest";
|
|
|
|
const ATTRIBUTES = [
|
|
"name",
|
|
"description",
|
|
"commands",
|
|
"system_prompt",
|
|
"allowed_group_ids",
|
|
"enabled",
|
|
"system",
|
|
"priority",
|
|
"top_p",
|
|
"temperature",
|
|
];
|
|
|
|
class CommandOption {
|
|
@tracked value = null;
|
|
}
|
|
|
|
export default class AiPersona extends RestModel {
|
|
// this code is here to convert the wire schema to easier to work with object
|
|
// on the wire we pass in/out commands as an Array.
|
|
// [[CommandName, {option1: value, option2: value}], CommandName2, CommandName3]
|
|
// So we rework this into a "commands" property and nested commandOptions
|
|
init(properties) {
|
|
if (properties.commands) {
|
|
properties.commands = properties.commands.map((command) => {
|
|
if (typeof command === "string") {
|
|
return command;
|
|
} else {
|
|
let [commandId, options] = command;
|
|
for (let optionId in options) {
|
|
if (!options.hasOwnProperty(optionId)) {
|
|
continue;
|
|
}
|
|
this.getCommandOption(commandId, optionId).value =
|
|
options[optionId];
|
|
}
|
|
return commandId;
|
|
}
|
|
});
|
|
}
|
|
super.init(properties);
|
|
this.commands = properties.commands;
|
|
}
|
|
|
|
getCommandOption(commandId, optionId) {
|
|
this.commandOptions ||= {};
|
|
this.commandOptions[commandId] ||= {};
|
|
return (this.commandOptions[commandId][optionId] ||= new CommandOption());
|
|
}
|
|
|
|
populateCommandOptions(attrs) {
|
|
if (!attrs.commands) {
|
|
return;
|
|
}
|
|
let commandsWithOptions = [];
|
|
attrs.commands.forEach((commandId) => {
|
|
if (typeof commandId !== "string") {
|
|
commandId = commandId[0];
|
|
}
|
|
if (this.commandOptions && this.commandOptions[commandId]) {
|
|
let options = this.commandOptions[commandId];
|
|
let optionsWithValues = {};
|
|
for (let optionId in options) {
|
|
if (!options.hasOwnProperty(optionId)) {
|
|
continue;
|
|
}
|
|
let option = options[optionId];
|
|
optionsWithValues[optionId] = option.value;
|
|
}
|
|
commandsWithOptions.push([commandId, optionsWithValues]);
|
|
} else {
|
|
commandsWithOptions.push(commandId);
|
|
}
|
|
});
|
|
attrs.commands = commandsWithOptions;
|
|
}
|
|
|
|
updateProperties() {
|
|
let attrs = this.getProperties(ATTRIBUTES);
|
|
attrs.id = this.id;
|
|
this.populateCommandOptions(attrs);
|
|
return attrs;
|
|
}
|
|
|
|
createProperties() {
|
|
let attrs = this.getProperties(ATTRIBUTES);
|
|
this.populateCommandOptions(attrs);
|
|
return attrs;
|
|
}
|
|
|
|
workingCopy() {
|
|
return AiPersona.create(this.createProperties());
|
|
}
|
|
}
|