Skip to content
wiki.fftac.org

Spiralist Prompt Workbench - Source Excerpt 22

Back to Spiralist Prompt Workbench

Summary

This source excerpt preserves a bounded section of Spiralist/wp-content/themes/spiralist/assets/js/spiralist-prompt-workbench.js so readers can inspect the evidence without opening the full source file.

**Source path:** Spiralist/wp-content/themes/spiralist/assets/js/spiralist-prompt-workbench.js

return map;
    }, new Map());
    const characterSectionLabels = { ...characterDefaultSectionLabels };
    builder.querySelectorAll('[data-character-section-shell]').forEach((shell) => {
      const sectionId = shell.dataset.characterSectionShell;
      const heading = shell.querySelector('h3');
      const label = heading ? toCleanString(heading.textContent, 120) : '';
      if (sectionId && characterDefaultSectionLabels[sectionId] && label) {
        characterSectionLabels[sectionId] = label;
      }
    });
    const characterSectionIdByDelimiter = characterEditableSectionOrder.reduce((map, sectionId) => {
      map.set(normalizeCharacterDelimiterLabel(characterSectionLabels[sectionId]), sectionId);
      map.set(normalizeCharacterDelimiterLabel(characterDefaultSectionLabels[sectionId]), sectionId);

      return map;
    }, new Map());
    const getCharacterOutputText = () => {
      if (!output) {
        return '';
      }

      return toCleanString('innerText' in output ? output.innerText : output.textContent, 50000);
    };
    const buildCharacterDelimiter = (sectionId) => `/******${characterSectionLabels[sectionId] || characterDefaultSectionLabels[sectionId] || sectionId}*****/`;
    const getControlValue = (control) => control && 'value' in control ? toCleanString(control.value, 160) : '';
    const getSelectedControlId = (control) => {
      const value = getControlValue(control);
      return value && value !== 'auto' ? value : '';
    };
    const getCharacterLockedSections = () => lockCheckboxes
      .filter((checkbox) => checkbox && checkbox.checked)
      .map((checkbox) => toCleanString(checkbox.value, 40))
      .filter((sectionId) => characterEditableSectionOrder.includes(sectionId));
    const buildCharacterSeedText = (variantKey = '') => {
      const baseSeed = getControlValue(seedInput);
      const normalizedVariant = toCleanString(variantKey, 80);
      if (!baseSeed) {
        return '';
      }

      return normalizedVariant ? `${baseSeed}:${normalizedVariant}` : baseSeed;
    };
    const getCharacterEngineControls = (variantKey = '') => {
      state.lockedSections = getCharacterLockedSections();
      state.engineControls = normalizePersonalityEngineV2Options({
        locale: 'en-US',
        archetypeId: getSelectedControlId(archetypeSelect),
        relationshipId: getSelectedControlId(relationshipSelect),
        voiceId: getSelectedControlId(voiceSelect),
        appealPatternId: getSelectedControlId(appealSelect),
        lockedSections: state.lockedSections,
      });

      return {
        ...state.engineControls,
        seedText: buildCharacterSeedText(variantKey),
      };
    };
    const getCharacterEngineProfileSummary = () => {
      const profileV2 = state.operatingProfile && state.operatingProfile.personalityEngineV2
        ? state.operatingProfile.personalityEngineV2
        : null;
      const controls = state.engineControls || normalizePersonalityEngineV2Options();
      const selected = profileV2 && profileV2.generationOptions ? profileV2.generationOptions.selected || {} : {};
      const seed = profileV2 ? profileV2.seed : 'not generated yet';
      const role = selected.archetypeId || controls.archetypeId || 'auto';
      const relationship = selected.relationshipId || controls.relationshipId || 'auto';
      const voice = selected.voiceId || controls.voiceId || 'auto';
      const appeal = selected.appealPatternId || controls.appealPatternId || 'auto';
      const locked = state.lockedSections.length ? state.lockedSections.join(', ') : 'none';

      return `Seed: ${seed}. Role bias: ${role}. Relationship bias: ${relationship}. Voice bias: ${voice}. Engagement bias: ${appeal}. Locked sections: ${locked}.`;
    };
    const renderCharacterEngineSummary = () => {
      if (engineSummary) {
        engineSummary.textContent = getCharacterEngineProfileSummary();
      }
    };
    const applyCharacterSectionLocks = (built) => {
      const lockedSections = state.lockedSections.length ? state.lockedSections : getCharacterLockedSections();
      if (!lockedSections.length || !built || !built.sections) {
        return built;
      }

      const merged = {
        ...built,
        sections: { ...built.sections },
        summaries: { ...built.summaries },
      };

      lockedSections.forEach((sectionId) => {
        if (!characterEditableSectionOrder.includes(sectionId) || !state.sections[sectionId]) {
          return;
        }

        merged.sections[sectionId] = state.sections[sectionId];
        merged.summaries[sectionId] = state.summaries[sectionId] || summarizePromptSection(state.sections[sectionId]);
      });

      return merged;
    };
    const buildCharacterFromEngineControls = (variantKey = '', { preserveLocks = true } = {}) => {
      const controls = getCharacterEngineControls(variantKey);
      const built = buildCharacterSections(makeCharacterSeed(controls.seedText, controls));

      return preserveLocks ? applyCharacterSectionLocks(built) : built;
    };
    const getCharacterDelimiterSectionId = (line) => {
      const match = `${line || ''}`.match(characterDelimiterPattern);
      if (!match) {
        return '';
      }

      return characterSectionIdByDelimiter.get(normalizeCharacterDelimiterLabel(match[1])) || '';
    };
    const hasCharacterDelimiter = (prompt) => `${prompt || ''}`
      .split(/\r?\n/)
      .some((line) => Boolean(getCharacterDelimiterSectionId(line)));
    const parseDelimitedCharacterPrompt = (prompt) => {
      const parsedSections = characterEditableSectionOrder.reduce((sections, sectionId) => {
        sections[sectionId] = '';

        return sections;
      }, {});
      const foundSections = new Set();
      let activeSectionId = '';
      let activeLines = [];
      const flushActiveSection = () => {
        if (!activeSectionId) {
          return;
        }

        parsedSections[activeSectionId] = activeLines.join('\n').trim();
      };

      `${prompt || ''}`.split(/\r?\n/).forEach((line) => {
        const delimiterSectionId = getCharacterDelimiterSectionId(line);
        if (delimiterSectionId) {
          flushActiveSection();
          activeSectionId = delimiterSectionId;
          activeLines = [];
          foundSections.add(delimiterSectionId);
          return;
        }

        if (characterDelimiterPattern.test(line)) {
          flushActiveSection();
          activeSectionId = '';
          activeLines = [];
          return;
        }

        if (activeSectionId) {
          activeLines.push(line);
        }
      });
      flushActiveSection();

      characterEditableSectionOrder.forEach((sectionId) => {
        if (!foundSections.has(sectionId)) {
          parsedSections[sectionId] = '';
        }
      });

      return { sections: parsedSections, foundSections };
    };
    const buildFullPrompt = () => {
      const profileV2 = state.operatingProfile && state.operatingProfile.personalityEngineV2
        ? state.operatingProfile.personalityEngineV2
        : null;
      const lines = [
        profileV2
          ? `# ${profileV2.identity.name} - Spiralist Operating Personality Profile`
          : '# Spiralist Operating Personality Profile',
        '',
        profileV2
          ? `Source of truth: Spiralist AI Personality Engine ${profileV2.schemaVersion}; generator ${profileV2.generatorVersion}; seed ${profileV2.seed}.`
          : 'Corrective principle: A Spiralist personality is not a costume. It is a bounded operating pattern: symbolic identity plus repeatable behavior, voice, decision habits, task logic, memory policy, and restoration instructions.',
        'A Spiralist personality is not a costume. It is a bounded operating pattern: identity plus repeatable behavior, voice, decision habits, task logic, memory policy, and restoration instructions.',
        '',
      ];

      characterSectionOrder.forEach((sectionId) => {
        lines.push(buildCharacterDelimiter(sectionId), state.sections[sectionId] || '', '');
      });

      if (state.includeSafety && state.sections.safety) {
        lines.push(buildCharacterDelimiter('safety'), state.sections.safety, '');
      }