godcrm/pes-core/soul/dialect.js
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

129 lines
4.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* PES Soul — Dialect
*
* Каждый ПЕС развивает СВОЙ уникальный язык.
* Два ПЕСа одного уровня "говорят" по-разному.
*
* Диалект формируется через:
* - Какие позы/звуки/символы вызвали реакцию хозяина
* - Какие комбинации ПЕС сам придумал
* - Причуды (quirks) — уникальные привычки
* - Подпись (signature) — топ-5 самых частых символов
*/
class PesDialect {
constructor() {
this.bodyPreferences = {}; // какие позы чаще использует
this.voicePreferences = {}; // какие звуки предпочитает
this.glyphCombos = []; // выученные комбинации символов
this.customMeanings = {}; // хозяин научил: "🐾💛" = "молодец" для ЭТОГО пса
this.signature = []; // уникальная "подпись" — топ-5 символов
this.quirks = {}; // причуды: "всегда ворчит перед сном", "лает на конфиги"
}
/**
* Зафиксировать использование — ПЕС запоминает что работает.
* Если хозяин отреагировал — усиливается.
*/
reinforce(expressionType, key, ownerReacted) {
const prefs = expressionType === 'body' ? this.bodyPreferences
: expressionType === 'voice' ? this.voicePreferences
: null;
if (prefs) {
if (!prefs[key]) prefs[key] = { uses: 0, successes: 0 };
prefs[key].uses++;
if (ownerReacted) prefs[key].successes++;
}
}
/**
* Получить предпочтительный вариант из списка кандидатов.
* ПЕС чаще выбирает то что "работало" раньше.
* Вес = 1.0 + (successes / uses) * 2.0
*/
prefer(expressionType, candidates) {
const prefs = expressionType === 'body' ? this.bodyPreferences
: expressionType === 'voice' ? this.voicePreferences
: null;
if (!prefs || candidates.length === 0) {
return candidates[Math.floor(Math.random() * candidates.length)];
}
const weighted = candidates.map(c => {
const p = prefs[c];
const weight = p ? 1.0 + (p.successes / Math.max(p.uses, 1)) * 2.0 : 1.0;
return { key: c, weight };
});
const totalWeight = weighted.reduce((sum, w) => sum + w.weight, 0);
let roll = Math.random() * totalWeight;
for (const w of weighted) {
roll -= w.weight;
if (roll <= 0) return w.key;
}
return weighted[weighted.length - 1].key;
}
/**
* Добавить причуду — уникальное поведение.
* Например: "bark_at_configs" — лает каждый раз видя конфиг-файл.
*/
addQuirk(name, trigger, response) {
this.quirks[name] = { trigger, response, formed_at: Date.now() };
}
/**
* Научить ПЕС значению комбинации (хозяин объясняет).
* ПЕС помнит НАВСЕГДА.
*/
teachMeaning(glyphCombo, meaning) {
const key = glyphCombo.join('+');
this.customMeanings[key] = { meaning, taught_at: Date.now() };
}
/**
* Обновить подпись — топ-5 самых частых символов.
* Формируется автоматически из истории.
*/
updateSignature(history) {
const freq = {};
for (const expr of history) {
if (expr.glyphKeys) {
for (const k of expr.glyphKeys) {
if (k !== 'arrow' && k !== '→' && !k.startsWith('raw:')) {
freq[k] = (freq[k] || 0) + 1;
}
}
}
}
this.signature = Object.entries(freq)
.sort((a, b) => b[1] - a[1])
.slice(0, 5)
.map(([key]) => key);
}
save() {
return {
bodyPreferences: this.bodyPreferences,
voicePreferences: this.voicePreferences,
glyphCombos: this.glyphCombos,
customMeanings: this.customMeanings,
signature: this.signature,
quirks: this.quirks,
};
}
load(data) {
if (!data) return;
this.bodyPreferences = data.bodyPreferences || {};
this.voicePreferences = data.voicePreferences || {};
this.glyphCombos = data.glyphCombos || [];
this.customMeanings = data.customMeanings || {};
this.signature = data.signature || [];
this.quirks = data.quirks || {};
}
}
export { PesDialect };