Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9369d9d0d7 | ||
|
|
5bf61ef9e1 | ||
|
|
107f14456b | ||
|
|
269f169abf | ||
|
|
7d7c169afa | ||
|
|
9211b211f5 | ||
|
|
24e6aa52bb | ||
|
|
48fff48aa2 | ||
|
|
bd40076dc1 | ||
|
|
3533cd1acc | ||
|
|
51ca942d7d | ||
|
|
ec8018333e | ||
|
|
6aaf8a0619 | ||
|
|
ac29d3080f | ||
|
|
65503a5038 | ||
|
|
b17c688162 | ||
|
|
e59184b65c | ||
|
|
8f4cd2fcbd | ||
|
|
f4708d4178 | ||
|
|
833f914e34 | ||
|
|
168d9d8eb9 | ||
|
|
3da4f5eac3 | ||
|
|
bb32d0d737 | ||
|
|
339251a371 |
+59
-45
@@ -1,79 +1,93 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (7.1.3.4)
|
||||
activesupport (8.0.2)
|
||||
base64
|
||||
benchmark (>= 0.3)
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
concurrent-ruby (~> 1.0, >= 1.3.1)
|
||||
connection_pool (>= 2.2.5)
|
||||
drb
|
||||
i18n (>= 1.6, < 2)
|
||||
logger (>= 1.4.2)
|
||||
minitest (>= 5.1)
|
||||
mutex_m
|
||||
tzinfo (~> 2.0)
|
||||
securerandom (>= 0.3)
|
||||
tzinfo (~> 2.0, >= 2.0.5)
|
||||
uri (>= 0.13.1)
|
||||
ast (2.4.2)
|
||||
base64 (0.2.0)
|
||||
bigdecimal (3.1.8)
|
||||
concurrent-ruby (1.3.3)
|
||||
connection_pool (2.4.1)
|
||||
benchmark (0.4.0)
|
||||
bigdecimal (3.1.9)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.0)
|
||||
drb (2.2.1)
|
||||
i18n (1.14.5)
|
||||
i18n (1.14.7)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.7.2)
|
||||
language_server-protocol (3.17.0.3)
|
||||
minitest (5.24.1)
|
||||
mutex_m (0.2.0)
|
||||
parallel (1.25.1)
|
||||
parser (3.3.3.0)
|
||||
json (2.10.2)
|
||||
language_server-protocol (3.17.0.4)
|
||||
lint_roller (1.1.0)
|
||||
logger (1.6.6)
|
||||
minitest (5.25.5)
|
||||
parallel (1.26.3)
|
||||
parser (3.3.7.1)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
prettier_print (1.2.1)
|
||||
racc (1.8.0)
|
||||
rack (3.1.10)
|
||||
racc (1.8.1)
|
||||
rack (3.1.12)
|
||||
rainbow (3.1.1)
|
||||
regexp_parser (2.9.2)
|
||||
rexml (3.3.9)
|
||||
rubocop (1.64.1)
|
||||
regexp_parser (2.10.0)
|
||||
rubocop (1.74.0)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
regexp_parser (>= 2.9.3, < 3.0)
|
||||
rubocop-ast (>= 1.38.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.31.3)
|
||||
unicode-display_width (>= 2.4.0, < 4.0)
|
||||
rubocop-ast (1.38.1)
|
||||
parser (>= 3.3.1.0)
|
||||
rubocop-capybara (2.21.0)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-discourse (3.8.1)
|
||||
rubocop-capybara (2.22.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-discourse (3.12.1)
|
||||
activesupport (>= 6.1)
|
||||
rubocop (>= 1.59.0)
|
||||
rubocop-capybara (>= 2.0.0)
|
||||
rubocop-factory_bot (>= 2.0.0)
|
||||
rubocop-rails (>= 2.25.0)
|
||||
lint_roller (>= 1.1.0)
|
||||
rubocop (>= 1.73.2)
|
||||
rubocop-capybara (>= 2.22.0)
|
||||
rubocop-factory_bot (>= 2.27.0)
|
||||
rubocop-rails (>= 2.30.3)
|
||||
rubocop-rspec (>= 3.0.1)
|
||||
rubocop-rspec_rails (>= 2.30.0)
|
||||
rubocop-factory_bot (2.26.1)
|
||||
rubocop (~> 1.61)
|
||||
rubocop-rails (2.25.1)
|
||||
rubocop-rspec_rails (>= 2.31.0)
|
||||
rubocop-factory_bot (2.27.1)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rails (2.30.3)
|
||||
activesupport (>= 4.2.0)
|
||||
lint_roller (~> 1.1)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
rubocop-rspec (3.0.2)
|
||||
rubocop (~> 1.61)
|
||||
rubocop-rspec_rails (2.30.0)
|
||||
rubocop (~> 1.61)
|
||||
rubocop-rspec (~> 3, >= 3.0.1)
|
||||
rubocop (>= 1.72.1, < 2.0)
|
||||
rubocop-ast (>= 1.38.0, < 2.0)
|
||||
rubocop-rspec (3.5.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rspec_rails (2.31.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rspec (~> 3.5)
|
||||
ruby-progressbar (1.13.0)
|
||||
securerandom (0.4.1)
|
||||
syntax_tree (6.2.0)
|
||||
prettier_print (>= 1.2.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
unicode-display_width (2.5.0)
|
||||
unicode-display_width (3.1.4)
|
||||
unicode-emoji (~> 4.0, >= 4.0.4)
|
||||
unicode-emoji (4.0.4)
|
||||
uri (1.0.3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -83,4 +97,4 @@ DEPENDENCIES
|
||||
syntax_tree
|
||||
|
||||
BUNDLED WITH
|
||||
2.5.10
|
||||
2.6.6
|
||||
|
||||
+5
-1
@@ -1,6 +1,10 @@
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default class DiscourseAiToolsNewRoute extends DiscourseRoute {
|
||||
beforeModel(transition) {
|
||||
this.preset = transition.to.queryParams.presetId || "empty_tool";
|
||||
}
|
||||
|
||||
async model() {
|
||||
return this.store.createRecord("ai-tool");
|
||||
}
|
||||
@@ -8,10 +12,10 @@ export default class DiscourseAiToolsNewRoute extends DiscourseRoute {
|
||||
setupController(controller) {
|
||||
super.setupController(...arguments);
|
||||
const toolsModel = this.modelFor("adminPlugins.show.discourse-ai-tools");
|
||||
|
||||
controller.set("allTools", toolsModel);
|
||||
controller.set("presets", toolsModel.resultSetMeta.presets);
|
||||
controller.set("llms", toolsModel.resultSetMeta.llms);
|
||||
controller.set("settings", toolsModel.resultSetMeta.settings);
|
||||
controller.set("selectedPreset", this.preset);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -5,5 +5,6 @@
|
||||
@presets={{this.presets}}
|
||||
@llms={{this.llms}}
|
||||
@settings={{this.settings}}
|
||||
@selectedPreset={{this.selectedPreset}}
|
||||
/>
|
||||
</section>
|
||||
@@ -53,7 +53,12 @@ module DiscourseAi
|
||||
end
|
||||
|
||||
def suggest_title
|
||||
input = get_text_param!
|
||||
if params[:topic_id]
|
||||
topic = Topic.find_by(id: params[:topic_id])
|
||||
input = DiscourseAi::Summarization::Strategies::TopicSummary.new(topic).targets_data
|
||||
else
|
||||
input = get_text_param!
|
||||
end
|
||||
|
||||
prompt = CompletionPrompt.enabled_by_name("generate_titles")
|
||||
raise Discourse::InvalidParameters.new(:mode) if !prompt
|
||||
@@ -73,22 +78,26 @@ module DiscourseAi
|
||||
end
|
||||
|
||||
def suggest_category
|
||||
input = get_text_param!
|
||||
input_hash = { text: input }
|
||||
if params[:topic_id]
|
||||
opts = { topic_id: params[:topic_id] }
|
||||
else
|
||||
input = get_text_param!
|
||||
opts = { text: input }
|
||||
end
|
||||
|
||||
render json:
|
||||
DiscourseAi::AiHelper::SemanticCategorizer.new(
|
||||
input_hash,
|
||||
current_user,
|
||||
).categories,
|
||||
render json: DiscourseAi::AiHelper::SemanticCategorizer.new(current_user, opts).categories,
|
||||
status: 200
|
||||
end
|
||||
|
||||
def suggest_tags
|
||||
input = get_text_param!
|
||||
input_hash = { text: input }
|
||||
if params[:topic_id]
|
||||
opts = { topic_id: params[:topic_id] }
|
||||
else
|
||||
input = get_text_param!
|
||||
opts = { text: input }
|
||||
end
|
||||
|
||||
render json: DiscourseAi::AiHelper::SemanticCategorizer.new(input_hash, current_user).tags,
|
||||
render json: DiscourseAi::AiHelper::SemanticCategorizer.new(current_user, opts).tags,
|
||||
status: 200
|
||||
end
|
||||
|
||||
|
||||
@@ -26,17 +26,23 @@ class LlmModel < ActiveRecord::Base
|
||||
access_key_id: :text,
|
||||
region: :text,
|
||||
disable_native_tools: :checkbox,
|
||||
disable_temperature: :checkbox,
|
||||
disable_top_p: :checkbox,
|
||||
enable_reasoning: :checkbox,
|
||||
reasoning_tokens: :number,
|
||||
},
|
||||
anthropic: {
|
||||
disable_native_tools: :checkbox,
|
||||
disable_temperature: :checkbox,
|
||||
disable_top_p: :checkbox,
|
||||
enable_reasoning: :checkbox,
|
||||
reasoning_tokens: :number,
|
||||
},
|
||||
open_ai: {
|
||||
organization: :text,
|
||||
disable_native_tools: :checkbox,
|
||||
disable_temperature: :checkbox,
|
||||
disable_top_p: :checkbox,
|
||||
disable_streaming: :checkbox,
|
||||
reasoning_effort: {
|
||||
type: :enum,
|
||||
@@ -69,6 +75,8 @@ class LlmModel < ActiveRecord::Base
|
||||
provider_order: :text,
|
||||
provider_quantizations: :text,
|
||||
disable_streaming: :checkbox,
|
||||
disable_temperature: :checkbox,
|
||||
disable_top_p: :checkbox,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
@@ -32,8 +32,10 @@ export default class AiTool extends RestModel {
|
||||
|
||||
if (parameter.enum && parameter.enum.length) {
|
||||
parameter.enum = new TrackedArray(parameter.enum);
|
||||
parameter.isEnum = true;
|
||||
} else {
|
||||
parameter.enum = null;
|
||||
parameter.isEnum = false;
|
||||
}
|
||||
|
||||
return parameter;
|
||||
|
||||
@@ -219,6 +219,7 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
this.router.transitionTo(this.router.currentRoute.name, {
|
||||
queryParams: {
|
||||
...currentQueryParams,
|
||||
filters: JSON.parse(currentQueryParams.filters), // avoids a double escaping
|
||||
selectedChart: data.title,
|
||||
},
|
||||
});
|
||||
@@ -267,6 +268,7 @@ export default class AdminReportSentimentAnalysis extends Component {
|
||||
this.router.transitionTo(this.router.currentRoute.name, {
|
||||
queryParams: {
|
||||
...currentQueryParams,
|
||||
filters: JSON.parse(currentQueryParams.filters), // avoids a double escaping
|
||||
selectedChart: null,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@ import getURL from "discourse/lib/get-url";
|
||||
|
||||
export default class AiArtifactComponent extends Component {
|
||||
@service siteSettings;
|
||||
|
||||
@tracked expanded = false;
|
||||
@tracked showingArtifact = false;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ export default class AiComposerHelperMenu extends Component {
|
||||
@service siteSettings;
|
||||
@service currentUser;
|
||||
@service site;
|
||||
|
||||
@tracked newSelectedText;
|
||||
@tracked diff;
|
||||
@tracked customPromptValue = "";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { service } from "@ember/service";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import icon from "discourse/helpers/d-icon";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import DTooltip from "float-kit/components/d-tooltip";
|
||||
|
||||
export default class AiSearchDiscoveriesTooltip extends Component {
|
||||
@service discobotDiscoveries;
|
||||
|
||||
<template>
|
||||
<span class="ai-search-discoveries-tooltip">
|
||||
<DTooltip @placement="top-end" @interactive={{true}}>
|
||||
<:trigger>
|
||||
{{icon "circle-info"}}
|
||||
</:trigger>
|
||||
<:content>
|
||||
<div class="ai-search-discoveries-tooltip__content">
|
||||
<div class="ai-search-discoveries-tooltip__header">
|
||||
{{i18n "discourse_ai.discobot_discoveries.tooltip.header"}}
|
||||
</div>
|
||||
|
||||
<div class="ai-search-discoveries-tooltip__description">
|
||||
{{#if this.discobotDiscoveries.modelUsed}}
|
||||
{{i18n
|
||||
"discourse_ai.discobot_discoveries.tooltip.content"
|
||||
model=this.discobotDiscoveries.modelUsed
|
||||
}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="ai-search-discoveries-tooltip__actions">
|
||||
<DButton
|
||||
class="btn-transparent btn-primary"
|
||||
@label="discourse_ai.discobot_discoveries.tooltip.actions.info"
|
||||
@href="https://meta.discourse.org/t/conversational-ai-search-coming-to-discourse-ai/355939"
|
||||
/>
|
||||
<DButton
|
||||
class="btn-transparent btn-danger"
|
||||
@label="discourse_ai.discobot_discoveries.tooltip.actions.disable"
|
||||
@action={{this.discobotDiscoveries.disableDiscoveries}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</:content>
|
||||
</DTooltip>
|
||||
</span>
|
||||
</template>
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,36 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { fn } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { LinkTo } from "@ember/routing";
|
||||
import { service } from "@ember/service";
|
||||
import { eq } from "truth-helpers";
|
||||
import DBreadcrumbsItem from "discourse/components/d-breadcrumbs-item";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import DPageSubheader from "discourse/components/d-page-subheader";
|
||||
import DropdownMenu from "discourse/components/dropdown-menu";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import AdminConfigAreaEmptyList from "admin/components/admin-config-area-empty-list";
|
||||
import DMenu from "float-kit/components/d-menu";
|
||||
|
||||
export default class AiToolListEditor extends Component {
|
||||
@service adminPluginNavManager;
|
||||
@service router;
|
||||
|
||||
get lastIndexOfPresets() {
|
||||
return this.args.tools.resultSetMeta.presets.length - 1;
|
||||
}
|
||||
|
||||
@action
|
||||
routeToNewTool(preset) {
|
||||
return this.router.transitionTo(
|
||||
"adminPlugins.show.discourse-ai-tools.new",
|
||||
{
|
||||
queryParams: {
|
||||
presetId: preset.preset_id,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
<template>
|
||||
<DBreadcrumbsItem
|
||||
@@ -20,13 +43,33 @@ export default class AiToolListEditor extends Component {
|
||||
@learnMoreUrl="https://meta.discourse.org/t/ai-bot-custom-tools/314103"
|
||||
@descriptionLabel={{i18n "discourse_ai.tools.subheader_description"}}
|
||||
>
|
||||
<:actions as |actions|>
|
||||
<actions.Primary
|
||||
@label="discourse_ai.tools.new"
|
||||
@route="adminPlugins.show.discourse-ai-tools.new"
|
||||
<:actions>
|
||||
<DMenu
|
||||
@triggerClass="btn-primary btn-small ai-tool-list-editor__new-button"
|
||||
@label={{i18n "discourse_ai.tools.new"}}
|
||||
@icon="plus"
|
||||
class="ai-tool-list-editor__new-button"
|
||||
/>
|
||||
@placement="bottom-end"
|
||||
>
|
||||
<:content>
|
||||
<DropdownMenu as |dropdown|>
|
||||
{{#each @tools.resultSetMeta.presets as |preset index|}}
|
||||
{{#if (eq index this.lastIndexOfPresets)}}
|
||||
<dropdown.divider />
|
||||
{{/if}}
|
||||
|
||||
<dropdown.item>
|
||||
<DButton
|
||||
@translatedLabel={{preset.preset_name}}
|
||||
@action={{fn this.routeToNewTool preset}}
|
||||
class="btn-transparent"
|
||||
data-option={{preset.preset_id}}
|
||||
/>
|
||||
</dropdown.item>
|
||||
{{/each}}
|
||||
</DropdownMenu>
|
||||
|
||||
</:content>
|
||||
</DMenu>
|
||||
</:actions>
|
||||
</DPageSubheader>
|
||||
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { fn } from "@ember/helper";
|
||||
import { on } from "@ember/modifier";
|
||||
import { action } from "@ember/object";
|
||||
import { TrackedArray, TrackedObject } from "@ember-compat/tracked-built-ins";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import withEventValue from "discourse/helpers/with-event-value";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import ComboBox from "select-kit/components/combo-box";
|
||||
|
||||
const PARAMETER_TYPES = [
|
||||
{ name: "string", id: "string" },
|
||||
{ name: "number", id: "number" },
|
||||
{ name: "boolean", id: "boolean" },
|
||||
{ name: "array", id: "array" },
|
||||
];
|
||||
|
||||
export default class AiToolParameterEditor extends Component {
|
||||
@action
|
||||
addParameter() {
|
||||
this.args.parameters.push(
|
||||
new TrackedObject({
|
||||
name: "",
|
||||
description: "",
|
||||
type: "string",
|
||||
required: false,
|
||||
enum: null,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
removeParameter(parameter) {
|
||||
const index = this.args.parameters.indexOf(parameter);
|
||||
this.args.parameters.splice(index, 1);
|
||||
}
|
||||
|
||||
@action
|
||||
toggleRequired(parameter, event) {
|
||||
parameter.required = event.target.checked;
|
||||
}
|
||||
|
||||
@action
|
||||
toggleEnum(parameter) {
|
||||
if (parameter.enum) {
|
||||
parameter.enum = null;
|
||||
} else {
|
||||
this.addEnumValue(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
addEnumValue(parameter) {
|
||||
parameter.enum ||= new TrackedArray();
|
||||
parameter.enum.push("");
|
||||
}
|
||||
|
||||
@action
|
||||
removeEnumValue(parameter, index) {
|
||||
parameter.enum.splice(index, 1);
|
||||
if (parameter.enum.length === 0) {
|
||||
parameter.enum = null;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
updateEnumValue(parameter, index, event) {
|
||||
parameter.enum[index] = event.target.value;
|
||||
}
|
||||
|
||||
<template>
|
||||
{{#each @parameters as |parameter|}}
|
||||
<div class="ai-tool-parameter">
|
||||
<div class="parameter-row">
|
||||
<input
|
||||
{{on "input" (withEventValue (fn (mut parameter.name)))}}
|
||||
value={{parameter.name}}
|
||||
type="text"
|
||||
placeholder={{i18n "discourse_ai.tools.parameter_name"}}
|
||||
/>
|
||||
<ComboBox @value={{parameter.type}} @content={{PARAMETER_TYPES}} />
|
||||
</div>
|
||||
|
||||
<div class="parameter-row">
|
||||
<input
|
||||
{{on "input" (withEventValue (fn (mut parameter.description)))}}
|
||||
value={{parameter.description}}
|
||||
type="text"
|
||||
placeholder={{i18n "discourse_ai.tools.parameter_description"}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="parameter-row">
|
||||
<label>
|
||||
<input
|
||||
{{on "input" (fn this.toggleRequired parameter)}}
|
||||
checked={{parameter.required}}
|
||||
type="checkbox"
|
||||
class="parameter-row__required-toggle"
|
||||
/>
|
||||
{{i18n "discourse_ai.tools.parameter_required"}}
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<input
|
||||
{{on "input" (fn this.toggleEnum parameter)}}
|
||||
checked={{parameter.enum}}
|
||||
type="checkbox"
|
||||
class="parameter-row__enum-toggle"
|
||||
/>
|
||||
{{i18n "discourse_ai.tools.parameter_enum"}}
|
||||
</label>
|
||||
|
||||
<DButton
|
||||
@action={{fn this.removeParameter parameter}}
|
||||
@icon="trash-can"
|
||||
class="btn-danger"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{{#if parameter.enum}}
|
||||
<div class="parameter-enum-values">
|
||||
{{#each parameter.enum as |enumValue enumIndex|}}
|
||||
<div class="enum-value-row">
|
||||
<input
|
||||
{{on "change" (fn this.updateEnumValue parameter enumIndex)}}
|
||||
value={{enumValue}}
|
||||
type="text"
|
||||
placeholder={{i18n "discourse_ai.tools.enum_value"}}
|
||||
/>
|
||||
<DButton
|
||||
@action={{fn this.removeEnumValue parameter enumIndex}}
|
||||
@icon="trash-can"
|
||||
class="btn-danger"
|
||||
/>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
||||
<DButton
|
||||
@action={{fn this.addEnumValue parameter}}
|
||||
@label="discourse_ai.tools.add_enum_value"
|
||||
@icon="plus"
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/each}}
|
||||
|
||||
<DButton
|
||||
@action={{this.addParameter}}
|
||||
@label="discourse_ai.tools.add_parameter"
|
||||
@icon="plus"
|
||||
/>
|
||||
</template>
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import ComboBox from "select-kit/components/combo-box";
|
||||
|
||||
export default class AiUsage extends Component {
|
||||
@service store;
|
||||
|
||||
@tracked startDate = moment().subtract(30, "days").toDate();
|
||||
@tracked endDate = new Date();
|
||||
@tracked data = this.args.model;
|
||||
|
||||
@@ -13,6 +13,7 @@ import AiIndicatorWave from "../ai-indicator-wave";
|
||||
|
||||
export default class ModalDiffModal extends Component {
|
||||
@service currentUser;
|
||||
|
||||
@tracked loading = false;
|
||||
@tracked diff;
|
||||
@tracked suggestion = "";
|
||||
|
||||
@@ -13,6 +13,7 @@ import { i18n } from "discourse-i18n";
|
||||
|
||||
export default class ShareModal extends Component {
|
||||
@service toasts;
|
||||
|
||||
@tracked shareKey = "";
|
||||
|
||||
constructor() {
|
||||
|
||||
@@ -16,6 +16,7 @@ export default class ShareModal extends Component {
|
||||
@service modal;
|
||||
@service siteSettings;
|
||||
@service currentUser;
|
||||
|
||||
@tracked contextValue = 1;
|
||||
@tracked htmlContext = "";
|
||||
@tracked maxContext = 0;
|
||||
|
||||
@@ -9,6 +9,7 @@ import { i18n } from "discourse-i18n";
|
||||
|
||||
export default class RagUploadProgress extends Component {
|
||||
@service messageBus;
|
||||
|
||||
@tracked updatedProgress = null;
|
||||
|
||||
willDestroy() {
|
||||
|
||||
@@ -16,6 +16,7 @@ import RagUploadProgress from "./rag-upload-progress";
|
||||
|
||||
export default class RagUploader extends Component {
|
||||
@service appEvents;
|
||||
|
||||
@tracked term = null;
|
||||
@tracked filteredUploads = null;
|
||||
@tracked ragIndexingStatuses = null;
|
||||
@@ -136,7 +137,10 @@ export default class RagUploader extends Component {
|
||||
{{#if this.ragUploads}}
|
||||
<div class="rag-uploader__search-input-container">
|
||||
<div class="rag-uploader__search-input">
|
||||
{{icon "search" class="rag-uploader__search-input__search-icon"}}
|
||||
{{icon
|
||||
"magnifying-glass"
|
||||
class="rag-uploader__search-input__search-icon"
|
||||
}}
|
||||
<Input
|
||||
class="rag-uploader__search-input__input"
|
||||
placeholder={{i18n "discourse_ai.rag.uploads.filter"}}
|
||||
|
||||
+14
-19
@@ -15,32 +15,19 @@ import { MIN_CHARACTER_COUNT } from "../../lib/ai-helper-suggestions";
|
||||
|
||||
export default class AiCategorySuggester extends Component {
|
||||
@service siteSettings;
|
||||
|
||||
@tracked loading = false;
|
||||
@tracked suggestions = null;
|
||||
@tracked untriggers = [];
|
||||
@tracked triggerIcon = "discourse-sparkles";
|
||||
@tracked content = null;
|
||||
@tracked topicContent = null;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
if (!this.topicContent && this.args.composer?.reply === undefined) {
|
||||
this.fetchTopicContent();
|
||||
}
|
||||
}
|
||||
|
||||
async fetchTopicContent() {
|
||||
await ajax(`/t/${this.args.buffered.content.id}.json`).then(
|
||||
({ post_stream }) => {
|
||||
this.topicContent = post_stream.posts[0].cooked;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get showSuggestionButton() {
|
||||
const composerFields = document.querySelector(".composer-fields");
|
||||
this.content = this.args.composer?.reply || this.topicContent;
|
||||
const showTrigger = this.content?.length > MIN_CHARACTER_COUNT;
|
||||
this.content = this.args.composer?.reply;
|
||||
const showTrigger =
|
||||
this.content?.length > MIN_CHARACTER_COUNT ||
|
||||
this.args.topicState === "edit";
|
||||
|
||||
if (composerFields) {
|
||||
if (showTrigger) {
|
||||
@@ -62,12 +49,20 @@ export default class AiCategorySuggester extends Component {
|
||||
this.loading = true;
|
||||
this.triggerIcon = "spinner";
|
||||
|
||||
const data = {};
|
||||
|
||||
if (this.content) {
|
||||
data.text = this.content;
|
||||
} else {
|
||||
data.topic_id = this.args.buffered.content.id;
|
||||
}
|
||||
|
||||
try {
|
||||
const { assistant } = await ajax(
|
||||
"/discourse-ai/ai-helper/suggest_category",
|
||||
{
|
||||
method: "POST",
|
||||
data: { text: this.content },
|
||||
data,
|
||||
}
|
||||
);
|
||||
this.suggestions = assistant;
|
||||
|
||||
@@ -16,32 +16,19 @@ import { MIN_CHARACTER_COUNT } from "../../lib/ai-helper-suggestions";
|
||||
export default class AiTagSuggester extends Component {
|
||||
@service siteSettings;
|
||||
@service toasts;
|
||||
|
||||
@tracked loading = false;
|
||||
@tracked suggestions = null;
|
||||
@tracked untriggers = [];
|
||||
@tracked triggerIcon = "discourse-sparkles";
|
||||
@tracked content = null;
|
||||
@tracked topicContent = null;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
if (!this.topicContent && this.args.composer?.reply === undefined) {
|
||||
this.fetchTopicContent();
|
||||
}
|
||||
}
|
||||
|
||||
async fetchTopicContent() {
|
||||
await ajax(`/t/${this.args.buffered.content.id}.json`).then(
|
||||
({ post_stream }) => {
|
||||
this.topicContent = post_stream.posts[0].cooked;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get showSuggestionButton() {
|
||||
const composerFields = document.querySelector(".composer-fields");
|
||||
this.content = this.args.composer?.reply || this.topicContent;
|
||||
const showTrigger = this.content?.length > MIN_CHARACTER_COUNT;
|
||||
this.content = this.args.composer?.reply;
|
||||
const showTrigger =
|
||||
this.content?.length > MIN_CHARACTER_COUNT ||
|
||||
this.args.topicState === "edit";
|
||||
|
||||
if (composerFields) {
|
||||
if (showTrigger) {
|
||||
@@ -74,15 +61,25 @@ export default class AiTagSuggester extends Component {
|
||||
this.loading = true;
|
||||
this.triggerIcon = "spinner";
|
||||
|
||||
const data = {};
|
||||
|
||||
if (this.content) {
|
||||
data.text = this.content;
|
||||
} else {
|
||||
data.topic_id = this.args.buffered.content.id;
|
||||
}
|
||||
|
||||
try {
|
||||
const { assistant } = await ajax("/discourse-ai/ai-helper/suggest_tags", {
|
||||
method: "POST",
|
||||
data: { text: this.content },
|
||||
data,
|
||||
});
|
||||
this.suggestions = assistant;
|
||||
|
||||
const model = this.args.composer
|
||||
? this.args.composer
|
||||
: this.args.buffered;
|
||||
|
||||
if (this.#tagSelectorHasValues()) {
|
||||
this.suggestions = this.suggestions.filter(
|
||||
(s) => !model.get("tags").includes(s.name)
|
||||
|
||||
@@ -17,30 +17,15 @@ export default class AiTitleSuggester extends Component {
|
||||
@tracked untriggers = [];
|
||||
@tracked triggerIcon = "discourse-sparkles";
|
||||
@tracked content = null;
|
||||
@tracked topicContent = null;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
if (!this.topicContent && this.args.composer?.reply === undefined) {
|
||||
this.fetchTopicContent();
|
||||
}
|
||||
}
|
||||
|
||||
async fetchTopicContent() {
|
||||
await ajax(`/t/${this.args.buffered.content.id}.json`).then(
|
||||
({ post_stream }) => {
|
||||
this.topicContent = post_stream.posts[0].cooked;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get showSuggestionButton() {
|
||||
const composerFields = document.querySelector(".composer-fields");
|
||||
const editTopicTitleField = document.querySelector(".edit-topic-title");
|
||||
|
||||
this.content = this.args.composer?.reply || this.topicContent;
|
||||
const showTrigger = this.content?.length > MIN_CHARACTER_COUNT;
|
||||
this.content = this.args.composer?.reply;
|
||||
const showTrigger =
|
||||
this.content?.length > MIN_CHARACTER_COUNT ||
|
||||
this.args.topicState === "edit";
|
||||
|
||||
if (composerFields) {
|
||||
if (showTrigger) {
|
||||
@@ -69,13 +54,20 @@ export default class AiTitleSuggester extends Component {
|
||||
|
||||
this.loading = true;
|
||||
this.triggerIcon = "spinner";
|
||||
const data = {};
|
||||
|
||||
if (this.content) {
|
||||
data.text = this.content;
|
||||
} else {
|
||||
data.topic_id = this.args.buffered.content.id;
|
||||
}
|
||||
|
||||
try {
|
||||
const { suggestions } = await ajax(
|
||||
"/discourse-ai/ai-helper/suggest_title",
|
||||
{
|
||||
method: "POST",
|
||||
data: { text: this.content },
|
||||
data,
|
||||
}
|
||||
);
|
||||
this.suggestions = suggestions;
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ export default class AiCategorySuggestion extends Component {
|
||||
}
|
||||
|
||||
<template>
|
||||
<AiCategorySuggester @composer={{@outletArgs.composer}} />
|
||||
<AiCategorySuggester @composer={{@outletArgs.composer}} @topicState="new" />
|
||||
</template>
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ export default class AiTagSuggestion extends Component {
|
||||
}
|
||||
|
||||
<template>
|
||||
<AiTagSuggester @composer={{@outletArgs.composer}} />
|
||||
<AiTagSuggester @composer={{@outletArgs.composer}} @topicState="new" />
|
||||
</template>
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ export default class AiTitleSuggestion extends Component {
|
||||
}
|
||||
|
||||
<template>
|
||||
<AiTitleSuggester @composer={{@outletArgs.composer}} />
|
||||
<AiTitleSuggester @composer={{@outletArgs.composer}} @topicState="new" />
|
||||
</template>
|
||||
}
|
||||
|
||||
+1
-3
@@ -9,7 +9,5 @@ export default class AiTopicGist extends Component {
|
||||
return !this.topicThumbnails?.enabledForRoute;
|
||||
}
|
||||
|
||||
<template>
|
||||
<AiGistToggle />
|
||||
</template>
|
||||
<template><AiGistToggle /></template>
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ export default class BotSelector extends Component {
|
||||
|
||||
@service currentUser;
|
||||
@service siteSettings;
|
||||
|
||||
@tracked llm;
|
||||
@tracked allowLLMSelector = true;
|
||||
|
||||
|
||||
+4
-1
@@ -13,6 +13,9 @@ export default class AiCategorySuggestion extends Component {
|
||||
}
|
||||
|
||||
<template>
|
||||
<AiCategorySuggester @buffered={{@outletArgs.buffered}} />
|
||||
<AiCategorySuggester
|
||||
@buffered={{@outletArgs.buffered}}
|
||||
@topicState="edit"
|
||||
/>
|
||||
</template>
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user