From 2619286efeb23ddfc91f558b2204b3a4cb8a352f Mon Sep 17 00:00:00 2001 From: Aphin1ty Date: Mon, 16 Mar 2026 00:34:55 +0800 Subject: [PATCH 1/6] update library.js - Added automatic (configurable) disable for cached models - Added configurable model block list - Added configuration option for turn to start Inner Self on --- src/library.js | 144 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 136 insertions(+), 8 deletions(-) diff --git a/src/library.js b/src/library.js index fc7ca5b..3b08c27 100644 --- a/src/library.js +++ b/src/library.js @@ -67,6 +67,18 @@ globalThis.MainSettings = (class MainSettings { IS_CONFIG_CARD_PINNED_BY_DEFAULT: false // (true or false) , + // Should Inner Self remain active on cached model turns? + ALLOW_CACHED_MODELS: false + // (true or false) + , + // Minimum turn count required before Inner Self can activate. + MINIMUM_HISTORY_LENGTH_BEFORE_ENABLE: 1 + // (0 to 9999) + , + // Which story models should block Inner Self? Leave empty to block none. Ex: Wayfarer Large,Wayfarer Small 2 + BLOCKED_STORY_MODELS: "" + // (write a comma separated list of exact model names inside the "" or leave empty) + , // Is AC already enabled when the adventure begins? IS_AC_ENABLED_BY_DEFAULT: false // (true or false) @@ -278,6 +290,18 @@ function InnerSelf(hook) { IS_CONFIG_CARD_PINNED_BY_DEFAULT: false // (true or false) , + // Should Inner Self remain active on cached model turns? + ALLOW_CACHED_MODELS: false + // (true or false) + , + // Minimum turn count required before Inner Self can activate. + MINIMUM_HISTORY_LENGTH_BEFORE_ENABLE: 1 + // (0 to 9999) + , + // Which story models should block Inner Self? Leave empty to block none. + BLOCKED_STORY_MODELS: "" + // (write a comma separated list of exact model names inside the "" or leave empty) + , // Is AC already enabled when the adventure begins? IS_AC_ENABLED_BY_DEFAULT: false // (true or false) @@ -339,6 +363,8 @@ function InnerSelf(hook) { label: 0, // Hash of recent history to detect retry or erase + continue turns hash: "", + // Most recent actionCount value observed from info + lastKnownActionCount: 0, // Total number of brain operations performed across all agents ops: 0, // Auto-Cards integration state @@ -381,6 +407,65 @@ function InnerSelf(hook) { } return n.toString(16); }; + const normalizeModelValue = (value = "") => String(value).trim().replace(/\s+/g, " ").toLowerCase(); + const splitModelList = (value = "") => [...new Set(String(value) + .split(/[,\n]/) + .map(model => normalizeModelValue(model)) + .filter(model => (model !== "")) + )]; + const readInfoActionCount = () => ( + Number.isInteger(info?.actionCount) + ? Math.abs(info.actionCount) + : null + ); + const rememberInfoActionCount = () => { + const current = readInfoActionCount(); + if (current !== null) { + IS.lastKnownActionCount = current; + return current; + } else if (Number.isInteger(IS.lastKnownActionCount)) { + return IS.lastKnownActionCount; + } + return 0; + }; + rememberInfoActionCount(); + const getStoryModelName = () => { + for (const candidate of [ + info?.storyModel?.name, + info?.storyModel?.id, + info?.storyModel?.slug, + info?.storyModel, + info?.model?.name, + info?.model?.id, + info?.model?.slug, + info?.modelName, + info?.model + ]) { + const model = normalizeModelValue(candidate); + if (model !== "") { + return model; + } + } + return ""; + }; + const isCacheEfficientTurn = () => (info?.useCacheEfficient === true); + const getInnerSelfActivationCount = () => rememberInfoActionCount(); + const isInnerSelfHistoryAllowed = (config = {}) => ( + getInnerSelfActivationCount() >= ( + Number.isInteger(config.minimumHistoryLength) + ? config.minimumHistoryLength + : 0 + ) + ); + const isInnerSelfModelAllowed = (config = {}) => { + if (!config.allowCachedModels && isCacheEfficientTurn()) { + return false; + } else if (Array.isArray(config.blockedModels) && (config.blockedModels.length !== 0)) { + const currentModel = getStoryModelName(); + return (currentModel === "") || !config.blockedModels.includes(currentModel); + } + return true; + }; /** * Safely parses a JSON string into an object * Optionally attempts to repair malformed JSON by extracting quoted content @@ -427,7 +512,10 @@ function InnerSelf(hook) { * @property {boolean} json - Is raw JSON syntax used to serialize NPC brains in their card notes? * @property {boolean} debug - Is debug mode enabled for inline task output visibility? * @property {boolean} pin - Is the config card pinned near the top of the list? + * @property {boolean} allowCachedModels - Should cached model turns run Inner Self? + * @property {number} minimumHistoryLength - Minimum turn count before Inner Self activates * @property {boolean} auto - Is Auto-Cards enabled? + * @property {string[]} blockedModels - Story model names which disable Inner Self * @property {string[]} agents - All agent names, ordered from highest to lowest trigger priority */ /** @@ -466,7 +554,10 @@ function InnerSelf(hook) { json: false, debug: false, pin: false, + allowCachedModels: false, + minimumHistoryLength: 1, auto: false, + blockedModels: [], agents: [] }); /** @type {config} */ @@ -625,6 +716,13 @@ function InnerSelf(hook) { { message: "Pin this config card near the top:", ...factory( "pin", S.IS_CONFIG_CARD_PINNED_BY_DEFAULT ) }, + { message: "Allow cached models:", ...factory( + "allowCachedModels", S.ALLOW_CACHED_MODELS + ) }, + { message: "Minimum turn count before activation:", ...factory( + "minimumHistoryLength", S.MINIMUM_HISTORY_LENGTH_BEFORE_ENABLE, + { lower: 0, upper: 9999 } + ) }, { message: "Install Auto-Cards:", ...factory( "auto", S.IS_AC_ENABLED_BY_DEFAULT ) }, @@ -640,6 +738,24 @@ function InnerSelf(hook) { { message: `Inner Self ${version} is an open-source and general-purpose AI Dungeon mod by LewdLeah. You have my full permission to use it with any scenario!` }, + { + message: "Block Inner Self on these story models (leave empty to block none):", + builder: (cfg = {}) => ["", "", ...( + config.blockedModels ?? cfg.setter?.(S.BLOCKED_STORY_MODELS) + ), ""].join("\n"), + setter: (value = null, fallible = false) => { + if (typeof value === "string") { + config.blockedModels = splitModelList(value); + } else if (Array.isArray(value)) { + config.blockedModels = splitModelList(value.join("\n")); + } else if (fallible) { + return; + } else { + return (config.blockedModels = [...fallback.blockedModels]); + } + return config.blockedModels; + } + }, { // This is where players list their NPCs message: "Write the first name of every intelligent story character on separate lines below, listed from highest to lowest trigger priority:", @@ -1064,6 +1180,11 @@ function InnerSelf(hook) { IS.agent = ""; /** @type {config} */ const config = Config.get(); + const innerSelfEnabled = ( + config.allow + && isInnerSelfHistoryAllowed(config) + && isInnerSelfModelAllowed(config) + ); if (config.pin) { // Move config card to top of list if pinning is enabled const index = storyCards.indexOf(config.card); @@ -1098,7 +1219,7 @@ function InnerSelf(hook) { IS.AC.enabled = true; if (IS.AC.event || (stop === true)) { // If AC triggered an event or stop, we're done here - config.allow ? unzero() : ((IS.encoding = ""), (text ||= " ")); + innerSelfEnabled ? unzero() : ((IS.encoding = ""), (text ||= " ")); return; } } else if (IS.AC.enabled) { @@ -1130,12 +1251,6 @@ function InnerSelf(hook) { } } } - if (!config.allow) { - // Early exit if Inner Self is disabled - IS.encoding = ""; - text ||= " "; - return; - } /** * Removes visual indicators from all story cards * Called when no agent is triggered or Inner Self is disabled @@ -1147,6 +1262,14 @@ function InnerSelf(hook) { } return; }; + if (!innerSelfEnabled) { + // Early exit if Inner Self is disabled + deindicateAll(); + IS.agent = ""; + IS.encoding = ""; + text ||= " "; + return; + } if (config.agents.length === 0) { // No agents are configured deindicateAll(); @@ -2125,6 +2248,11 @@ Follow the format **perfectly**. // Process model output and implement brain operations /** @type {config} */ const config = Config.get(); + const innerSelfEnabled = ( + config.allow + && isInnerSelfHistoryAllowed(config) + && isInnerSelfModelAllowed(config) + ); /** * Ensures clean visual separation between actions * Only applies after "continue" or "story" actions @@ -2258,7 +2386,7 @@ I hope you will have lots of fun! prespace(); IS.agent = ""; return; - } else if (!config.allow) { + } else if (!innerSelfEnabled) { // Early exit if Inner Self is disabled text ||= "\u200B"; IS.agent = ""; From 80b1cc3c798f41943a55e6a19e4bb4d96b2b0014 Mon Sep 17 00:00:00 2001 From: Aphin1ty Date: Mon, 16 Mar 2026 17:41:14 +0800 Subject: [PATCH 2/6] Updated library.js - Adjusted default cache setting to match existing mod behavior. - Added one time warning toggle for disabled models - Added customisable messages for sending to the player. --- src/library.js | 178 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 164 insertions(+), 14 deletions(-) diff --git a/src/library.js b/src/library.js index 3b08c27..03f3fb7 100644 --- a/src/library.js +++ b/src/library.js @@ -68,13 +68,25 @@ globalThis.MainSettings = (class MainSettings { // (true or false) , // Should Inner Self remain active on cached model turns? - ALLOW_CACHED_MODELS: false + ALLOW_CACHED_MODELS: true // (true or false) , // Minimum turn count required before Inner Self can activate. - MINIMUM_HISTORY_LENGTH_BEFORE_ENABLE: 1 + MINIMUM_HISTORY_LENGTH_BEFORE_ENABLE: 0 // (0 to 9999) , + // Should one-time warning messages be shown when model rules disable Inner Self? + ENABLE_MODEL_WARNING_MESSAGES: false + // (true or false) + , + // Message shown once per model when Inner Self is disabled on a cached turn. + NOTIFICATION_CACHED_MODEL: "Inner Self is disabled on cached turns for %{model}." + // (any text inside the ""; use %{model} to include the model name) + , + // Message shown once per model when Inner Self is disabled by the blocked models list. + NOTIFICATION_BLOCKED_STORY_MODEL: "Inner Self is disabled on blocked story model %{model}." + // (any text inside the ""; use %{model} to include the model name) + , // Which story models should block Inner Self? Leave empty to block none. Ex: Wayfarer Large,Wayfarer Small 2 BLOCKED_STORY_MODELS: "" // (write a comma separated list of exact model names inside the "" or leave empty) @@ -291,13 +303,25 @@ function InnerSelf(hook) { // (true or false) , // Should Inner Self remain active on cached model turns? - ALLOW_CACHED_MODELS: false + ALLOW_CACHED_MODELS: true // (true or false) , // Minimum turn count required before Inner Self can activate. MINIMUM_HISTORY_LENGTH_BEFORE_ENABLE: 1 // (0 to 9999) , + // Should one-time warning messages be shown when model rules disable Inner Self? + ENABLE_MODEL_WARNING_MESSAGES: true + // (true or false) + , + // Message shown once per model when Inner Self is disabled on a cached turn. + NOTIFICATION_CACHED_MODEL: "Inner Self is disabled on cached turns for %{model}." + // (any text inside the ""; use %{model} to include the model name) + , + // Message shown once per model when Inner Self is disabled by the blocked models list. + NOTIFICATION_BLOCKED_STORY_MODEL: "Inner Self is disabled on blocked story model %{model}." + // (any text inside the ""; use %{model} to include the model name) + , // Which story models should block Inner Self? Leave empty to block none. BLOCKED_STORY_MODELS: "" // (write a comma separated list of exact model names inside the "" or leave empty) @@ -365,6 +389,14 @@ function InnerSelf(hook) { hash: "", // Most recent actionCount value observed from info lastKnownActionCount: 0, + // Models from the blocked list which have actually been encountered + detectedBlockedModels: [], + // Blocked models already shown to the user + warnedBlockedModels: [], + // Cached models already shown to the user + warnedCachedModels: [], + // One-time output notice queued for the current turn + pendingUserNotice: "", // Total number of brain operations performed across all agents ops: 0, // Auto-Cards integration state @@ -407,12 +439,25 @@ function InnerSelf(hook) { } return n.toString(16); }; + const normalizeWhitespace = (value = "") => ( + ((typeof value === "string") || (typeof value === "number")) + ? String(value).replace(/\s+/g, " ").trim() + : "" + ); const normalizeModelValue = (value = "") => String(value).trim().replace(/\s+/g, " ").toLowerCase(); const splitModelList = (value = "") => [...new Set(String(value) .split(/[,\n]/) .map(model => normalizeModelValue(model)) .filter(model => (model !== "")) )]; + const pushUnique = (list = [], value = "") => { + value = normalizeWhitespace(value); + if ((value === "") || !Array.isArray(list) || list.includes(value)) { + return false; + } + list.push(value); + return true; + }; const readInfoActionCount = () => ( Number.isInteger(info?.actionCount) ? Math.abs(info.actionCount) @@ -429,7 +474,7 @@ function InnerSelf(hook) { return 0; }; rememberInfoActionCount(); - const getStoryModelName = () => { + const getStoryModelDisplayName = () => { for (const candidate of [ info?.storyModel?.name, info?.storyModel?.id, @@ -441,13 +486,14 @@ function InnerSelf(hook) { info?.modelName, info?.model ]) { - const model = normalizeModelValue(candidate); + const model = normalizeWhitespace(candidate); if (model !== "") { return model; } } - return ""; + return "unknown"; }; + const getStoryModelName = () => normalizeModelValue(getStoryModelDisplayName()); const isCacheEfficientTurn = () => (info?.useCacheEfficient === true); const getInnerSelfActivationCount = () => rememberInfoActionCount(); const isInnerSelfHistoryAllowed = (config = {}) => ( @@ -457,14 +503,63 @@ function InnerSelf(hook) { : 0 ) ); - const isInnerSelfModelAllowed = (config = {}) => { + const getInnerSelfModelStatus = (config = {}) => { + const modelName = getStoryModelName(); + const modelLabel = getStoryModelDisplayName(); if (!config.allowCachedModels && isCacheEfficientTurn()) { - return false; + return { allowed: false, reason: "cached", modelName, modelLabel }; } else if (Array.isArray(config.blockedModels) && (config.blockedModels.length !== 0)) { - const currentModel = getStoryModelName(); - return (currentModel === "") || !config.blockedModels.includes(currentModel); + if ((modelName !== "") && (modelName !== "unknown") && config.blockedModels.includes(modelName)) { + return { allowed: false, reason: "blocked", modelName, modelLabel }; + } } - return true; + return { allowed: true, reason: "", modelName, modelLabel }; + }; + const formatModelWarning = (template = "", modelLabel = "") => normalizeWhitespace( + String(template || "").replace(/%\{model\}/g, modelLabel || "unknown") + ); + const queueModelWarning = (modelStatus = {}, config = {}) => { + const modelKey = normalizeModelValue(modelStatus.modelName || ""); + const modelLabel = normalizeWhitespace(modelStatus.modelLabel || modelKey || "unknown"); + if (modelStatus.reason === "blocked") { + pushUnique(IS.detectedBlockedModels, modelKey || modelLabel); + } + if (!config.enableModelWarningMessages) { + return; + } + const warnedList = + (modelStatus.reason === "blocked") + ? IS.warnedBlockedModels + : (modelStatus.reason === "cached") + ? IS.warnedCachedModels + : null; + if (!warnedList || !pushUnique(warnedList, modelKey || modelLabel)) { + return; + } + IS.pendingUserNotice = formatModelWarning( + (modelStatus.reason === "blocked") + ? config.notificationBlockedStoryModel + : config.notificationCachedModel, + modelLabel + ); + }; + const consumePendingUserNotice = () => { + const pending = normalizeWhitespace(IS.pendingUserNotice || ""); + IS.pendingUserNotice = ""; + return pending; + }; + const buildUserNoticeBlock = (message = "") => { + message = normalizeWhitespace(message); + return (message === "") ? "" : `>>> Inner Self:\n${message}\n<<<`; + }; + const applyUserNoticeToOutput = (output = "") => { + const notice = buildUserNoticeBlock(consumePendingUserNotice()); + if (notice === "") { + return output; + } else if ((typeof output !== "string") || (output === "") || (output === "\u200B")) { + return notice; + } + return `${notice}\n\n${String(output).trimStart()}`; }; /** * Safely parses a JSON string into an object @@ -514,6 +609,9 @@ function InnerSelf(hook) { * @property {boolean} pin - Is the config card pinned near the top of the list? * @property {boolean} allowCachedModels - Should cached model turns run Inner Self? * @property {number} minimumHistoryLength - Minimum turn count before Inner Self activates + * @property {boolean} enableModelWarningMessages - Show one-time model warning messages in output + * @property {string} notificationCachedModel - Cached-model warning message template + * @property {string} notificationBlockedStoryModel - Blocked-model warning message template * @property {boolean} auto - Is Auto-Cards enabled? * @property {string[]} blockedModels - Story model names which disable Inner Self * @property {string[]} agents - All agent names, ordered from highest to lowest trigger priority @@ -554,8 +652,12 @@ function InnerSelf(hook) { json: false, debug: false, pin: false, - allowCachedModels: false, + allowCachedModels: true, minimumHistoryLength: 1, + enableModelWarningMessages: true, + notificationCachedModel: "Inner Self is disabled on cached turns for %{model}.", + notificationBlockedStoryModel: + "Inner Self is disabled on blocked story model %{model}.", auto: false, blockedModels: [], agents: [] @@ -723,6 +825,44 @@ function InnerSelf(hook) { "minimumHistoryLength", S.MINIMUM_HISTORY_LENGTH_BEFORE_ENABLE, { lower: 0, upper: 9999 } ) }, + { message: "Enable model warning messages:", ...factory( + "enableModelWarningMessages", S.ENABLE_MODEL_WARNING_MESSAGES + ) }, + { + message: "Cached model warning message:", + builder: (cfg = {}) => ` "${( + config.notificationCachedModel + ?? cfg.setter?.(S.NOTIFICATION_CACHED_MODEL) + )}"`, + setter: (value = null, fallible = false) => { + if (typeof value === "string") { + config.notificationCachedModel = value.replaceAll("\"", "").trim(); + } else if (fallible) { + return; + } else { + config.notificationCachedModel = fallback.notificationCachedModel; + } + return config.notificationCachedModel; + } + }, + { + message: "Blocked story model warning message:", + builder: (cfg = {}) => ` "${( + config.notificationBlockedStoryModel + ?? cfg.setter?.(S.NOTIFICATION_BLOCKED_STORY_MODEL) + )}"`, + setter: (value = null, fallible = false) => { + if (typeof value === "string") { + config.notificationBlockedStoryModel = value.replaceAll("\"", "").trim(); + } else if (fallible) { + return; + } else { + config.notificationBlockedStoryModel = + fallback.notificationBlockedStoryModel; + } + return config.notificationBlockedStoryModel; + } + }, { message: "Install Auto-Cards:", ...factory( "auto", S.IS_AC_ENABLED_BY_DEFAULT ) }, @@ -1180,10 +1320,14 @@ function InnerSelf(hook) { IS.agent = ""; /** @type {config} */ const config = Config.get(); + const modelStatus = getInnerSelfModelStatus(config); + if (!modelStatus.allowed) { + queueModelWarning(modelStatus, config); + } const innerSelfEnabled = ( config.allow && isInnerSelfHistoryAllowed(config) - && isInnerSelfModelAllowed(config) + && modelStatus.allowed ); if (config.pin) { // Move config card to top of list if pinning is enabled @@ -2248,10 +2392,14 @@ Follow the format **perfectly**. // Process model output and implement brain operations /** @type {config} */ const config = Config.get(); + const modelStatus = getInnerSelfModelStatus(config); + if (!modelStatus.allowed) { + queueModelWarning(modelStatus, config); + } const innerSelfEnabled = ( config.allow && isInnerSelfHistoryAllowed(config) - && isInnerSelfModelAllowed(config) + && modelStatus.allowed ); /** * Ensures clean visual separation between actions @@ -2389,6 +2537,7 @@ I hope you will have lots of fun! } else if (!innerSelfEnabled) { // Early exit if Inner Self is disabled text ||= "\u200B"; + text = applyUserNoticeToOutput(text); IS.agent = ""; return; } @@ -2882,6 +3031,7 @@ I hope you will have lots of fun! agent.card.entry = `${agent.card.entry}\n\n// operation ${IS.ops}\n${operation()}`.trimStart(); } text ||= "\u200B"; + text = applyUserNoticeToOutput(text); // Keep the operation log from growing unbounded // Limit to approximately 2000 chars to satisfy AID's soft entry limit agent.card.entry = agent.card.entry.split(/\n\n/).slice(-2000).reduceRight((out, op) => ( From e29132bbbc45f4087980074100eaf19a09cae8cb Mon Sep 17 00:00:00 2001 From: Aphin1ty Date: Sat, 11 Apr 2026 23:36:28 +0800 Subject: [PATCH 3/6] Update library.js Adding additional instructions to thought generation to prevent duplicated thoughts and tighten thought generation to information specific for the subject character. --- src/library.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/library.js b/src/library.js index 03f3fb7..028df79 100644 --- a/src/library.js +++ b/src/library.js @@ -1782,7 +1782,7 @@ You must output one short parenthetical task followed by the story continuation. ## STORY CONTINUATION (REQUIRED) - After the closing parenthesis, write **one space** and then continue the story - Written from ${ownership(config.player)} **first person present tense** PoV -- The story continues where it previously left off, with many lines or sentences of new prose +- The story continues EXACTLY where it previously left off, with many lines or sentences of new prose, without reiterating information or content ## EXACT SHAPE (delete unwanted_key) Story continues from ${ownership(config.player)} perspective, using first person present tense prose... @@ -1803,7 +1803,7 @@ You must output one short parenthetical task followed by the story continuation. ## STORY CONTINUATION (REQUIRED) - After the closing parenthesis, write **one space** and then continue the story - Written from ${ownership(config.player)} **second person present tense** ("you") PoV -- The story continues where it previously left off, with many lines or sentences of new prose +- The story continues EXACTLY where it previously left off, with many lines or sentences of new prose, without reiterating information or content ## EXACT SHAPE (delete unwanted_key) Story continues from ${ownership(config.player)} second person perspective... @@ -1824,7 +1824,7 @@ You must output one short parenthetical task followed by the story continuation. ## STORY CONTINUATION (REQUIRED) - After the closing parenthesis, write **one space** and then continue the story - Written from ${ownership(config.player)} **third person** PoV -- The story continues where it previously left off, with many lines or sentences of new prose +- The story continues EXACTLY where it previously left off, with many lines or sentences of new prose, without reiterating information or content ## EXACT SHAPE (delete unwanted_key) Story continues with third person prose... @@ -1863,7 +1863,7 @@ This creates or overwrites the thought associated with that key. ## STORY CONTINUATION (REQUIRED) - After the closing parenthesis, write **one space** and then continue the story - Written from ${ownership(config.player)} **first person present tense** PoV -- The story continues where it previously left off, with many lines or sentences of new prose +- The story continues EXACTLY where it previously left off, with many lines or sentences of new prose, without reiterating information or content ## EXACT SHAPE (example_key = \`${ownership(agent.name)} own short 1-sentence thought in first person.\`) Story continues from ${ownership(config.player)} perspective, using first person present tense prose... @@ -1899,7 +1899,7 @@ This creates or overwrites the thought associated with that key. ## STORY CONTINUATION (REQUIRED) - After the closing parenthesis, write **one space** and then continue the story - Written from ${ownership(config.player)} **second person present tense** ("you") PoV -- The story continues where it previously left off, with many lines or sentences of new prose +- The story continues EXACTLY where it previously left off, with many lines or sentences of new prose, without reiterating information or content ## EXACT SHAPE (example_key = \`${ownership(agent.name)} own short 1-sentence thought in first person.\`) Story continues from ${ownership(config.player)} second person perspective... @@ -1935,7 +1935,7 @@ This creates or overwrites the thought associated with that key. ## STORY CONTINUATION (REQUIRED) - After the closing parenthesis, write **one space** and then continue the story - Written from ${ownership(config.player)} **third person** PoV -- The story continues where it previously left off, with many lines or sentences of new prose +- The story continues EXACTLY where it previously left off, with many lines or sentences of new prose, without reiterating information or content ## EXACT SHAPE (example_key = \`${ownership(agent.name)} own short 1-sentence thought in first person.\`) Story continues with third person prose... @@ -1982,6 +1982,8 @@ Inside the parentheses: - Only refer to other characters directly by name in the thought sentence. - Avoid using pronouns or the word "you" which is too vague. Use specific names instead. - Never repeat, novelty and uniqueness are top priorities. + - Never repeat former identical thoughts of ${ownership(agent.name)}. + - Only use facts what ${ownership(agent.name)} logically has information on. - ${ownership(agent.name)} thought must be short. - Never hallucinate facts. - End the sentence with a period and backtick **inside** the parentheses; close with ".\`)". @@ -2091,6 +2093,8 @@ Inside the parentheses: - Only refer to other characters directly by name in the thought sentence. - Avoid using pronouns or the word "you" which is too vague. Use specific names instead. - Never repeat, novelty and uniqueness are top priorities. + - Never repeat former identical thoughts of ${ownership(agent.name)}. + - Only use facts what ${ownership(agent.name)} logically has information on. - ${ownership(agent.name)} thought must be short. - Never hallucinate facts. - End the sentence with a period and backtick **inside** the parentheses; close with ".\`)". @@ -2200,6 +2204,8 @@ Inside the parentheses: - Only refer to other characters directly by name in the thought sentence. - Avoid using pronouns or the word "you" which is too vague. Use specific names instead. - Never repeat, novelty and uniqueness are top priorities. + - Never repeat former identical thoughts of ${ownership(agent.name)}. + - Only use facts what ${ownership(agent.name)} logically has information on. - ${ownership(agent.name)} thought must be short. - Never hallucinate facts. - End the sentence with a period and backtick **inside** the parentheses; close with ".\`)". From 571de739d1e91eca129d68792499599be3fe80a3 Mon Sep 17 00:00:00 2001 From: Aphin1ty Date: Thu, 16 Apr 2026 14:23:00 +0800 Subject: [PATCH 4/6] update library.js I've set the default disable for cache models to true again, I've also set the minimum start length for IS to turn 2 by default. Fixed a few missing instruction improvements. --- src/library.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/library.js b/src/library.js index 028df79..2c11de9 100644 --- a/src/library.js +++ b/src/library.js @@ -68,11 +68,11 @@ globalThis.MainSettings = (class MainSettings { // (true or false) , // Should Inner Self remain active on cached model turns? - ALLOW_CACHED_MODELS: true + ALLOW_CACHED_MODELS: false // (true or false) , // Minimum turn count required before Inner Self can activate. - MINIMUM_HISTORY_LENGTH_BEFORE_ENABLE: 0 + MINIMUM_HISTORY_LENGTH_BEFORE_ENABLE: 2 // (0 to 9999) , // Should one-time warning messages be shown when model rules disable Inner Self? @@ -1854,7 +1854,9 @@ Inside the parentheses: - Written from ${ownership(agent.name)} **first person** PoV${refocus(false)} - Avoid using pronouns or the word "you", instead ${agent.name} refers to other characters directly by name - Never repeat, novelty and uniqueness are top priorities + - Never repeat former identical thoughts of ${ownership(agent.name)} - ${ownership(agent.name)} thought must be one single sentence only + - Only use facts what ${ownership(agent.name)} logically has information on - Never hallucinate facts - End the sentence with a period and backtick inside the parentheses; close with ".\`)" @@ -1890,7 +1892,9 @@ Inside the parentheses: - Written from ${ownership(agent.name)} **first person** PoV${refocus(false)} - Avoid using pronouns or the word "you", instead ${agent.name} refers to other characters directly by name - Never repeat, novelty and uniqueness are top priorities + - Never repeat former identical thoughts of ${ownership(agent.name)} - ${ownership(agent.name)} thought must be one single sentence only + - Only use facts what ${ownership(agent.name)} logically has information on - Never hallucinate facts - End the sentence with a period and backtick inside the parentheses; close with ".\`)" @@ -1926,7 +1930,9 @@ Inside the parentheses: - Written from ${ownership(agent.name)} **first person** PoV${refocus(false)} - Avoid using pronouns or the word "you", instead ${agent.name} refers to other characters directly by name - Never repeat, novelty and uniqueness are top priorities + - Never repeat former identical thoughts of ${ownership(agent.name)} - ${ownership(agent.name)} thought must be one single sentence only + - Only use facts what ${ownership(agent.name)} logically has information on - Never hallucinate facts - End the sentence with a period and backtick inside the parentheses; close with ".\`)" @@ -1983,8 +1989,8 @@ Inside the parentheses: - Avoid using pronouns or the word "you" which is too vague. Use specific names instead. - Never repeat, novelty and uniqueness are top priorities. - Never repeat former identical thoughts of ${ownership(agent.name)}. - - Only use facts what ${ownership(agent.name)} logically has information on. - ${ownership(agent.name)} thought must be short. + - Only use facts what ${ownership(agent.name)} logically has information on. - Never hallucinate facts. - End the sentence with a period and backtick **inside** the parentheses; close with ".\`)". @@ -2024,7 +2030,7 @@ Rules: 4. Do **NOT** write extra parentheses. 5. Do **NOT** use more than one operation per turn. 6. Do **NOT** invent new structures or mix formats. -7. The story continues where it previously left off, with many sentences of brand new prose. +7. The story continues EXACTLY where it previously left off, with many sentences of brand new prose, without reiterating information or content. --- @@ -2034,7 +2040,7 @@ Rules: - **If ${agent.name} reuses an already existing key, the new thought REPLACES / OVERRIDES the older thought stored under that key.** - This means: - Reusing an old key: **Overwrite an old thought with a new thought.** Useful for extending or maintaining existing information stored in ${ownership(agent.name)} brain. - - Using a new key: **Create a new thought.** Useful for storing ${ownership(agent.name)} memories, self-modifying ${ownership(agent.name)} own personality, tracking ${ownership(agent.name)} goals, or making plans for ${agent.name} to follow. + - Using a new key: **Create a new thought.** Useful for storing ${ownership(agent.name)} memories, self-modifying ${ownership(agent.name)} own personality, tracking ${ownership(agent.name)} goals with, demonstration slow-burn gain or loss of ${ownership(agent.name)}'s relationship with ${agent.name} or making plans for ${agent.name} to follow. - **Renaming a key moves the thought to a new name.** Useful for reorganizing ${ownership(agent.name)} brain. - **Deleting a key removes the thought permanently.** Helps ${agent.name} forget outdated, superfluous, or irrelevant information. - Choose keys carefully so ${agent.name} can easily recall, update, overwrite, rename, or delete thoughts as required for self-improvement. @@ -2135,7 +2141,7 @@ Rules: 4. Do **NOT** write extra parentheses. 5. Do **NOT** use more than one operation per turn. 6. Do **NOT** invent new structures or mix formats. -7. The story continues where it previously left off, with many sentences of brand new prose. +7. The story continues EXACTLY where it previously left off, with many sentences of brand new prose, without reiterating information or content. --- @@ -2145,7 +2151,7 @@ Rules: - **If ${agent.name} reuses an already existing key, the new thought REPLACES / OVERRIDES the older thought stored under that key.** - This means: - Reusing an old key: **Overwrite an old thought with a new thought.** Useful for extending or maintaining existing information stored in ${ownership(agent.name)} brain. - - Using a new key: **Create a new thought.** Useful for storing ${ownership(agent.name)} memories, self-modifying ${ownership(agent.name)} own personality, tracking ${ownership(agent.name)} goals, or making plans for ${agent.name} to follow. + - Using a new key: **Create a new thought.** Useful for storing ${ownership(agent.name)} memories, self-modifying ${ownership(agent.name)} own personality, tracking ${ownership(agent.name)} goals with, demonstration slow-burn gain or loss of ${ownership(agent.name)}'s relationship with ${agent.name} or making plans for ${agent.name} to follow. - **Renaming a key moves the thought to a new name.** Useful for reorganizing ${ownership(agent.name)} brain. - **Deleting a key removes the thought permanently.** Helps ${agent.name} forget outdated, superfluous, or irrelevant information. - Choose keys carefully so ${agent.name} can easily recall, update, overwrite, rename, or delete thoughts as required for self-improvement. @@ -2246,7 +2252,7 @@ Rules: 4. Do **NOT** write extra parentheses. 5. Do **NOT** use more than one operation per turn. 6. Do **NOT** invent new structures or mix formats. -7. The story continues where it previously left off, with many sentences of brand new prose. +7. The story continues EXACTLY where it previously left off, with many sentences of brand new prose, without reiterating information or content. --- @@ -2256,7 +2262,7 @@ Rules: - **If ${agent.name} reuses an already existing key, the new thought REPLACES / OVERRIDES the older thought stored under that key.** - This means: - Reusing an old key: **Overwrite an old thought with a new thought.** Useful for extending or maintaining existing information stored in ${ownership(agent.name)} brain. - - Using a new key: **Create a new thought.** Useful for storing ${ownership(agent.name)} memories, self-modifying ${ownership(agent.name)} own personality, tracking ${ownership(agent.name)} goals, or making plans for ${agent.name} to follow. + - Using a new key: **Create a new thought.** Useful for storing ${ownership(agent.name)} memories, self-modifying ${ownership(agent.name)} own personality, tracking ${ownership(agent.name)} goals with, demonstration slow-burn gain or loss of ${ownership(agent.name)}'s relationship with ${agent.name} or making plans for ${agent.name} to follow. - **Renaming a key moves the thought to a new name.** Useful for reorganizing ${ownership(agent.name)} brain. - **Deleting a key removes the thought permanently.** Helps ${agent.name} forget outdated, superfluous, or irrelevant information. - Choose keys carefully so ${agent.name} can easily recall, update, overwrite, rename, or delete thoughts as required for self-improvement. From c5080f605f84746353eb0097569e2e2d1819a453 Mon Sep 17 00:00:00 2001 From: Aphin1ty Date: Thu, 16 Apr 2026 16:47:21 +0800 Subject: [PATCH 5/6] update README.md added change notes and updated contributions --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index bc6a87d..9da5d18 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,20 @@ Your task is to transform the character concept into a JSON object
(click to expand) +### 1.0.3 +- Added config "Automatic disable for cache enabled models" +- Lets players disable Inner Self automatically if a cache-enabled model is detected +- Added config "Additional model block list" +- Lets players decided if they want to disable certain models automatically if they are detected +- Added config "Enable Model Warning Messages" +- Added config "Notification Cached Model" +- Added config "Notification blocked story model" +- These changes let players enable or disable and customise a one-time per model warning message if a cached-model or block story model is detected. +- Added config "Turn delay for Inner Self start" +- This change prevents Inner Self from impacting turn one output +- Adjusted AI prompts for Inner Self to reduce duplicate brain entries and reinforce story continuation +- Pull request by [Fly3-r](https://github.com/Fly3-r) + ### 1.0.2 - Added config "Brain card notes store brains as JSON" - When disabled, brain card notes use a simpler colon + newline delimited format instead of JSON @@ -229,6 +243,7 @@ Your task is to transform the character concept into a JSON object
(click to expand) +- v1.0.2 → v1.0.3 by [Fly3-r](https://github.com/Fly3-r) - v1.0.1 → v1.0.2 by [dirtymined13](https://github.com/dirtymined13) - v1.0.0 → v1.0.1 by [-Vinny-](https://play.aidungeon.com/profile/-Vinny-) From 1afc85b4454578bef96c1b471e0bf9ba08f1af51 Mon Sep 17 00:00:00 2001 From: Aphin1ty Date: Thu, 16 Apr 2026 16:58:54 +0800 Subject: [PATCH 6/6] update library.js version bump --- src/library.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library.js b/src/library.js index 2c11de9..4c10c35 100644 --- a/src/library.js +++ b/src/library.js @@ -11,7 +11,7 @@ globalThis.MainSettings = (class MainSettings { //————————————————————————————————————————————————————————————————————————————————— /** - * Inner Self v1.0.2 + * Inner Self v1.0.3 * Made by LewdLeah on January 3, 2026 * Gives story characters the ability to learn, plan, and adapt over time * Inner Self is free and open-source for anyone! ❤️