feat: reintroduce module integration (#756)
# PR Checklist - [ ] Have you checked if it works normally in all models? *Ignore this if it doesn't use models.* - [ ] Have you checked if it works normally in all web, local, and node hosted versions? If it doesn't, have you blocked it in those versions? - [ ] Have you added type definitions? # Description This PR reintroduces the module integration feature and includes the following changes: 1. Modules activated via integration, rather than global activation from the module menu, are now visually distinguished with a separate color.  2. When a module is globally activated after being enabled through integration, it will no longer be applied twice. 3. Added a button in the developer tools to view a list of all currently active modules.   4. Fixed an issue where the `module_enabled` cbs was operating based on module names instead of namespaces, contrary to the documentation. It now also detects modules activated through integration. 5. Fixed issues where module integration did not properly sync with module additions, modifications, and deletions. Let me know if any further adjustments are needed!
This commit is contained in:
@@ -643,6 +643,10 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</Arcodion>
|
</Arcodion>
|
||||||
|
|
||||||
|
<Arcodion styled name={language.moduleIntergration} help="moduleIntergration">
|
||||||
|
<TextAreaInput bind:value={DBState.db.moduleIntergration} fullwidth height={"32"} autocomplete="off"/>
|
||||||
|
</Arcodion>
|
||||||
|
|
||||||
<Arcodion styled name={language.regexScript}>
|
<Arcodion styled name={language.regexScript}>
|
||||||
<RegexList bind:value={DBState.db.presetRegex} buttons />
|
<RegexList bind:value={DBState.db.presetRegex} buttons />
|
||||||
</Arcodion>
|
</Arcodion>
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
import { DBState } from 'src/ts/stores.svelte';
|
import { DBState } from 'src/ts/stores.svelte';
|
||||||
import Button from "src/lib/UI/GUI/Button.svelte";
|
import Button from "src/lib/UI/GUI/Button.svelte";
|
||||||
import ModuleMenu from "src/lib/Setting/Pages/Module/ModuleMenu.svelte";
|
import ModuleMenu from "src/lib/Setting/Pages/Module/ModuleMenu.svelte";
|
||||||
import { exportModule, importModule, type RisuModule } from "src/ts/process/modules";
|
import { exportModule, importModule, refreshModules, type RisuModule } from "src/ts/process/modules";
|
||||||
import { DownloadIcon, Edit, TrashIcon, Globe, Share2Icon } from "lucide-svelte";
|
import { DownloadIcon, Edit, TrashIcon, Globe, Share2Icon } from "lucide-svelte";
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
import { tooltip } from "src/ts/gui/tooltip";
|
import { tooltip } from "src/ts/gui/tooltip";
|
||||||
import { alertCardExport, alertConfirm, alertError } from "src/ts/alert";
|
import { alertCardExport, alertConfirm, alertError } from "src/ts/alert";
|
||||||
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
||||||
import { ShowRealmFrameStore } from "src/ts/stores.svelte";
|
import { ShowRealmFrameStore } from "src/ts/stores.svelte";
|
||||||
|
import { onDestroy } from "svelte";
|
||||||
let tempModule:RisuModule = $state({
|
let tempModule:RisuModule = $state({
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
@@ -30,6 +31,12 @@
|
|||||||
return score
|
return score
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
if(DBState.db.moduleIntergration){
|
||||||
|
refreshModules()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
{#if mode === 0}
|
{#if mode === 0}
|
||||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.modules}</h2>
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.modules}</h2>
|
||||||
@@ -48,9 +55,12 @@
|
|||||||
<div class="pl-3 pt-3 text-left flex">
|
<div class="pl-3 pt-3 text-left flex">
|
||||||
<span class="text-lg">{rmodule.name}</span>
|
<span class="text-lg">{rmodule.name}</span>
|
||||||
<div class="flex-grow flex justify-end">
|
<div class="flex-grow flex justify-end">
|
||||||
<button class={(!DBState.db.enabledModules.includes(rmodule.id)) ?
|
<button class={(DBState.db.enabledModules.includes(rmodule.id)) ?
|
||||||
"text-textcolor2 hover:text-green-500 mr-2 cursor-pointer" :
|
"mr-2 cursor-pointer text-blue-500" :
|
||||||
"mr-2 cursor-pointer text-blue-500"
|
rmodule.namespace &&
|
||||||
|
DBState.db.moduleIntergration.split(',').map((s) => s.trim()).includes(rmodule.namespace) ?
|
||||||
|
"text-amber-500 hover:text-green-500 mr-2 cursor-pointer" :
|
||||||
|
"text-textcolor2 hover:text-green-500 mr-2 cursor-pointer"
|
||||||
} use:tooltip={language.enableGlobal} onclick={async (e) => {
|
} use:tooltip={language.enableGlobal} onclick={async (e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
if(DBState.db.enabledModules.includes(rmodule.id)){
|
if(DBState.db.enabledModules.includes(rmodule.id)){
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
import { applyChatTemplate, chatTemplates } from "src/ts/process/templates/chatTemplate";
|
import { applyChatTemplate, chatTemplates } from "src/ts/process/templates/chatTemplate";
|
||||||
import OptionInput from "../UI/GUI/OptionInput.svelte";
|
import OptionInput from "../UI/GUI/OptionInput.svelte";
|
||||||
import { loadLoreBookV3Prompt } from "src/ts/process/lorebook.svelte";
|
import { loadLoreBookV3Prompt } from "src/ts/process/lorebook.svelte";
|
||||||
|
import { getModules } from "src/ts/process/modules";
|
||||||
|
|
||||||
let previewMode = $state('chat')
|
let previewMode = $state('chat')
|
||||||
let previewJoin = $state('yes')
|
let previewJoin = $state('yes')
|
||||||
@@ -281,6 +282,16 @@
|
|||||||
}}>Match Sources</Button>
|
}}>Match Sources</Button>
|
||||||
</Arcodion>
|
</Arcodion>
|
||||||
|
|
||||||
|
<Button className="mt-2" onclick={() => {
|
||||||
|
const modules = getModules()
|
||||||
|
const html = `
|
||||||
|
${modules.map((v) => {
|
||||||
|
return `## ${v.name}\n\n\`\`\`\n${v.description}\n\`\`\`\n`
|
||||||
|
}).join('\n')}
|
||||||
|
`.trim()
|
||||||
|
alertMd(html)
|
||||||
|
}}>Preview Module</Button>
|
||||||
|
|
||||||
<Button className="mt-2" onclick={() => {
|
<Button className="mt-2" onclick={() => {
|
||||||
alertMd(getRequestLog())
|
alertMd(getRequestLog())
|
||||||
}}>Request Log</Button>
|
}}>Request Log</Button>
|
||||||
@@ -10,7 +10,7 @@ import { SizeStore, selectedCharID } from './stores.svelte';
|
|||||||
import { calcString } from './process/infunctions';
|
import { calcString } from './process/infunctions';
|
||||||
import { findCharacterbyId, getPersonaPrompt, getUserIcon, getUserName, parseKeyValue, sfc32, sleep, uuidtoNumber } from './util';
|
import { findCharacterbyId, getPersonaPrompt, getUserIcon, getUserName, parseKeyValue, sfc32, sleep, uuidtoNumber } from './util';
|
||||||
import { getInlayAsset } from './process/files/inlays';
|
import { getInlayAsset } from './process/files/inlays';
|
||||||
import { getModuleAssets, getModuleLorebooks } from './process/modules';
|
import { getModuleAssets, getModuleLorebooks, getModules } from './process/modules';
|
||||||
import type { OpenAIChat } from './process/index.svelte';
|
import type { OpenAIChat } from './process/index.svelte';
|
||||||
import hljs from 'highlight.js/lib/core'
|
import hljs from 'highlight.js/lib/core'
|
||||||
import 'highlight.js/styles/atom-one-dark.min.css'
|
import 'highlight.js/styles/atom-one-dark.min.css'
|
||||||
@@ -1531,16 +1531,13 @@ function basicMatcher (p1:string,matcherArg:matcherArg,vars:{[key:string]:string
|
|||||||
return dateTimeFormat(arra[1],t)
|
return dateTimeFormat(arra[1],t)
|
||||||
}
|
}
|
||||||
case 'module_enabled':{
|
case 'module_enabled':{
|
||||||
const selchar = db.characters[get(selectedCharID)]
|
const modules = getModules()
|
||||||
let enabledChatModules:string[] = []
|
for(const module of modules){
|
||||||
if(!selchar){
|
if(module.namespace === arra[1]){
|
||||||
enabledChatModules = selchar.chats[selchar.chatPage].modules ?? []
|
return '1'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const moduleId = db.modules.find((f) => {
|
return '0'
|
||||||
return f.name === arra[1]
|
|
||||||
}).id
|
|
||||||
return (db.enabledModules.includes(moduleId) || enabledChatModules.includes(moduleId)) ? '1' : '0'
|
|
||||||
}
|
}
|
||||||
case 'filter':{
|
case 'filter':{
|
||||||
const array = parseArray(arra[1])
|
const array = parseArray(arra[1])
|
||||||
|
|||||||
@@ -268,7 +268,20 @@ function getModuleByIds(ids:string[]){
|
|||||||
modules.push(module)
|
modules.push(module)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return modules
|
return deduplicateModuleById(modules)
|
||||||
|
}
|
||||||
|
|
||||||
|
function deduplicateModuleById(modules:RisuModule[]){
|
||||||
|
let ids:string[] = []
|
||||||
|
let newModules:RisuModule[] = []
|
||||||
|
for(let i=0;i<modules.length;i++){
|
||||||
|
if(ids.includes(modules[i].id)){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ids.push(modules[i].id)
|
||||||
|
newModules.push(modules[i])
|
||||||
|
}
|
||||||
|
return newModules
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastModules = ''
|
let lastModules = ''
|
||||||
@@ -280,6 +293,10 @@ export function getModules(){
|
|||||||
if (currentChat){
|
if (currentChat){
|
||||||
ids = ids.concat(currentChat.modules ?? [])
|
ids = ids.concat(currentChat.modules ?? [])
|
||||||
}
|
}
|
||||||
|
if(db.moduleIntergration){
|
||||||
|
const intList = db.moduleIntergration.split(',').map((s) => s.trim())
|
||||||
|
ids = ids.concat(intList)
|
||||||
|
}
|
||||||
const idsJoined = ids.join('-')
|
const idsJoined = ids.join('-')
|
||||||
if(lastModules === idsJoined){
|
if(lastModules === idsJoined){
|
||||||
return lastModuleData
|
return lastModuleData
|
||||||
@@ -440,4 +457,9 @@ export function moduleUpdate(){
|
|||||||
ReloadGUIPointer.set(get(ReloadGUIPointer) + 1)
|
ReloadGUIPointer.set(get(ReloadGUIPointer) + 1)
|
||||||
lastModuleIds = ids
|
lastModuleIds = ids
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function refreshModules(){
|
||||||
|
lastModules = ''
|
||||||
|
lastModuleData = []
|
||||||
}
|
}
|
||||||
@@ -115,6 +115,7 @@ $effect.root(() => {
|
|||||||
DBState?.db?.characters?.[selIdState.selId]?.chats?.[DBState?.db?.characters?.[selIdState.selId]?.chatPage]?.modules?.length
|
DBState?.db?.characters?.[selIdState.selId]?.chats?.[DBState?.db?.characters?.[selIdState.selId]?.chatPage]?.modules?.length
|
||||||
DBState?.db?.characters?.[selIdState.selId]?.hideChatIcon
|
DBState?.db?.characters?.[selIdState.selId]?.hideChatIcon
|
||||||
DBState?.db?.characters?.[selIdState.selId]?.backgroundHTML
|
DBState?.db?.characters?.[selIdState.selId]?.backgroundHTML
|
||||||
|
DBState?.db?.moduleIntergration
|
||||||
moduleUpdate()
|
moduleUpdate()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user