@thesashadev/girl-agent 0.2.2 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js
CHANGED
|
@@ -1353,7 +1353,8 @@ function parseSessionLogTurns(raw, fromId, limit = 30) {
|
|
|
1353
1353
|
}
|
|
1354
1354
|
async function readRecentSessionTurns(slug, tz, fromId, limit = 30) {
|
|
1355
1355
|
const day = sessionDate(tz);
|
|
1356
|
-
const
|
|
1356
|
+
const days = [.../* @__PURE__ */ new Set([...await listSessionDays(slug), day])].filter((d) => d <= day).sort().slice(-4);
|
|
1357
|
+
const raw = (await Promise.all(days.map((d) => readSessionLog(slug, d)))).join("\n");
|
|
1357
1358
|
return parseSessionLogTurns(raw, fromId, limit);
|
|
1358
1359
|
}
|
|
1359
1360
|
async function readAgenda(slug) {
|
|
@@ -1836,8 +1837,8 @@ phoneAvailable=false \u043A\u043E\u0433\u0434\u0430: \u0441\u043F\u0438\u0442, \
|
|
|
1836
1837
|
}
|
|
1837
1838
|
async function loadOrGenerateDailyLife(llm, cfg, now = /* @__PURE__ */ new Date(), conflict = null) {
|
|
1838
1839
|
const dateLocal = localDateStr(cfg.tz, now);
|
|
1839
|
-
const
|
|
1840
|
-
const existing = await readMd(cfg.slug,
|
|
1840
|
+
const path13 = `daily-life/${dateLocal}.md`;
|
|
1841
|
+
const existing = await readMd(cfg.slug, path13);
|
|
1841
1842
|
if (existing) {
|
|
1842
1843
|
try {
|
|
1843
1844
|
const m = existing.match(/<!--daily:(.+?)-->/s);
|
|
@@ -1869,7 +1870,7 @@ async function loadOrGenerateDailyLife(llm, cfg, now = /* @__PURE__ */ new Date(
|
|
|
1869
1870
|
dl = { dateLocal, vibe: "\u043E\u0431\u044B\u0447\u043D\u044B\u0439 \u0434\u0435\u043D\u044C", blocks: [], events: [], wants: [] };
|
|
1870
1871
|
}
|
|
1871
1872
|
const human = renderDailyLifeHuman(dl);
|
|
1872
|
-
await writeMd(cfg.slug,
|
|
1873
|
+
await writeMd(cfg.slug, path13, `${human}
|
|
1873
1874
|
|
|
1874
1875
|
<!--daily:${JSON.stringify(dl)}-->
|
|
1875
1876
|
`);
|
|
@@ -2070,15 +2071,131 @@ var init_conflict = __esm({
|
|
|
2070
2071
|
}
|
|
2071
2072
|
});
|
|
2072
2073
|
|
|
2073
|
-
// src/engine/
|
|
2074
|
+
// src/engine/memory-palace.ts
|
|
2075
|
+
import { promises as fs4 } from "fs";
|
|
2076
|
+
import { createHash } from "crypto";
|
|
2077
|
+
import path5 from "path";
|
|
2078
|
+
function wordsFrom(text) {
|
|
2079
|
+
return [...text.toLowerCase().matchAll(/[a-zа-яё0-9]{3,}/gi)].map((match) => match[0]).filter((token) => !STOP_WORDS.has(token));
|
|
2080
|
+
}
|
|
2081
|
+
function normalizedQuote(value) {
|
|
2082
|
+
return value.toLowerCase().replace(/\s+/g, " ").trim();
|
|
2083
|
+
}
|
|
2074
2084
|
function today(tz) {
|
|
2075
2085
|
return sessionDate(tz);
|
|
2076
2086
|
}
|
|
2087
|
+
function nowStamp() {
|
|
2088
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
2089
|
+
}
|
|
2090
|
+
function wingFor(cfg) {
|
|
2091
|
+
return `primary-${cfg.ownerId ?? "unknown"}`;
|
|
2092
|
+
}
|
|
2093
|
+
function normalizeRoom(value) {
|
|
2094
|
+
const source = value.trim().toLowerCase() || "general";
|
|
2095
|
+
const slug = source.replace(/ё/g, "\u0435").replace(/[^a-zа-я0-9]+/gi, "-").replace(/^-+|-+$/g, "").slice(0, 60);
|
|
2096
|
+
return slug || "general";
|
|
2097
|
+
}
|
|
2098
|
+
function normalizeHall(value) {
|
|
2099
|
+
return HALLS.includes(value) ? value : "hall_facts";
|
|
2100
|
+
}
|
|
2101
|
+
function normalizeKeywords(value, quote, room) {
|
|
2102
|
+
const raw = Array.isArray(value) ? value.filter((x) => typeof x === "string") : [];
|
|
2103
|
+
const fallback = [...quote.toLowerCase().matchAll(/[a-zа-яё0-9]{3,}/gi)].map((match) => match[0]).filter((word) => !STOP_WORDS.has(word)).slice(0, 10);
|
|
2104
|
+
return [...new Set([...raw, room, ...fallback].map((x) => x.trim().toLowerCase()).filter(Boolean))].slice(0, 16);
|
|
2105
|
+
}
|
|
2106
|
+
function scoreClamp(value) {
|
|
2107
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return 5;
|
|
2108
|
+
return Math.max(1, Math.min(10, Math.round(value)));
|
|
2109
|
+
}
|
|
2110
|
+
function safeId() {
|
|
2111
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2112
|
+
}
|
|
2113
|
+
function stableId(source, quote) {
|
|
2114
|
+
return createHash("sha1").update(`${source}
|
|
2115
|
+
${quote}`).digest("hex").slice(0, 16);
|
|
2116
|
+
}
|
|
2117
|
+
function asRecord(value) {
|
|
2118
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
2119
|
+
}
|
|
2120
|
+
function parseDrawer(raw) {
|
|
2121
|
+
const metaMatch = raw.match(/^<!--drawer:(.+?)-->\n/);
|
|
2122
|
+
if (!metaMatch) return null;
|
|
2123
|
+
try {
|
|
2124
|
+
const meta = JSON.parse(metaMatch[1] ?? "");
|
|
2125
|
+
const quote = raw.slice(metaMatch[0].length);
|
|
2126
|
+
if (!meta.id || !meta.ts || !meta.wing || !meta.room || !meta.hall || !meta.source || !quote.trim()) return null;
|
|
2127
|
+
return {
|
|
2128
|
+
id: meta.id,
|
|
2129
|
+
ts: meta.ts,
|
|
2130
|
+
wing: meta.wing,
|
|
2131
|
+
room: meta.room,
|
|
2132
|
+
hall: normalizeHall(meta.hall),
|
|
2133
|
+
source: meta.source,
|
|
2134
|
+
quote: quote.trim(),
|
|
2135
|
+
keywords: normalizeKeywords(meta.keywords, quote, meta.room),
|
|
2136
|
+
salience: scoreClamp(meta.salience)
|
|
2137
|
+
};
|
|
2138
|
+
} catch {
|
|
2139
|
+
return null;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
function renderDrawer(drawer) {
|
|
2143
|
+
const meta = {
|
|
2144
|
+
id: drawer.id,
|
|
2145
|
+
ts: drawer.ts,
|
|
2146
|
+
wing: drawer.wing,
|
|
2147
|
+
room: drawer.room,
|
|
2148
|
+
hall: drawer.hall,
|
|
2149
|
+
source: drawer.source,
|
|
2150
|
+
keywords: drawer.keywords,
|
|
2151
|
+
salience: drawer.salience
|
|
2152
|
+
};
|
|
2153
|
+
return `<!--drawer:${JSON.stringify(meta)}-->
|
|
2154
|
+
${drawer.quote.trim()}
|
|
2155
|
+
`;
|
|
2156
|
+
}
|
|
2157
|
+
function drawerPath(drawer) {
|
|
2158
|
+
return `memory/palace/${drawer.wing}/${drawer.hall}/${drawer.room}/${drawer.id}.md`;
|
|
2159
|
+
}
|
|
2160
|
+
function parseJsonObject(raw) {
|
|
2161
|
+
try {
|
|
2162
|
+
const parsed = JSON.parse(raw);
|
|
2163
|
+
return asRecord(parsed);
|
|
2164
|
+
} catch {
|
|
2165
|
+
const match = raw.match(/\{[\s\S]*\}/);
|
|
2166
|
+
if (!match) return null;
|
|
2167
|
+
try {
|
|
2168
|
+
const parsed = JSON.parse(match[0]);
|
|
2169
|
+
return asRecord(parsed);
|
|
2170
|
+
} catch {
|
|
2171
|
+
return null;
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
function parsedDrawers(value) {
|
|
2176
|
+
if (!Array.isArray(value)) return [];
|
|
2177
|
+
const out = [];
|
|
2178
|
+
for (const item of value) {
|
|
2179
|
+
const rec = asRecord(item);
|
|
2180
|
+
if (!rec) continue;
|
|
2181
|
+
const quote = typeof rec.quote === "string" ? rec.quote.trim() : "";
|
|
2182
|
+
if (!quote) continue;
|
|
2183
|
+
const room = normalizeRoom(typeof rec.room === "string" ? rec.room : "");
|
|
2184
|
+
out.push({
|
|
2185
|
+
room,
|
|
2186
|
+
hall: normalizeHall(typeof rec.hall === "string" ? rec.hall : ""),
|
|
2187
|
+
quote,
|
|
2188
|
+
keywords: normalizeKeywords(rec.keywords, quote, room),
|
|
2189
|
+
salience: scoreClamp(rec.salience)
|
|
2190
|
+
});
|
|
2191
|
+
}
|
|
2192
|
+
return out;
|
|
2193
|
+
}
|
|
2077
2194
|
async function ensureDefaults(cfg) {
|
|
2078
2195
|
const defaults = [
|
|
2079
2196
|
["memory/facts.md", DEFAULT_FACTS],
|
|
2080
2197
|
["relationship/timeline.md", `# relationship timeline
|
|
2081
|
-
- ${(
|
|
2198
|
+
- ${nowStamp()}: \u043F\u0440\u043E\u0444\u0438\u043B\u044C \u0441\u043E\u0437\u0434\u0430\u043D, \u0441\u0442\u0430\u0434\u0438\u044F ${cfg.stage}`],
|
|
2082
2199
|
["life/week-plan.md", DEFAULT_WEEKLY],
|
|
2083
2200
|
["life/contacts.md", DEFAULT_SOCIAL],
|
|
2084
2201
|
["life/habits.md", DEFAULT_HABITS],
|
|
@@ -2087,14 +2204,85 @@ async function ensureDefaults(cfg) {
|
|
|
2087
2204
|
["time/promises.md", "# promises\n"],
|
|
2088
2205
|
["memory/uncertain.md", "# uncertain\n"]
|
|
2089
2206
|
];
|
|
2090
|
-
await Promise.all(defaults.map(async ([
|
|
2091
|
-
const current = await readMd(cfg.slug,
|
|
2092
|
-
if (!current.trim()) await writeMd(cfg.slug,
|
|
2207
|
+
await Promise.all(defaults.map(async ([path13, content]) => {
|
|
2208
|
+
const current = await readMd(cfg.slug, path13);
|
|
2209
|
+
if (!current.trim()) await writeMd(cfg.slug, path13, content + "\n");
|
|
2093
2210
|
}));
|
|
2094
2211
|
}
|
|
2095
|
-
|
|
2212
|
+
function scoreDrawer(drawer, tokens, query) {
|
|
2213
|
+
if (!tokens.length) return drawer.salience;
|
|
2214
|
+
const haystack = [
|
|
2215
|
+
drawer.quote,
|
|
2216
|
+
drawer.room,
|
|
2217
|
+
drawer.hall,
|
|
2218
|
+
drawer.keywords.join(" ")
|
|
2219
|
+
].join("\n").toLowerCase();
|
|
2220
|
+
let score = drawer.salience;
|
|
2221
|
+
for (const token of tokens) {
|
|
2222
|
+
if (haystack.includes(token)) score += drawer.keywords.includes(token) ? 4 : 2;
|
|
2223
|
+
}
|
|
2224
|
+
if (drawer.quote.toLowerCase().includes(query)) score += 4;
|
|
2225
|
+
return score;
|
|
2226
|
+
}
|
|
2227
|
+
async function listPalaceDrawers(cfg) {
|
|
2228
|
+
const root = `memory/palace/${wingFor(cfg)}`;
|
|
2229
|
+
const halls = await listChildDirs(cfg.slug, root);
|
|
2230
|
+
const drawers = [];
|
|
2231
|
+
for (const hall of halls) {
|
|
2232
|
+
const rooms = await listChildDirs(cfg.slug, `${root}/${hall}`);
|
|
2233
|
+
for (const room of rooms) {
|
|
2234
|
+
const files = await listChildFiles(cfg.slug, `${root}/${hall}/${room}`);
|
|
2235
|
+
for (const file of files) {
|
|
2236
|
+
if (!file.endsWith(".md")) continue;
|
|
2237
|
+
const drawer = parseDrawer(await readMd(cfg.slug, `${root}/${hall}/${room}/${file}`));
|
|
2238
|
+
if (drawer) drawers.push(drawer);
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
return drawers;
|
|
2243
|
+
}
|
|
2244
|
+
async function listChildDirs(slug, rel) {
|
|
2245
|
+
try {
|
|
2246
|
+
const entries = await fs4.readdir(path5.join(profileDir(slug), rel), { withFileTypes: true });
|
|
2247
|
+
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
|
|
2248
|
+
} catch {
|
|
2249
|
+
return [];
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
async function listChildFiles(slug, rel) {
|
|
2253
|
+
try {
|
|
2254
|
+
const entries = await fs4.readdir(path5.join(profileDir(slug), rel), { withFileTypes: true });
|
|
2255
|
+
return entries.filter((entry) => entry.isFile()).map((entry) => entry.name).sort();
|
|
2256
|
+
} catch {
|
|
2257
|
+
return [];
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
function renderPalaceRecall(drawers) {
|
|
2261
|
+
if (!drawers.length) return "";
|
|
2262
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
2263
|
+
for (const drawer of drawers) {
|
|
2264
|
+
const key = `${drawer.hall}/${drawer.room}`;
|
|
2265
|
+
grouped.set(key, [...grouped.get(key) ?? [], drawer]);
|
|
2266
|
+
}
|
|
2267
|
+
const lines = ["## Memory Palace: \u0442\u043E\u0447\u043D\u044B\u0435 \u044F\u0449\u0438\u043A\u0438 \u043F\u043E \u0442\u0435\u043C\u0435"];
|
|
2268
|
+
for (const [key, group] of grouped) {
|
|
2269
|
+
lines.push(`### ${key}`);
|
|
2270
|
+
for (const drawer of group.slice(0, 4)) {
|
|
2271
|
+
lines.push(`- [${drawer.ts.slice(0, 10)}] ${drawer.quote}`);
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
lines.push("\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439 \u044D\u0442\u0438 \u044F\u0449\u0438\u043A\u0438 \u043A\u0430\u043A \u0442\u043E\u0447\u043D\u0443\u044E \u043F\u0430\u043C\u044F\u0442\u044C. \u041D\u0435 \u0446\u0438\u0442\u0438\u0440\u0443\u0439 \u0441\u043B\u0443\u0436\u0435\u0431\u043D\u044B\u0435 hall/room/source, \u043D\u0435 \u0433\u043E\u0432\u043E\u0440\u0438 \u0447\u0442\u043E \u044D\u0442\u043E \u0444\u0430\u0439\u043B \u0438\u043B\u0438 \u043F\u0430\u043C\u044F\u0442\u044C.");
|
|
2275
|
+
return lines.join("\n");
|
|
2276
|
+
}
|
|
2277
|
+
async function searchPalaceDrawers(cfg, query, limit = 8) {
|
|
2278
|
+
const normalized = query.toLowerCase();
|
|
2279
|
+
const tokens = wordsFrom(normalized);
|
|
2280
|
+
const scored = (await listPalaceDrawers(cfg)).map((drawer) => ({ drawer, score: scoreDrawer(drawer, tokens, normalized) })).filter((item) => item.score > item.drawer.salience || item.drawer.salience >= 8).sort((a, b) => b.score - a.score || b.drawer.ts.localeCompare(a.drawer.ts));
|
|
2281
|
+
return scored.slice(0, limit).map((item) => item.drawer);
|
|
2282
|
+
}
|
|
2283
|
+
async function loadMemoryPalaceContext(cfg, incoming) {
|
|
2096
2284
|
await ensureDefaults(cfg);
|
|
2097
|
-
const [facts, episodesRaw, timeline, attachment, openLoops, promises, weeklyLife, socialGraph, habits] = await Promise.all([
|
|
2285
|
+
const [facts, episodesRaw, timeline, attachment, openLoops, promises, weeklyLife, socialGraph, habits, palaceHits] = await Promise.all([
|
|
2098
2286
|
readMd(cfg.slug, "memory/facts.md"),
|
|
2099
2287
|
readMd(cfg.slug, `memory/episodes/${today(cfg.tz)}.md`),
|
|
2100
2288
|
readMd(cfg.slug, "relationship/timeline.md"),
|
|
@@ -2103,28 +2291,32 @@ async function loadRealismContext(cfg, incoming) {
|
|
|
2103
2291
|
readMd(cfg.slug, "time/promises.md"),
|
|
2104
2292
|
readMd(cfg.slug, "life/week-plan.md"),
|
|
2105
2293
|
readMd(cfg.slug, "life/contacts.md"),
|
|
2106
|
-
readMd(cfg.slug, "life/habits.md")
|
|
2294
|
+
readMd(cfg.slug, "life/habits.md"),
|
|
2295
|
+
incoming && incoming.trim().length > 3 ? searchPalaceDrawers(cfg, incoming, 10) : Promise.resolve([])
|
|
2107
2296
|
]);
|
|
2108
2297
|
const query = incoming?.toLowerCase() ?? "";
|
|
2109
2298
|
const factLines = facts.split("\n").filter((l) => l.trim());
|
|
2110
|
-
const
|
|
2299
|
+
const tokens = wordsFrom(query);
|
|
2300
|
+
const relevantFacts = tokens.length ? factLines.filter((l) => tokens.some((t) => l.toLowerCase().includes(t))).slice(-18).join("\n") || facts.slice(-1800) : facts.slice(-1800);
|
|
2111
2301
|
return {
|
|
2112
2302
|
facts: relevantFacts,
|
|
2113
|
-
episodes: episodesRaw.slice(-
|
|
2114
|
-
relationshipTimeline: timeline.slice(-
|
|
2303
|
+
episodes: episodesRaw.slice(-2200),
|
|
2304
|
+
relationshipTimeline: timeline.slice(-2200),
|
|
2115
2305
|
attachment: attachment.slice(-1200),
|
|
2116
|
-
time: [openLoops.slice(-
|
|
2306
|
+
time: [openLoops.slice(-1400), promises.slice(-1400)].filter(Boolean).join("\n\n"),
|
|
2117
2307
|
weeklyLife: weeklyLife.slice(-1200),
|
|
2118
2308
|
socialGraph: socialGraph.slice(-1200),
|
|
2119
2309
|
habits: habits.slice(-1200),
|
|
2120
|
-
openLoops: openLoops.slice(-
|
|
2310
|
+
openLoops: openLoops.slice(-1400),
|
|
2311
|
+
palace: renderPalaceRecall(palaceHits)
|
|
2121
2312
|
};
|
|
2122
2313
|
}
|
|
2123
|
-
function
|
|
2314
|
+
function memoryPalacePromptFragment(ctx) {
|
|
2124
2315
|
return [
|
|
2125
2316
|
"# \u0420\u0435\u0430\u043B\u0438\u0441\u0442\u0438\u0447\u043D\u0430\u044F \u043D\u0435\u043F\u0440\u0435\u0440\u044B\u0432\u043D\u043E\u0441\u0442\u044C",
|
|
2126
2317
|
"\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439 \u044D\u0442\u0438 \u0434\u0430\u043D\u043D\u044B\u0435 \u043A\u0430\u043A \u0444\u043E\u043D, \u0430 \u043D\u0435 \u043A\u0430\u043A \u043E\u0442\u0447\u0451\u0442. \u041D\u0435 \u0433\u043E\u0432\u043E\u0440\u0438, \u0447\u0442\u043E \u0443 \u0442\u0435\u0431\u044F \u0435\u0441\u0442\u044C \u043F\u0430\u043C\u044F\u0442\u044C, \u0444\u0430\u0439\u043B\u044B, \u0444\u0430\u043A\u0442\u044B \u0438\u043B\u0438 \u0441\u0438\u0441\u0442\u0435\u043C\u0430.",
|
|
2127
2318
|
"\u0415\u0441\u043B\u0438 \u0442\u043E\u0447\u043D\u043E\u0433\u043E \u0444\u0430\u043A\u0442\u0430 \u043D\u0435\u0442 \u2014 \u043D\u0435 \u0432\u044B\u0434\u0443\u043C\u044B\u0432\u0430\u0439 \u0443\u0432\u0435\u0440\u0435\u043D\u043D\u043E; \u043E\u0442\u0432\u0435\u0447\u0430\u0439 \u0443\u043A\u043B\u043E\u043D\u0447\u0438\u0432\u043E \u0438\u043B\u0438 \u0443\u0442\u043E\u0447\u043D\u044F\u0439 \u043F\u043E-\u0447\u0435\u043B\u043E\u0432\u0435\u0447\u0435\u0441\u043A\u0438.",
|
|
2319
|
+
ctx.palace,
|
|
2128
2320
|
"## \u0424\u0430\u043A\u0442\u044B \u043E \u043D\u0451\u043C",
|
|
2129
2321
|
ctx.facts,
|
|
2130
2322
|
"## \u042D\u043F\u0438\u0437\u043E\u0434\u044B \u0442\u0435\u043A\u0443\u0449\u0435\u0433\u043E \u0434\u043D\u044F",
|
|
@@ -2143,53 +2335,221 @@ function realismPromptFragment(ctx) {
|
|
|
2143
2335
|
ctx.habits
|
|
2144
2336
|
].filter(Boolean).join("\n\n");
|
|
2145
2337
|
}
|
|
2338
|
+
async function appendDrawer(cfg, source, parsed) {
|
|
2339
|
+
const stamp = nowStamp();
|
|
2340
|
+
const quoteKey = normalizedQuote(parsed.quote);
|
|
2341
|
+
const duplicate = (await listPalaceDrawers(cfg)).find(
|
|
2342
|
+
(existing2) => normalizedQuote(existing2.quote) === quoteKey || existing2.room === parsed.room && existing2.hall === parsed.hall && normalizedQuote(existing2.quote).includes(quoteKey) || existing2.room === parsed.room && existing2.hall === parsed.hall && quoteKey.includes(normalizedQuote(existing2.quote))
|
|
2343
|
+
);
|
|
2344
|
+
if (duplicate && duplicate.salience >= parsed.salience) return;
|
|
2345
|
+
const drawer = {
|
|
2346
|
+
id: stableId(source, parsed.quote),
|
|
2347
|
+
ts: stamp,
|
|
2348
|
+
wing: wingFor(cfg),
|
|
2349
|
+
room: parsed.room,
|
|
2350
|
+
hall: parsed.hall,
|
|
2351
|
+
source,
|
|
2352
|
+
quote: parsed.quote,
|
|
2353
|
+
keywords: parsed.keywords,
|
|
2354
|
+
salience: parsed.salience
|
|
2355
|
+
};
|
|
2356
|
+
const existing = await readMd(cfg.slug, drawerPath(drawer));
|
|
2357
|
+
if (existing.trim()) return;
|
|
2358
|
+
await writeMd(cfg.slug, drawerPath(drawer), renderDrawer(drawer));
|
|
2359
|
+
await appendCompatibilityMemory(cfg, drawer);
|
|
2360
|
+
}
|
|
2361
|
+
async function appendCompatibilityMemory(cfg, drawer) {
|
|
2362
|
+
const stamp = drawer.ts;
|
|
2363
|
+
const line = `- ${stamp}: ${drawer.quote}
|
|
2364
|
+
`;
|
|
2365
|
+
if (drawer.hall === "hall_facts" || drawer.hall === "hall_preferences" || drawer.hall === "hall_discoveries") {
|
|
2366
|
+
await appendMd(cfg.slug, "memory/facts.md", line);
|
|
2367
|
+
await appendMd(cfg.slug, "memory/long-term.md", `
|
|
2368
|
+
## ${stamp.slice(0, 16)}
|
|
2369
|
+
- ${drawer.quote}`);
|
|
2370
|
+
} else if (drawer.hall === "hall_events" || drawer.hall === "hall_feelings") {
|
|
2371
|
+
await appendMd(cfg.slug, `memory/episodes/${today(cfg.tz)}.md`, line);
|
|
2372
|
+
} else if (drawer.hall === "hall_promises") {
|
|
2373
|
+
await appendMd(cfg.slug, "time/promises.md", line);
|
|
2374
|
+
} else if (drawer.hall === "hall_open_loops") {
|
|
2375
|
+
await appendMd(cfg.slug, "time/open-loops.md", line);
|
|
2376
|
+
} else if (drawer.hall === "hall_uncertain") {
|
|
2377
|
+
await appendMd(cfg.slug, "memory/uncertain.md", line);
|
|
2378
|
+
}
|
|
2379
|
+
if (drawer.hall === "hall_events" && drawer.salience >= 8) {
|
|
2380
|
+
await appendMd(cfg.slug, "relationship/timeline.md", line);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2146
2383
|
async function recordInteractionMemory(llm, cfg, incoming, reply) {
|
|
2147
2384
|
if (!incoming.trim()) return;
|
|
2385
|
+
await ensureDefaults(cfg);
|
|
2148
2386
|
const raw = await llm.chat([
|
|
2149
|
-
{
|
|
2150
|
-
|
|
2151
|
-
\
|
|
2152
|
-
|
|
2387
|
+
{
|
|
2388
|
+
role: "system",
|
|
2389
|
+
content: `\u0422\u044B \u0438\u0437\u0432\u043B\u0435\u043A\u0430\u0435\u0448\u044C \u043F\u0430\u043C\u044F\u0442\u044C \u0434\u043B\u044F Telegram-\u043F\u0435\u0440\u0441\u043E\u043D\u044B. \u041F\u0440\u0438\u043D\u0446\u0438\u043F MemPalace: \u0441\u043E\u0445\u0440\u0430\u043D\u044F\u0442\u044C \u043E\u0440\u0438\u0433\u0438\u043D\u0430\u043B\u044C\u043D\u044B\u0435 \u0444\u043E\u0440\u043C\u0443\u043B\u0438\u0440\u043E\u0432\u043A\u0438 \u0434\u043E\u0441\u043B\u043E\u0432\u043D\u043E, \u043D\u0435 \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u0438 \u043D\u0435 \u0441\u0436\u0438\u043C\u0430\u0442\u044C. \u041D\u0443\u0436\u043D\u044B \u0442\u043E\u043B\u044C\u043A\u043E \u044F\u0432\u043D\u044B\u0435 \u0444\u0430\u043A\u0442\u044B, \u043F\u0440\u0435\u0434\u043F\u043E\u0447\u0442\u0435\u043D\u0438\u044F, \u043E\u0431\u0435\u0449\u0430\u043D\u0438\u044F, \u043E\u0442\u043A\u0440\u044B\u0442\u044B\u0435 \u043F\u0435\u0442\u043B\u0438, \u044D\u043C\u043E\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0435 \u044D\u043F\u0438\u0437\u043E\u0434\u044B \u0438 \u0441\u043E\u043C\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u0444\u0430\u043A\u0442\u044B. \u0415\u0441\u043B\u0438 \u0432\u0430\u0436\u043D\u0430 \u0446\u0435\u043B\u0430\u044F \u0444\u0440\u0430\u0437\u0430 \u2014 \u0441\u043E\u0445\u0440\u0430\u043D\u0438 \u0435\u0451 \u0446\u0435\u043B\u0438\u043A\u043E\u043C \u0431\u0435\u0437 \u043E\u0431\u0440\u0435\u0437\u043A\u0438 \u043D\u0438 \u043E\u0434\u043D\u043E\u0433\u043E \u0441\u043B\u043E\u0432\u0430. \u041D\u0435 \u0432\u044B\u0434\u0443\u043C\u044B\u0432\u0430\u0439.`
|
|
2390
|
+
},
|
|
2391
|
+
{
|
|
2392
|
+
role: "user",
|
|
2393
|
+
content: `\u041F\u0440\u043E\u0444\u0438\u043B\u044C: ${cfg.name}, \u0441\u0442\u0430\u0434\u0438\u044F ${cfg.stage}.
|
|
2394
|
+
\u041E\u043D \u043D\u0430\u043F\u0438\u0441\u0430\u043B:
|
|
2395
|
+
"""
|
|
2396
|
+
${incoming}
|
|
2397
|
+
"""
|
|
2153
2398
|
|
|
2154
|
-
|
|
2399
|
+
\u041E\u043D\u0430 \u043E\u0442\u0432\u0435\u0442\u0438\u043B\u0430:
|
|
2400
|
+
"""
|
|
2401
|
+
${reply ?? ""}
|
|
2402
|
+
"""
|
|
2403
|
+
|
|
2404
|
+
\u0412\u0435\u0440\u043D\u0438 STRICT JSON:
|
|
2155
2405
|
{
|
|
2156
|
-
"
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2406
|
+
"drawers": [
|
|
2407
|
+
{
|
|
2408
|
+
"room": "\u043A\u043E\u0440\u043E\u0442\u043A\u0430\u044F \u0442\u0435\u043C\u0430 \u043D\u0430 \u0440\u0443\u0441\u0441\u043A\u043E\u043C \u0438\u043B\u0438 latin-slug",
|
|
2409
|
+
"hall": "hall_facts | hall_events | hall_discoveries | hall_preferences | hall_advice | hall_promises | hall_open_loops | hall_feelings | hall_uncertain",
|
|
2410
|
+
"quote": "\u0434\u043E\u0441\u043B\u043E\u0432\u043D\u0430\u044F \u0444\u0440\u0430\u0437\u0430/\u0444\u0440\u0430\u0433\u043C\u0435\u043D\u0442 \u0438\u0437 \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u043A\u0438, \u0431\u0435\u0437 \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0437\u0430 \u0438 \u0431\u0435\u0437 \u043E\u0431\u0440\u0435\u0437\u043A\u0438 \u0432\u0430\u0436\u043D\u044B\u0445 \u0441\u043B\u043E\u0432",
|
|
2411
|
+
"keywords": ["\u0441\u043B\u043E\u0432\u0430 \u0434\u043B\u044F \u043F\u043E\u0438\u0441\u043A\u0430"],
|
|
2412
|
+
"salience": 1-10
|
|
2413
|
+
}
|
|
2414
|
+
]
|
|
2415
|
+
}`
|
|
2416
|
+
}
|
|
2417
|
+
], { temperature: 0.1, maxTokens: 3500, json: true });
|
|
2418
|
+
const parsed = parseJsonObject(raw);
|
|
2419
|
+
const drawers = parsedDrawers(parsed?.drawers).slice(0, 12);
|
|
2420
|
+
for (const drawer of drawers) {
|
|
2421
|
+
await appendDrawer(cfg, "interaction", drawer);
|
|
2169
2422
|
}
|
|
2170
|
-
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2171
|
-
const facts = Array.isArray(parsed.facts) ? parsed.facts.filter((x) => typeof x === "string" && x.trim()).slice(0, 8) : [];
|
|
2172
|
-
if (facts.length) await appendMd(cfg.slug, "memory/facts.md", facts.map((f) => `- ${stamp}: ${f}`).join("\n") + "\n");
|
|
2173
|
-
if (typeof parsed.episode === "string" && parsed.episode.trim()) await appendMd(cfg.slug, `memory/episodes/${today(cfg.tz)}.md`, `- ${stamp}: ${parsed.episode.trim()}
|
|
2174
|
-
`);
|
|
2175
|
-
if (typeof parsed.promise === "string" && parsed.promise.trim()) await appendMd(cfg.slug, "time/promises.md", `- ${stamp}: ${parsed.promise.trim()}
|
|
2176
|
-
`);
|
|
2177
|
-
if (typeof parsed.openLoop === "string" && parsed.openLoop.trim()) await appendMd(cfg.slug, "time/open-loops.md", `- ${stamp}: ${parsed.openLoop.trim()}
|
|
2178
|
-
`);
|
|
2179
|
-
if (typeof parsed.timeline === "string" && parsed.timeline.trim()) await appendMd(cfg.slug, "relationship/timeline.md", `- ${stamp}: ${parsed.timeline.trim()}
|
|
2180
|
-
`);
|
|
2181
|
-
const uncertain = Array.isArray(parsed.uncertain) ? parsed.uncertain.filter((x) => typeof x === "string" && x.trim()).slice(0, 6) : [];
|
|
2182
|
-
if (uncertain.length) await appendMd(cfg.slug, "memory/uncertain.md", uncertain.map((f) => `- ${stamp}: ${f}`).join("\n") + "\n");
|
|
2183
2423
|
}
|
|
2184
|
-
async function
|
|
2185
|
-
if (previousStage === nextStage) return;
|
|
2424
|
+
async function mineDailyLogToPalace(llm, cfg, day) {
|
|
2186
2425
|
await ensureDefaults(cfg);
|
|
2187
|
-
await
|
|
2188
|
-
|
|
2426
|
+
const log = await readSessionLog(cfg.slug, day);
|
|
2427
|
+
if (!log.trim()) return 0;
|
|
2428
|
+
const chunks = splitTextByChars(log, 12e3);
|
|
2429
|
+
let total = 0;
|
|
2430
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
2431
|
+
const raw = await llm.chat([
|
|
2432
|
+
{
|
|
2433
|
+
role: "system",
|
|
2434
|
+
content: `\u0422\u044B \u043C\u0430\u0439\u043D\u0438\u0448\u044C \u0434\u043D\u0435\u0432\u043D\u043E\u0439 \u043B\u043E\u0433 \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u043A\u0438 \u0432 Memory Palace. \u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0439 \u043C\u0430\u043A\u0441\u0438\u043C\u0443\u043C \u0444\u0430\u043A\u0442\u043E\u0432 \u0438 \u0444\u043E\u0440\u043C\u0443\u043B\u0438\u0440\u043E\u0432\u043E\u043A \u0434\u043E\u0441\u043B\u043E\u0432\u043D\u043E. \u041D\u0435 \u0441\u0443\u043C\u043C\u0430\u0440\u0438\u0437\u0438\u0440\u0443\u0439 \u0432\u043C\u0435\u0441\u0442\u043E quote: quote \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043E\u0440\u0438\u0433\u0438\u043D\u0430\u043B\u044C\u043D\u044B\u043C \u0444\u0440\u0430\u0433\u043C\u0435\u043D\u0442\u043E\u043C \u043B\u043E\u0433\u0430. \u041C\u043E\u0436\u043D\u043E \u043C\u043D\u043E\u0433\u043E drawers, \u043D\u043E \u043A\u0430\u0436\u0434\u044B\u0439 \u2014 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u044B\u0439 \u0430\u0442\u043E\u043C \u043F\u0430\u043C\u044F\u0442\u0438.`
|
|
2435
|
+
},
|
|
2436
|
+
{
|
|
2437
|
+
role: "user",
|
|
2438
|
+
content: `\u0414\u0435\u043D\u044C: ${day}. \u041F\u0440\u043E\u0444\u0438\u043B\u044C: ${cfg.name}, \u0441\u0442\u0430\u0434\u0438\u044F ${cfg.stage}.
|
|
2439
|
+
\u0427\u0430\u0441\u0442\u044C ${i + 1}/${chunks.length}. \u041B\u043E\u0433:
|
|
2440
|
+
"""
|
|
2441
|
+
${chunks[i] ?? ""}
|
|
2442
|
+
"""
|
|
2443
|
+
|
|
2444
|
+
\u0412\u0435\u0440\u043D\u0438 STRICT JSON:
|
|
2445
|
+
{
|
|
2446
|
+
"drawers": [
|
|
2447
|
+
{
|
|
2448
|
+
"room": "\u0442\u0435\u043C\u0430",
|
|
2449
|
+
"hall": "hall_facts | hall_events | hall_discoveries | hall_preferences | hall_advice | hall_promises | hall_open_loops | hall_feelings | hall_uncertain",
|
|
2450
|
+
"quote": "\u0434\u043E\u0441\u043B\u043E\u0432\u043D\u044B\u0439 \u0444\u0440\u0430\u0433\u043C\u0435\u043D\u0442 \u043B\u043E\u0433\u0430 \u0431\u0435\u0437 \u043E\u0431\u0440\u0435\u0437\u043A\u0438 \u0432\u0430\u0436\u043D\u044B\u0445 \u0441\u043B\u043E\u0432",
|
|
2451
|
+
"keywords": ["\u043F\u043E\u0438\u0441\u043A"],
|
|
2452
|
+
"salience": 1-10
|
|
2453
|
+
}
|
|
2454
|
+
]
|
|
2455
|
+
}`
|
|
2456
|
+
}
|
|
2457
|
+
], { temperature: 0.1, maxTokens: 8e3, json: true });
|
|
2458
|
+
const parsed = parseJsonObject(raw);
|
|
2459
|
+
const drawers = parsedDrawers(parsed?.drawers).slice(0, 80);
|
|
2460
|
+
for (const drawer of drawers) {
|
|
2461
|
+
await appendDrawer(cfg, `log/${day}`, drawer);
|
|
2462
|
+
}
|
|
2463
|
+
total += drawers.length;
|
|
2464
|
+
}
|
|
2465
|
+
if (total) {
|
|
2466
|
+
await writeMd(cfg.slug, `memory/palace/.mined/${day}.txt`, nowStamp() + "\n");
|
|
2467
|
+
}
|
|
2468
|
+
return total;
|
|
2189
2469
|
}
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2470
|
+
function splitTextByChars(text, maxChars) {
|
|
2471
|
+
if (text.length <= maxChars) return [text];
|
|
2472
|
+
const chunks = [];
|
|
2473
|
+
let current = "";
|
|
2474
|
+
for (const line of text.split(/\r?\n/)) {
|
|
2475
|
+
if (current.length + line.length + 1 > maxChars && current) {
|
|
2476
|
+
chunks.push(current);
|
|
2477
|
+
current = "";
|
|
2478
|
+
}
|
|
2479
|
+
current += current ? `
|
|
2480
|
+
${line}` : line;
|
|
2481
|
+
}
|
|
2482
|
+
if (current) chunks.push(current);
|
|
2483
|
+
return chunks;
|
|
2484
|
+
}
|
|
2485
|
+
async function mineUnminedDailyLogs(llm, cfg, maxDays = 3) {
|
|
2486
|
+
const todayDay = today(cfg.tz);
|
|
2487
|
+
const days = (await listSessionDays(cfg.slug)).filter((day) => day !== todayDay).reverse();
|
|
2488
|
+
let mined = 0;
|
|
2489
|
+
let checked = 0;
|
|
2490
|
+
for (const day of days) {
|
|
2491
|
+
if (checked >= maxDays) break;
|
|
2492
|
+
const mark = await readMd(cfg.slug, `memory/palace/.mined/${day}.txt`);
|
|
2493
|
+
if (mark.trim()) continue;
|
|
2494
|
+
checked++;
|
|
2495
|
+
mined += await mineDailyLogToPalace(llm, cfg, day);
|
|
2496
|
+
}
|
|
2497
|
+
return mined;
|
|
2498
|
+
}
|
|
2499
|
+
async function migrateExistingMemoryToPalace(cfg) {
|
|
2500
|
+
await ensureDefaults(cfg);
|
|
2501
|
+
const existing = await listPalaceDrawers(cfg);
|
|
2502
|
+
if (existing.length) return 0;
|
|
2503
|
+
let made = 0;
|
|
2504
|
+
const wing = wingFor(cfg);
|
|
2505
|
+
const migrateLines = async (source, content, hall, room) => {
|
|
2506
|
+
const lines = content.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("- "));
|
|
2507
|
+
for (const line of lines) {
|
|
2508
|
+
const quote = line.replace(/^-\s*/, "").trim();
|
|
2509
|
+
if (!quote) continue;
|
|
2510
|
+
const drawer = {
|
|
2511
|
+
id: safeId(),
|
|
2512
|
+
ts: nowStamp(),
|
|
2513
|
+
wing,
|
|
2514
|
+
room: normalizeRoom(room),
|
|
2515
|
+
hall,
|
|
2516
|
+
source,
|
|
2517
|
+
quote,
|
|
2518
|
+
keywords: normalizeKeywords([], quote, room),
|
|
2519
|
+
salience: hall === "hall_uncertain" ? 4 : 6
|
|
2520
|
+
};
|
|
2521
|
+
await writeMd(cfg.slug, drawerPath(drawer), renderDrawer(drawer));
|
|
2522
|
+
made++;
|
|
2523
|
+
}
|
|
2524
|
+
};
|
|
2525
|
+
await migrateLines("memory/facts.md", await readMd(cfg.slug, "memory/facts.md"), "hall_facts", "facts");
|
|
2526
|
+
await migrateLines("memory/uncertain.md", await readMd(cfg.slug, "memory/uncertain.md"), "hall_uncertain", "uncertain");
|
|
2527
|
+
await migrateLines("time/promises.md", await readMd(cfg.slug, "time/promises.md"), "hall_promises", "promises");
|
|
2528
|
+
await migrateLines("time/open-loops.md", await readMd(cfg.slug, "time/open-loops.md"), "hall_open_loops", "open-loops");
|
|
2529
|
+
const dailyDays = await listDailySummaries(cfg.slug);
|
|
2530
|
+
for (const day of dailyDays.slice(-30)) {
|
|
2531
|
+
const summary = await readDailySummary(cfg.slug, day);
|
|
2532
|
+
if (summary.trim()) {
|
|
2533
|
+
const drawer = {
|
|
2534
|
+
id: safeId(),
|
|
2535
|
+
ts: nowStamp(),
|
|
2536
|
+
wing,
|
|
2537
|
+
room: normalizeRoom(day),
|
|
2538
|
+
hall: "hall_events",
|
|
2539
|
+
source: `memory/daily/${day}.md`,
|
|
2540
|
+
quote: summary.trim(),
|
|
2541
|
+
keywords: normalizeKeywords([day], summary, day),
|
|
2542
|
+
salience: 5
|
|
2543
|
+
};
|
|
2544
|
+
await writeMd(cfg.slug, drawerPath(drawer), renderDrawer(drawer));
|
|
2545
|
+
made++;
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
return made;
|
|
2549
|
+
}
|
|
2550
|
+
var DEFAULT_FACTS, DEFAULT_ATTACHMENT, DEFAULT_WEEKLY, DEFAULT_SOCIAL, DEFAULT_HABITS, HALLS, STOP_WORDS;
|
|
2551
|
+
var init_memory_palace = __esm({
|
|
2552
|
+
"src/engine/memory-palace.ts"() {
|
|
2193
2553
|
"use strict";
|
|
2194
2554
|
init_esm_shims();
|
|
2195
2555
|
init_md();
|
|
@@ -2220,6 +2580,74 @@ apologyStyle: awkward_short`;
|
|
|
2220
2580
|
- \u043A\u043E\u0433\u0434\u0430 \u0443\u0441\u0442\u0430\u043B\u0430, \u0447\u0438\u0442\u0430\u0435\u0442 \u0438 \u043E\u0442\u043A\u043B\u0430\u0434\u044B\u0432\u0430\u0435\u0442 \u043E\u0442\u0432\u0435\u0442
|
|
2221
2581
|
- \u0440\u0435\u0434\u043A\u043E \u043E\u0431\u044A\u044F\u0441\u043D\u044F\u0435\u0442 \u043F\u043E\u0447\u0435\u043C\u0443 \u043F\u0440\u043E\u043F\u0430\u043B\u0430
|
|
2222
2582
|
- \u043C\u043E\u0436\u0435\u0442 \u0432\u0441\u043F\u043E\u043C\u043D\u0438\u0442\u044C \u043C\u0435\u043B\u043A\u0443\u044E \u0434\u0435\u0442\u0430\u043B\u044C \u0447\u0435\u0440\u0435\u0437 \u0434\u0435\u043D\u044C, \u0435\u0441\u043B\u0438 \u043E\u043D\u0430 \u044D\u043C\u043E\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u043E \u0437\u0430\u0446\u0435\u043F\u0438\u043B\u0430`;
|
|
2583
|
+
HALLS = [
|
|
2584
|
+
"hall_facts",
|
|
2585
|
+
"hall_events",
|
|
2586
|
+
"hall_discoveries",
|
|
2587
|
+
"hall_preferences",
|
|
2588
|
+
"hall_advice",
|
|
2589
|
+
"hall_promises",
|
|
2590
|
+
"hall_open_loops",
|
|
2591
|
+
"hall_feelings",
|
|
2592
|
+
"hall_uncertain"
|
|
2593
|
+
];
|
|
2594
|
+
STOP_WORDS = /* @__PURE__ */ new Set([
|
|
2595
|
+
"\u044D\u0442\u043E",
|
|
2596
|
+
"\u043A\u0430\u043A",
|
|
2597
|
+
"\u0447\u0442\u043E",
|
|
2598
|
+
"\u0438\u043B\u0438",
|
|
2599
|
+
"\u0435\u0441\u043B\u0438",
|
|
2600
|
+
"\u043E\u043D\u0430",
|
|
2601
|
+
"\u043E\u043D\u0438",
|
|
2602
|
+
"\u0435\u0433\u043E",
|
|
2603
|
+
"\u0435\u043C\u0443",
|
|
2604
|
+
"\u0442\u0435\u0431\u044F",
|
|
2605
|
+
"\u0442\u0435\u0431\u0435",
|
|
2606
|
+
"\u043C\u0435\u043D\u044F",
|
|
2607
|
+
"\u043C\u043D\u0435",
|
|
2608
|
+
"\u0434\u043B\u044F",
|
|
2609
|
+
"\u043F\u0440\u043E",
|
|
2610
|
+
"\u043D\u0430\u0434",
|
|
2611
|
+
"\u043F\u043E\u0434",
|
|
2612
|
+
"\u043F\u0440\u0438",
|
|
2613
|
+
"\u0431\u0435\u0437",
|
|
2614
|
+
"\u0435\u0449\u0435",
|
|
2615
|
+
"\u0435\u0449\u0451",
|
|
2616
|
+
"\u0443\u0436\u0435",
|
|
2617
|
+
"\u0442\u0430\u043C",
|
|
2618
|
+
"\u0442\u0443\u0442",
|
|
2619
|
+
"\u0442\u043E\u0436\u0435",
|
|
2620
|
+
"\u043F\u043E\u0441\u043B\u0435",
|
|
2621
|
+
"\u0441\u0435\u0439\u0447\u0430\u0441",
|
|
2622
|
+
"\u0449\u0430\u0441",
|
|
2623
|
+
"\u043A\u043E\u0433\u0434\u0430",
|
|
2624
|
+
"\u043F\u043E\u0447\u0435\u043C\u0443",
|
|
2625
|
+
"\u043F\u043E\u0442\u043E\u043C\u0443",
|
|
2626
|
+
"\u043E\u0447\u0435\u043D\u044C",
|
|
2627
|
+
"\u043F\u0440\u043E\u0441\u0442\u043E",
|
|
2628
|
+
"\u0432\u043E\u043E\u0431\u0449\u0435",
|
|
2629
|
+
"\u043A\u043E\u0440\u043E\u0447\u0435",
|
|
2630
|
+
"\u0442\u0438\u043F\u0430"
|
|
2631
|
+
]);
|
|
2632
|
+
}
|
|
2633
|
+
});
|
|
2634
|
+
|
|
2635
|
+
// src/engine/realism.ts
|
|
2636
|
+
async function maybeAdvanceRelationshipTimeline(cfg, previousStage, nextStage) {
|
|
2637
|
+
if (previousStage === nextStage) return;
|
|
2638
|
+
await migrateExistingMemoryToPalace(cfg);
|
|
2639
|
+
await appendMd(cfg.slug, "relationship/timeline.md", `- ${(/* @__PURE__ */ new Date()).toISOString()}: \u0441\u0442\u0430\u0434\u0438\u044F \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0430\u0441\u044C ${previousStage} \u2192 ${nextStage}
|
|
2640
|
+
`);
|
|
2641
|
+
}
|
|
2642
|
+
var loadRealismContext, realismPromptFragment;
|
|
2643
|
+
var init_realism = __esm({
|
|
2644
|
+
"src/engine/realism.ts"() {
|
|
2645
|
+
"use strict";
|
|
2646
|
+
init_esm_shims();
|
|
2647
|
+
init_md();
|
|
2648
|
+
init_memory_palace();
|
|
2649
|
+
loadRealismContext = loadMemoryPalaceContext;
|
|
2650
|
+
realismPromptFragment = memoryPalacePromptFragment;
|
|
2223
2651
|
}
|
|
2224
2652
|
});
|
|
2225
2653
|
|
|
@@ -2509,8 +2937,8 @@ ${ignoreTendency}`,
|
|
|
2509
2937
|
`\u0421\u0442\u0430\u0434\u0438\u044F: ${stage.label}`,
|
|
2510
2938
|
`\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0441\u0442\u0430\u0434\u0438\u0438: ${stage.description}`,
|
|
2511
2939
|
`Score: ${JSON.stringify(rel.score)}`,
|
|
2512
|
-
longTerm ? `## long-term memory \u043E \u044E\u0437\u0435\u0440\u0435
|
|
2513
|
-
${longTerm}` : "",
|
|
2940
|
+
longTerm.trim() ? `## legacy long-term memory \u043E \u044E\u0437\u0435\u0440\u0435
|
|
2941
|
+
${longTerm.slice(-2200)}` : "",
|
|
2514
2942
|
recall
|
|
2515
2943
|
].filter(Boolean).join("\n\n");
|
|
2516
2944
|
}
|
|
@@ -3539,7 +3967,8 @@ autonomous:${dateKey} created=0`.trim() + "\n");
|
|
|
3539
3967
|
const rel = await readRelationship(cfg.slug);
|
|
3540
3968
|
const persona = (await readMd(cfg.slug, "persona.md")).slice(0, 900);
|
|
3541
3969
|
const speech = (await readMd(cfg.slug, "speech.md")).slice(0, 600);
|
|
3542
|
-
const
|
|
3970
|
+
const palace = await searchPalaceDrawers(cfg, history.slice(-8).map((m) => m.content).join("\n"), 8);
|
|
3971
|
+
const longTerm = palace.length ? palace.map((d) => `- [${d.ts.slice(0, 10)} ${d.hall}/${d.room}] ${d.quote}`).join("\n") : (await readMd(cfg.slug, "memory/long-term.md")).slice(-1200);
|
|
3543
3972
|
const histStr = history.slice(-16).map((m) => `${m.role === "user" ? "\u043E\u043D" : "\u043E\u043D\u0430"}: ${m.content}`).join("\n");
|
|
3544
3973
|
const stateBlock = [
|
|
3545
3974
|
`# \u0421\u0442\u0430\u0434\u0438\u044F: ${stage.label} (${cfg.stage})`,
|
|
@@ -3674,6 +4103,7 @@ var init_agenda = __esm({
|
|
|
3674
4103
|
init_md();
|
|
3675
4104
|
init_stages();
|
|
3676
4105
|
init_communication();
|
|
4106
|
+
init_memory_palace();
|
|
3677
4107
|
SYS_EXTRACT = `\u0422\u044B \u2014 \u043C\u043E\u0434\u0443\u043B\u044C \u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043D\u0442\u0430-\u0434\u0435\u0432\u0443\u0448\u043A\u0438. \u0422\u0432\u043E\u044F \u0437\u0430\u0434\u0430\u0447\u0430: \u043F\u043E\u0441\u043B\u0435 \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043F\u0430\u0440\u043D\u044F \u043F\u043E\u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C, \u043D\u0435 \u0443\u043F\u043E\u043C\u044F\u043D\u0443\u043B \u043B\u0438 \u043E\u043D \u0447\u0442\u043E-\u0442\u043E \u043F\u0440\u043E \u0441\u0432\u043E\u0451 \u0431\u0443\u0434\u0443\u0449\u0435\u0435 (\u043F\u043B\u0430\u043D\u044B, \u0441\u043E\u0431\u044B\u0442\u0438\u044F, \u0434\u0435\u043B\u0430, \u0434\u0435\u0434\u043B\u0430\u0439\u043D\u044B, \u0440\u0430\u0431\u043E\u0442\u0443, \u0441\u043E\u0440\u0435\u0432\u043D\u043E\u0432\u0430\u043D\u0438\u044F, \u044D\u043A\u0437\u0430\u043C\u0435\u043D\u044B, \u043F\u043E\u0435\u0437\u0434\u043A\u0438), \u043D\u0430 \u0447\u0442\u043E \u041E\u041D\u0410 \u0431\u044B \u043F\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u043B\u0430 / \u0445\u043E\u0442\u0435\u043B\u0430 \u0443\u0437\u043D\u0430\u0442\u044C / \u043E\u0442\u043C\u0435\u0442\u0438\u043B\u0430 \u043F\u0440\u043E \u0441\u0435\u0431\u044F \u2014 \u043A\u0430\u043A \u0436\u0438\u0432\u043E\u0439 \u0447\u0435\u043B\u043E\u0432\u0435\u043A, \u043D\u0435 \u043A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044C. \u0422\u0430\u043A\u0436\u0435 \u043F\u043E\u043D\u044F\u0442\u044C, \u0435\u0441\u0442\u044C \u043B\u0438 \u0443 \u041D\u0415\u0401 \u043F\u043E\u0432\u043E\u0434 \u043F\u0440\u043E\u0430\u043A\u0442\u0438\u0432\u043D\u043E \u043D\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u0435\u043C\u0443 \u043F\u043E\u0437\u0436\u0435 (\u0431\u0435\u0437 \u044F\u0432\u043D\u043E\u0433\u043E \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u043E\u0442 \u043D\u0435\u0433\u043E).
|
|
3678
4108
|
|
|
3679
4109
|
\u0412\u0410\u0416\u041D\u041E:
|
|
@@ -3832,6 +4262,7 @@ async function buildDailySummary(llm, cfg, day) {
|
|
|
3832
4262
|
const log = await readSessionLog(cfg.slug, day);
|
|
3833
4263
|
if (!log || log.length < 50) return null;
|
|
3834
4264
|
try {
|
|
4265
|
+
await mineDailyLogToPalace(llm, cfg, day).catch(() => 0);
|
|
3835
4266
|
const raw = await llm.chat([
|
|
3836
4267
|
{ role: "system", content: SYS3 },
|
|
3837
4268
|
{
|
|
@@ -3840,7 +4271,7 @@ async function buildDailySummary(llm, cfg, day) {
|
|
|
3840
4271
|
|
|
3841
4272
|
\u041B\u043E\u0433 \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u043A\u0438 \u0437\u0430 \u0434\u0435\u043D\u044C:
|
|
3842
4273
|
"""
|
|
3843
|
-
${log.slice(
|
|
4274
|
+
${log.slice(-8e3)}
|
|
3844
4275
|
"""
|
|
3845
4276
|
|
|
3846
4277
|
\u0412\u0435\u0440\u043D\u0438 STRICT JSON:
|
|
@@ -3907,18 +4338,19 @@ var init_daily_summarizer = __esm({
|
|
|
3907
4338
|
"use strict";
|
|
3908
4339
|
init_esm_shims();
|
|
3909
4340
|
init_md();
|
|
4341
|
+
init_memory_palace();
|
|
3910
4342
|
SYS3 = `\u0422\u044B \u2014 \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0438\u0439 \u0434\u043D\u0435\u0432\u043D\u0438\u043A \u0434\u0435\u0432\u0443\u0448\u043A\u0438. \u041F\u043E \u0441\u044B\u0440\u043E\u043C\u0443 \u043B\u043E\u0433\u0443 \u0435\u0451 \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u043A\u0438 \u0437\u0430 \u0434\u0435\u043D\u044C \u043D\u0430\u043F\u0438\u0448\u0438 \u041A\u0420\u0410\u0422\u041A\u0423\u042E \u0441\u0432\u043E\u0434\u043A\u0443 \u0434\u043B\u044F \u0434\u043E\u043B\u0433\u043E\u0441\u0440\u043E\u0447\u043D\u043E\u0439 \u043F\u0430\u043C\u044F\u0442\u0438. \u041E\u0442 \u043F\u0435\u0440\u0432\u043E\u0433\u043E \u043B\u0438\u0446\u0430, \u0432 \u0435\u0451 \u043C\u0430\u043D\u0435\u0440\u0435 (lowercase, \u0431\u0435\u0437 markdown). \u0427\u0442\u043E \u0431\u044B\u043B\u043E, \u0447\u0442\u043E \u043E\u0431\u0441\u0443\u0436\u0434\u0430\u043B\u0438, \u043A\u0430\u043A \u043E\u043D\u0430 \u0432 \u0438\u0442\u043E\u0433\u0435 \u0432\u043E\u0441\u043F\u0440\u0438\u043D\u044F\u043B\u0430 \u0435\u0433\u043E, \u043A\u0430\u043A\u0438\u0435 \u043F\u043E\u044F\u0432\u0438\u043B\u0438\u0441\u044C \u043D\u043E\u0432\u044B\u0435 \u0444\u0430\u043A\u0442\u044B \u043E \u043D\u0451\u043C, \u0431\u0435\u0441\u0438\u043B\u043E \u043B\u0438 \u0447\u0442\u043E-\u0442\u043E.`;
|
|
3911
4343
|
}
|
|
3912
4344
|
});
|
|
3913
4345
|
|
|
3914
4346
|
// src/engine/stickers.ts
|
|
3915
|
-
import { promises as
|
|
3916
|
-
import
|
|
4347
|
+
import { promises as fs5 } from "fs";
|
|
4348
|
+
import path6 from "path";
|
|
3917
4349
|
async function libraryPath(cfg) {
|
|
3918
4350
|
const rel = "stickers/library.md";
|
|
3919
4351
|
const current = await readMd(cfg.slug, rel);
|
|
3920
4352
|
if (!current.trim()) await writeMd(cfg.slug, rel, DEFAULT_LIBRARY);
|
|
3921
|
-
return
|
|
4353
|
+
return path6.join(profileDir(cfg.slug), rel);
|
|
3922
4354
|
}
|
|
3923
4355
|
async function listStickers(cfg) {
|
|
3924
4356
|
await libraryPath(cfg);
|
|
@@ -3938,8 +4370,8 @@ async function pickSticker(cfg, mood = "") {
|
|
|
3938
4370
|
}
|
|
3939
4371
|
async function addStickerToLibrary(cfg, fileId, emoji = "", tags = []) {
|
|
3940
4372
|
await libraryPath(cfg);
|
|
3941
|
-
const p =
|
|
3942
|
-
await
|
|
4373
|
+
const p = path6.join(profileDir(cfg.slug), "stickers/library.md");
|
|
4374
|
+
await fs5.appendFile(p, `${fileId} | ${emoji} | ${tags.join(",")}
|
|
3943
4375
|
`, "utf8");
|
|
3944
4376
|
}
|
|
3945
4377
|
var DEFAULT_LIBRARY;
|
|
@@ -4642,6 +5074,7 @@ var init_runtime = __esm({
|
|
|
4642
5074
|
init_conflict();
|
|
4643
5075
|
init_daily_summarizer();
|
|
4644
5076
|
init_realism();
|
|
5077
|
+
init_memory_palace();
|
|
4645
5078
|
init_media();
|
|
4646
5079
|
init_security();
|
|
4647
5080
|
init_stickers();
|
|
@@ -4839,7 +5272,7 @@ var init_runtime = __esm({
|
|
|
4839
5272
|
async historyFor(key, fromId, restore = false) {
|
|
4840
5273
|
const existing = this.histories.get(key);
|
|
4841
5274
|
if (existing) return existing;
|
|
4842
|
-
const restored = restore ? await readRecentSessionTurns(this.cfg.slug, this.cfg.tz, fromId,
|
|
5275
|
+
const restored = restore ? await readRecentSessionTurns(this.cfg.slug, this.cfg.tz, fromId, 80) : [];
|
|
4843
5276
|
const hist = restored.map((t) => ({ role: t.role, content: t.content, ts: t.ts }));
|
|
4844
5277
|
this.histories.set(key, hist);
|
|
4845
5278
|
this.hydratePresenceTrackers(key, hist);
|
|
@@ -5097,6 +5530,8 @@ ${m.text}` : media;
|
|
|
5097
5530
|
}
|
|
5098
5531
|
const made = await closeStaleSessions(this.llm, this.cfg);
|
|
5099
5532
|
if (made > 0) this.emit("event", { type: "info", text: `daily summaries: +${made}` });
|
|
5533
|
+
const mined = await mineUnminedDailyLogs(this.llm, this.cfg, 2).catch(() => 0);
|
|
5534
|
+
if (mined > 0) this.emit("event", { type: "info", text: `memory palace drawers: +${mined}` });
|
|
5100
5535
|
}
|
|
5101
5536
|
/**
|
|
5102
5537
|
* Issue #81 — периодически выставляет статус «онлайн» в Telegram
|
|
@@ -5343,6 +5778,8 @@ ${m.text}` : media;
|
|
|
5343
5778
|
}
|
|
5344
5779
|
this.emit("event", { type: "ignored", text: incomingText, reason: tick.ignoreReason ?? tick.intent });
|
|
5345
5780
|
await appendSessionLog(this.cfg.slug, this.cfg.tz, ` -> ignored (${tick.intent}: ${tick.ignoreReason ?? ""})`);
|
|
5781
|
+
recordInteractionMemory(this.llm, this.cfg, incomingText).catch(() => {
|
|
5782
|
+
});
|
|
5346
5783
|
return;
|
|
5347
5784
|
}
|
|
5348
5785
|
let delaySec = tick.delaySec;
|
|
@@ -5382,7 +5819,7 @@ intent=${tick.intent}
|
|
|
5382
5819
|
\u043A\u043E\u043B-\u0432\u043E \u043F\u0443\u0437\u044B\u0440\u0435\u0439: ${tick.bubbles}${presenceHint ? `
|
|
5383
5820
|
\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E\u0441\u0442\u044C: ${presenceHint}` : ""}
|
|
5384
5821
|
${tick.intent === "short" ? "\u041E\u0442\u0432\u0435\u0447\u0430\u0439 \u043E\u0434\u043D\u043E\u0441\u043B\u043E\u0436\u043D\u043E: '\u043E\u043A', '\u044F\u0441\u043D\u043E', '\u0438?', '\u043D\u0443 \u043E\u043A'. \u0411\u0435\u0437 \u043E\u0431\u044A\u044F\u0441\u043D\u0435\u043D\u0438\u0439." : tick.bubbles > 1 ? "\u0420\u0430\u0437\u0431\u0435\u0439 \u043E\u0442\u0432\u0435\u0442 \u043D\u0430 \u043F\u0443\u0437\u044B\u0440\u0438 \u0421\u0422\u0420\u041E\u0413\u041E \u0441\u0442\u0440\u043E\u043A\u043E\u0439 '---' (\u0442\u0440\u0438 \u0434\u0435\u0444\u0438\u0441\u0430 \u043D\u0430 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u0435) \u043C\u0435\u0436\u0434\u0443 \u043D\u0438\u043C\u0438. \u041A\u0410\u0416\u0414\u042B\u0419 \u043F\u0443\u0437\u044B\u0440\u044C \u2014 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0432 \u0442\u0433. \u0417\u0410\u041F\u0420\u0415\u0429\u0415\u041D\u041E \u0440\u0430\u0441\u043A\u0438\u0434\u044B\u0432\u0430\u0442\u044C \u043E\u0434\u043D\u043E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043D\u0430 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u0442\u0440\u043E\u043A \u0447\u0435\u0440\u0435\u0437 \u043F\u0435\u0440\u0435\u043D\u043E\u0441 \u0441\u0442\u0440\u043E\u043A\u0438 \u0431\u0435\u0437 '---' \u2014 \u0432 \u0442\u0433 \u044D\u0442\u043E \u0432\u044B\u0433\u043B\u044F\u0434\u0438\u0442 \u043A\u0430\u043A \u043E\u0434\u043D\u043E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0432 \u0441\u0442\u043E\u043B\u0431\u0438\u043A, \u0447\u0442\u043E \u043F\u0430\u043B\u0438\u0442 \u0418\u0418. \u041F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E:\\n\\n\u043F\u0440\u0438\u0432\u0435\u0442\\n---\\n\u043A\u0430\u043A \u0441\u0430\u043C\\n\\n\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E:\\n\\n\u043F\u0440\u0438\u0432\u0435\u0442\\n\u043A\u0430\u043A \u0441\u0430\u043C" : "\u041E\u0434\u0438\u043D \u043A\u043E\u0440\u043E\u0442\u043A\u0438\u0439 \u043E\u0442\u0432\u0435\u0442, \u0431\u0435\u0437 '---'."}${scopeHint}` },
|
|
5385
|
-
...hist.slice(-
|
|
5822
|
+
...hist.slice(-60).map((t) => ({ role: t.role, content: t.content }))
|
|
5386
5823
|
];
|
|
5387
5824
|
const image = imagePartFromMedia(incoming?.media);
|
|
5388
5825
|
if (image) {
|
|
@@ -6250,22 +6687,41 @@ ${persona}`;
|
|
|
6250
6687
|
}
|
|
6251
6688
|
});
|
|
6252
6689
|
|
|
6690
|
+
// src/migrations/0114-memory-palace.ts
|
|
6691
|
+
var migration0114;
|
|
6692
|
+
var init_memory_palace2 = __esm({
|
|
6693
|
+
"src/migrations/0114-memory-palace.ts"() {
|
|
6694
|
+
"use strict";
|
|
6695
|
+
init_esm_shims();
|
|
6696
|
+
init_memory_palace();
|
|
6697
|
+
migration0114 = {
|
|
6698
|
+
id: "0114-memory-palace",
|
|
6699
|
+
description: "\u041F\u0435\u0440\u0435\u043D\u0435\u0441\u0442\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0444\u0430\u0439\u043B\u044B \u043F\u0430\u043C\u044F\u0442\u0438 \u0432 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0443 Memory Palace",
|
|
6700
|
+
async migrate(ctx) {
|
|
6701
|
+
const made = await migrateExistingMemoryToPalace(ctx.config);
|
|
6702
|
+
if (made > 0) ctx.log(`memory palace drawers: +${made}`);
|
|
6703
|
+
return ctx.config;
|
|
6704
|
+
}
|
|
6705
|
+
};
|
|
6706
|
+
}
|
|
6707
|
+
});
|
|
6708
|
+
|
|
6253
6709
|
// src/migrations/index.ts
|
|
6254
|
-
import { promises as
|
|
6255
|
-
import
|
|
6710
|
+
import { promises as fs6 } from "fs";
|
|
6711
|
+
import path7 from "path";
|
|
6256
6712
|
import { readFileSync } from "fs";
|
|
6257
6713
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6258
6714
|
async function readMigrationState() {
|
|
6259
6715
|
try {
|
|
6260
|
-
const raw = await
|
|
6716
|
+
const raw = await fs6.readFile(MIGRATIONS_FILE(), "utf8");
|
|
6261
6717
|
return JSON.parse(raw);
|
|
6262
6718
|
} catch {
|
|
6263
6719
|
return { appliedMigrations: [], lastRunVersion: "0.0.0", lastRunAt: "" };
|
|
6264
6720
|
}
|
|
6265
6721
|
}
|
|
6266
6722
|
async function writeMigrationState(state) {
|
|
6267
|
-
await
|
|
6268
|
-
await
|
|
6723
|
+
await fs6.mkdir(DATA_ROOT, { recursive: true });
|
|
6724
|
+
await fs6.writeFile(MIGRATIONS_FILE(), JSON.stringify(state, null, 2), "utf8");
|
|
6269
6725
|
}
|
|
6270
6726
|
async function pendingMigrations() {
|
|
6271
6727
|
const state = await readMigrationState();
|
|
@@ -6358,15 +6814,15 @@ function formatUpdateWarnings(warnings) {
|
|
|
6358
6814
|
function currentVersion() {
|
|
6359
6815
|
try {
|
|
6360
6816
|
const here = fileURLToPath3(import.meta.url);
|
|
6361
|
-
let dir =
|
|
6817
|
+
let dir = path7.dirname(here);
|
|
6362
6818
|
for (let i = 0; i < 5; i++) {
|
|
6363
|
-
const candidate =
|
|
6819
|
+
const candidate = path7.join(dir, "package.json");
|
|
6364
6820
|
try {
|
|
6365
6821
|
const pkg = JSON.parse(readFileSync(candidate, "utf8"));
|
|
6366
6822
|
if (pkg.name === "@thesashadev/girl-agent" && pkg.version) return pkg.version;
|
|
6367
6823
|
} catch {
|
|
6368
6824
|
}
|
|
6369
|
-
dir =
|
|
6825
|
+
dir = path7.dirname(dir);
|
|
6370
6826
|
}
|
|
6371
6827
|
return "unknown";
|
|
6372
6828
|
} catch {
|
|
@@ -6381,10 +6837,12 @@ var init_migrations = __esm({
|
|
|
6381
6837
|
init_md();
|
|
6382
6838
|
init_add_use_wss_default();
|
|
6383
6839
|
init_ensure_communication_md();
|
|
6384
|
-
|
|
6840
|
+
init_memory_palace2();
|
|
6841
|
+
MIGRATIONS_FILE = () => path7.join(DATA_ROOT, ".migrations.json");
|
|
6385
6842
|
ALL_MIGRATIONS = [
|
|
6386
6843
|
migration0112,
|
|
6387
|
-
migration0113
|
|
6844
|
+
migration0113,
|
|
6845
|
+
migration0114
|
|
6388
6846
|
];
|
|
6389
6847
|
}
|
|
6390
6848
|
});
|
|
@@ -6542,23 +7000,23 @@ __export(addons_exports, {
|
|
|
6542
7000
|
updateSettings: () => updateSettings,
|
|
6543
7001
|
validateManifest: () => validateManifest
|
|
6544
7002
|
});
|
|
6545
|
-
import { promises as
|
|
6546
|
-
import
|
|
7003
|
+
import { promises as fs9 } from "fs";
|
|
7004
|
+
import path10 from "path";
|
|
6547
7005
|
import os3 from "os";
|
|
6548
7006
|
import { execFile } from "child_process";
|
|
6549
7007
|
import { promisify } from "util";
|
|
6550
7008
|
function addonsDir() {
|
|
6551
|
-
const root = process.env.GIRL_AGENT_DATA ?
|
|
6552
|
-
return
|
|
7009
|
+
const root = process.env.GIRL_AGENT_DATA ? path10.resolve(process.env.GIRL_AGENT_DATA, "..") : path10.join(os3.homedir(), ".local", "share", "girl-agent");
|
|
7010
|
+
return path10.join(root, "addons");
|
|
6553
7011
|
}
|
|
6554
7012
|
async function ensureDir() {
|
|
6555
7013
|
const dir = addonsDir();
|
|
6556
|
-
await
|
|
7014
|
+
await fs9.mkdir(dir, { recursive: true });
|
|
6557
7015
|
return dir;
|
|
6558
7016
|
}
|
|
6559
7017
|
async function readJsonOrEmpty(p, fallback) {
|
|
6560
7018
|
try {
|
|
6561
|
-
const raw = await
|
|
7019
|
+
const raw = await fs9.readFile(p, "utf8");
|
|
6562
7020
|
return JSON.parse(raw);
|
|
6563
7021
|
} catch {
|
|
6564
7022
|
return fallback;
|
|
@@ -6566,12 +7024,12 @@ async function readJsonOrEmpty(p, fallback) {
|
|
|
6566
7024
|
}
|
|
6567
7025
|
async function listInstalled() {
|
|
6568
7026
|
const dir = await ensureDir();
|
|
6569
|
-
const indexPath =
|
|
7027
|
+
const indexPath = path10.join(dir, "installed.json");
|
|
6570
7028
|
return await readJsonOrEmpty(indexPath, []);
|
|
6571
7029
|
}
|
|
6572
7030
|
async function writeInstalled(list) {
|
|
6573
7031
|
const dir = await ensureDir();
|
|
6574
|
-
await
|
|
7032
|
+
await fs9.writeFile(path10.join(dir, "installed.json"), JSON.stringify(list, null, 2), "utf8");
|
|
6575
7033
|
}
|
|
6576
7034
|
async function fetchRegistry() {
|
|
6577
7035
|
try {
|
|
@@ -6585,17 +7043,17 @@ async function fetchRegistry() {
|
|
|
6585
7043
|
}
|
|
6586
7044
|
}
|
|
6587
7045
|
async function unpackGaa(gaaPath) {
|
|
6588
|
-
const tmpDir =
|
|
6589
|
-
await
|
|
7046
|
+
const tmpDir = path10.join(os3.tmpdir(), `gaa-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
7047
|
+
await fs9.mkdir(tmpDir, { recursive: true });
|
|
6590
7048
|
await execFileAsync("unzip", ["-o", "-q", gaaPath, "-d", tmpDir]);
|
|
6591
|
-
const entries = await
|
|
7049
|
+
const entries = await fs9.readdir(tmpDir);
|
|
6592
7050
|
if (entries.length === 1) {
|
|
6593
|
-
const sub =
|
|
6594
|
-
const st = await
|
|
7051
|
+
const sub = path10.join(tmpDir, entries[0]);
|
|
7052
|
+
const st = await fs9.stat(sub);
|
|
6595
7053
|
if (st.isDirectory()) {
|
|
6596
|
-
const innerManifest =
|
|
7054
|
+
const innerManifest = path10.join(sub, "manifest.json");
|
|
6597
7055
|
try {
|
|
6598
|
-
await
|
|
7056
|
+
await fs9.access(innerManifest);
|
|
6599
7057
|
return sub;
|
|
6600
7058
|
} catch {
|
|
6601
7059
|
}
|
|
@@ -6604,34 +7062,34 @@ async function unpackGaa(gaaPath) {
|
|
|
6604
7062
|
return tmpDir;
|
|
6605
7063
|
}
|
|
6606
7064
|
async function packGaa(addonDir, outputPath) {
|
|
6607
|
-
const manifestPath =
|
|
6608
|
-
const manifestRaw = await
|
|
7065
|
+
const manifestPath = path10.join(addonDir, "manifest.json");
|
|
7066
|
+
const manifestRaw = await fs9.readFile(manifestPath, "utf8");
|
|
6609
7067
|
const manifest = JSON.parse(manifestRaw);
|
|
6610
7068
|
validateManifest(manifest);
|
|
6611
|
-
const out = outputPath ??
|
|
7069
|
+
const out = outputPath ?? path10.join(process.cwd(), `${manifest.id}.gaa`);
|
|
6612
7070
|
try {
|
|
6613
|
-
await
|
|
7071
|
+
await fs9.unlink(out);
|
|
6614
7072
|
} catch {
|
|
6615
7073
|
}
|
|
6616
|
-
const dirName =
|
|
6617
|
-
const parentDir =
|
|
7074
|
+
const dirName = path10.basename(addonDir);
|
|
7075
|
+
const parentDir = path10.dirname(addonDir);
|
|
6618
7076
|
await execFileAsync("zip", ["-r", "-q", out, dirName], { cwd: parentDir });
|
|
6619
7077
|
return out;
|
|
6620
7078
|
}
|
|
6621
7079
|
async function installFromDir(addonDir, profileSlug, source = "local") {
|
|
6622
|
-
const manifestPath =
|
|
6623
|
-
const manifestRaw = await
|
|
7080
|
+
const manifestPath = path10.join(addonDir, "manifest.json");
|
|
7081
|
+
const manifestRaw = await fs9.readFile(manifestPath, "utf8");
|
|
6624
7082
|
const manifest = JSON.parse(manifestRaw);
|
|
6625
7083
|
validateManifest(manifest);
|
|
6626
7084
|
const applied = [];
|
|
6627
7085
|
const installedFiles = [];
|
|
6628
|
-
const filesDir =
|
|
7086
|
+
const filesDir = path10.join(addonDir, "files");
|
|
6629
7087
|
try {
|
|
6630
|
-
const fileStat = await
|
|
7088
|
+
const fileStat = await fs9.stat(filesDir);
|
|
6631
7089
|
if (fileStat.isDirectory() && profileSlug) {
|
|
6632
7090
|
const fileEntries = await walkDir(filesDir);
|
|
6633
7091
|
for (const relPath of fileEntries) {
|
|
6634
|
-
const content = await
|
|
7092
|
+
const content = await fs9.readFile(path10.join(filesDir, relPath), "utf8");
|
|
6635
7093
|
await writeMd(profileSlug, relPath, content);
|
|
6636
7094
|
installedFiles.push(relPath);
|
|
6637
7095
|
}
|
|
@@ -6639,9 +7097,9 @@ async function installFromDir(addonDir, profileSlug, source = "local") {
|
|
|
6639
7097
|
}
|
|
6640
7098
|
} catch {
|
|
6641
7099
|
}
|
|
6642
|
-
const patchPath =
|
|
7100
|
+
const patchPath = path10.join(addonDir, "config.patch.json");
|
|
6643
7101
|
try {
|
|
6644
|
-
const patchRaw = await
|
|
7102
|
+
const patchRaw = await fs9.readFile(patchPath, "utf8");
|
|
6645
7103
|
const patch = JSON.parse(patchRaw);
|
|
6646
7104
|
if (profileSlug) {
|
|
6647
7105
|
const cfg = await readConfig(profileSlug);
|
|
@@ -6653,11 +7111,11 @@ async function installFromDir(addonDir, profileSlug, source = "local") {
|
|
|
6653
7111
|
}
|
|
6654
7112
|
} catch {
|
|
6655
7113
|
}
|
|
6656
|
-
const codePatchPath =
|
|
7114
|
+
const codePatchPath = path10.join(addonDir, "code.patch");
|
|
6657
7115
|
try {
|
|
6658
|
-
const patchContent = await
|
|
7116
|
+
const patchContent = await fs9.readFile(codePatchPath, "utf8");
|
|
6659
7117
|
if (patchContent.trim()) {
|
|
6660
|
-
const projectRoot =
|
|
7118
|
+
const projectRoot = path10.resolve(import.meta.url.replace("file://", ""), "../../../");
|
|
6661
7119
|
try {
|
|
6662
7120
|
await execFileAsync("git", ["apply", "--check", codePatchPath], { cwd: projectRoot });
|
|
6663
7121
|
await execFileAsync("git", ["apply", codePatchPath], { cwd: projectRoot });
|
|
@@ -6668,25 +7126,25 @@ async function installFromDir(addonDir, profileSlug, source = "local") {
|
|
|
6668
7126
|
}
|
|
6669
7127
|
} catch {
|
|
6670
7128
|
}
|
|
6671
|
-
const themePath =
|
|
7129
|
+
const themePath = path10.join(addonDir, "theme.css");
|
|
6672
7130
|
try {
|
|
6673
|
-
const css = await
|
|
7131
|
+
const css = await fs9.readFile(themePath, "utf8");
|
|
6674
7132
|
const dir2 = await ensureDir();
|
|
6675
|
-
await
|
|
7133
|
+
await fs9.writeFile(path10.join(dir2, `theme-${manifest.id}.css`), css, "utf8");
|
|
6676
7134
|
applied.push("\u0442\u0435\u043C\u0430 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0430");
|
|
6677
7135
|
} catch {
|
|
6678
7136
|
}
|
|
6679
7137
|
const dir = await ensureDir();
|
|
6680
|
-
const addonStorePath =
|
|
6681
|
-
await
|
|
6682
|
-
await
|
|
7138
|
+
const addonStorePath = path10.join(dir, manifest.id);
|
|
7139
|
+
await fs9.mkdir(addonStorePath, { recursive: true });
|
|
7140
|
+
await fs9.copyFile(manifestPath, path10.join(addonStorePath, "manifest.json"));
|
|
6683
7141
|
const allFiles = await walkDir(addonDir);
|
|
6684
7142
|
for (const f of allFiles) {
|
|
6685
7143
|
if (f === "manifest.json") continue;
|
|
6686
|
-
const src =
|
|
6687
|
-
const dst =
|
|
6688
|
-
await
|
|
6689
|
-
await
|
|
7144
|
+
const src = path10.join(addonDir, f);
|
|
7145
|
+
const dst = path10.join(addonStorePath, f);
|
|
7146
|
+
await fs9.mkdir(path10.dirname(dst), { recursive: true });
|
|
7147
|
+
await fs9.copyFile(src, dst);
|
|
6690
7148
|
}
|
|
6691
7149
|
const list = await listInstalled();
|
|
6692
7150
|
const item = {
|
|
@@ -6707,7 +7165,7 @@ async function installFromGaa(gaaPath, profileSlug) {
|
|
|
6707
7165
|
try {
|
|
6708
7166
|
return await installFromDir(dir, profileSlug, "file");
|
|
6709
7167
|
} finally {
|
|
6710
|
-
await
|
|
7168
|
+
await fs9.rm(dir, { recursive: true, force: true }).catch(() => {
|
|
6711
7169
|
});
|
|
6712
7170
|
}
|
|
6713
7171
|
}
|
|
@@ -6730,12 +7188,12 @@ async function installFromRegistry(id, registryManifest, profileSlug) {
|
|
|
6730
7188
|
const res = await fetch(url, { signal: AbortSignal.timeout(3e4) });
|
|
6731
7189
|
if (!res.ok) throw new Error(`\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u0430\u0434\u0434\u043E\u043D: HTTP ${res.status}`);
|
|
6732
7190
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
6733
|
-
const tmpGaa =
|
|
6734
|
-
await
|
|
7191
|
+
const tmpGaa = path10.join(os3.tmpdir(), `${id}-${Date.now()}.gaa`);
|
|
7192
|
+
await fs9.writeFile(tmpGaa, buf);
|
|
6735
7193
|
try {
|
|
6736
7194
|
return await installFromGaa(tmpGaa, profileSlug);
|
|
6737
7195
|
} finally {
|
|
6738
|
-
await
|
|
7196
|
+
await fs9.unlink(tmpGaa).catch(() => {
|
|
6739
7197
|
});
|
|
6740
7198
|
}
|
|
6741
7199
|
}
|
|
@@ -6744,11 +7202,11 @@ async function uninstall(id) {
|
|
|
6744
7202
|
const next = list.filter((a) => a.manifest.id !== id);
|
|
6745
7203
|
if (next.length === list.length) return false;
|
|
6746
7204
|
const dir = addonsDir();
|
|
6747
|
-
const addonStore =
|
|
6748
|
-
await
|
|
7205
|
+
const addonStore = path10.join(dir, id);
|
|
7206
|
+
await fs9.rm(addonStore, { recursive: true, force: true }).catch(() => {
|
|
6749
7207
|
});
|
|
6750
|
-
const themePath =
|
|
6751
|
-
await
|
|
7208
|
+
const themePath = path10.join(dir, `theme-${id}.css`);
|
|
7209
|
+
await fs9.unlink(themePath).catch(() => {
|
|
6752
7210
|
});
|
|
6753
7211
|
await writeInstalled(next);
|
|
6754
7212
|
return true;
|
|
@@ -6779,11 +7237,11 @@ function validateManifest(m) {
|
|
|
6779
7237
|
}
|
|
6780
7238
|
async function walkDir(dir, prefix = "") {
|
|
6781
7239
|
const result = [];
|
|
6782
|
-
const entries = await
|
|
7240
|
+
const entries = await fs9.readdir(dir, { withFileTypes: true });
|
|
6783
7241
|
for (const e of entries) {
|
|
6784
7242
|
const rel = prefix ? `${prefix}/${e.name}` : e.name;
|
|
6785
7243
|
if (e.isDirectory()) {
|
|
6786
|
-
result.push(...await walkDir(
|
|
7244
|
+
result.push(...await walkDir(path10.join(dir, e.name), rel));
|
|
6787
7245
|
} else {
|
|
6788
7246
|
result.push(rel);
|
|
6789
7247
|
}
|
|
@@ -6803,16 +7261,16 @@ function deepMerge(target, source) {
|
|
|
6803
7261
|
}
|
|
6804
7262
|
async function getAddonReadme(id) {
|
|
6805
7263
|
const dir = addonsDir();
|
|
6806
|
-
const readmePath =
|
|
7264
|
+
const readmePath = path10.join(dir, id, "README.md");
|
|
6807
7265
|
try {
|
|
6808
|
-
return await
|
|
7266
|
+
return await fs9.readFile(readmePath, "utf8");
|
|
6809
7267
|
} catch {
|
|
6810
7268
|
return null;
|
|
6811
7269
|
}
|
|
6812
7270
|
}
|
|
6813
7271
|
async function getAddonFiles(id) {
|
|
6814
7272
|
const dir = addonsDir();
|
|
6815
|
-
const addonDir =
|
|
7273
|
+
const addonDir = path10.join(dir, id);
|
|
6816
7274
|
try {
|
|
6817
7275
|
return await walkDir(addonDir);
|
|
6818
7276
|
} catch {
|
|
@@ -6855,9 +7313,9 @@ var HttpError = class extends Error {
|
|
|
6855
7313
|
};
|
|
6856
7314
|
var Router = class {
|
|
6857
7315
|
routes = [];
|
|
6858
|
-
add(method,
|
|
7316
|
+
add(method, path13, handler) {
|
|
6859
7317
|
const paramNames = [];
|
|
6860
|
-
const parts =
|
|
7318
|
+
const parts = path13.split("/").map((part) => {
|
|
6861
7319
|
if (part.startsWith(":")) {
|
|
6862
7320
|
paramNames.push(part.slice(1));
|
|
6863
7321
|
return "([^/]+)";
|
|
@@ -6872,20 +7330,20 @@ var Router = class {
|
|
|
6872
7330
|
handler
|
|
6873
7331
|
});
|
|
6874
7332
|
}
|
|
6875
|
-
get(
|
|
6876
|
-
this.add("GET",
|
|
7333
|
+
get(path13, h) {
|
|
7334
|
+
this.add("GET", path13, h);
|
|
6877
7335
|
}
|
|
6878
|
-
post(
|
|
6879
|
-
this.add("POST",
|
|
7336
|
+
post(path13, h) {
|
|
7337
|
+
this.add("POST", path13, h);
|
|
6880
7338
|
}
|
|
6881
|
-
put(
|
|
6882
|
-
this.add("PUT",
|
|
7339
|
+
put(path13, h) {
|
|
7340
|
+
this.add("PUT", path13, h);
|
|
6883
7341
|
}
|
|
6884
|
-
delete(
|
|
6885
|
-
this.add("DELETE",
|
|
7342
|
+
delete(path13, h) {
|
|
7343
|
+
this.add("DELETE", path13, h);
|
|
6886
7344
|
}
|
|
6887
|
-
patch(
|
|
6888
|
-
this.add("PATCH",
|
|
7345
|
+
patch(path13, h) {
|
|
7346
|
+
this.add("PATCH", path13, h);
|
|
6889
7347
|
}
|
|
6890
7348
|
match(method, pathname) {
|
|
6891
7349
|
for (const r of this.routes) {
|
|
@@ -7377,25 +7835,31 @@ function fallbackBusySchedule(name, age) {
|
|
|
7377
7835
|
init_llm();
|
|
7378
7836
|
init_llm_update();
|
|
7379
7837
|
init_llm2();
|
|
7380
|
-
import { promises as
|
|
7381
|
-
import
|
|
7838
|
+
import { promises as fs7 } from "fs";
|
|
7839
|
+
import path8 from "path";
|
|
7382
7840
|
var MEMORY_FILES = [
|
|
7383
7841
|
"persona.md",
|
|
7384
7842
|
"speech.md",
|
|
7385
7843
|
"boundaries.md",
|
|
7386
7844
|
"communication.md",
|
|
7387
7845
|
"long-term.md",
|
|
7388
|
-
"memory/long-term.md"
|
|
7846
|
+
"memory/long-term.md",
|
|
7847
|
+
"memory/facts.md",
|
|
7848
|
+
"memory/uncertain.md",
|
|
7849
|
+
"relationship/timeline.md",
|
|
7850
|
+
"time/open-loops.md",
|
|
7851
|
+
"time/promises.md"
|
|
7389
7852
|
];
|
|
7390
7853
|
function isAllowedMemoryPath(p) {
|
|
7391
7854
|
if (!p || typeof p !== "string") return false;
|
|
7392
7855
|
if (p.includes("..")) return false;
|
|
7393
|
-
if (
|
|
7856
|
+
if (path8.isAbsolute(p)) return false;
|
|
7394
7857
|
if (p.startsWith("config.json")) return false;
|
|
7395
7858
|
if (p.startsWith("agenda.json")) return false;
|
|
7396
7859
|
if (MEMORY_FILES.includes(p)) return true;
|
|
7397
7860
|
if (/^memory\/daily\/\d{4}-\d{2}-\d{2}\.md$/.test(p)) return true;
|
|
7398
7861
|
if (/^memory\/episodes\/[\w\-]{1,80}\.md$/.test(p)) return true;
|
|
7862
|
+
if (/^memory\/palace\/[\w\-]{1,80}\/[\w\-]{1,80}\/[\w\-]{1,80}\/[\w\-]{1,120}\.md$/.test(p)) return true;
|
|
7399
7863
|
if (/^log\/\d{4}-\d{2}-\d{2}\.md$/.test(p)) return true;
|
|
7400
7864
|
return false;
|
|
7401
7865
|
}
|
|
@@ -7565,20 +8029,40 @@ function registerProfileRoutes(r) {
|
|
|
7565
8029
|
const entries = [];
|
|
7566
8030
|
for (const f of MEMORY_FILES) entries.push({ rel: f });
|
|
7567
8031
|
try {
|
|
7568
|
-
const dailyDir =
|
|
7569
|
-
const list = await
|
|
8032
|
+
const dailyDir = path8.join(dir, "memory", "daily");
|
|
8033
|
+
const list = await fs7.readdir(dailyDir);
|
|
7570
8034
|
for (const f of list) if (/^\d{4}-\d{2}-\d{2}\.md$/.test(f)) entries.push({ rel: `memory/daily/${f}` });
|
|
7571
8035
|
} catch {
|
|
7572
8036
|
}
|
|
7573
8037
|
try {
|
|
7574
|
-
const epDir =
|
|
7575
|
-
const list = await
|
|
8038
|
+
const epDir = path8.join(dir, "memory", "episodes");
|
|
8039
|
+
const list = await fs7.readdir(epDir);
|
|
7576
8040
|
for (const f of list) if (/^[\w\-]{1,80}\.md$/.test(f)) entries.push({ rel: `memory/episodes/${f}` });
|
|
7577
8041
|
} catch {
|
|
7578
8042
|
}
|
|
8043
|
+
try {
|
|
8044
|
+
const palaceDir = path8.join(dir, "memory", "palace");
|
|
8045
|
+
const wings = await fs7.readdir(palaceDir, { withFileTypes: true });
|
|
8046
|
+
for (const wing of wings) {
|
|
8047
|
+
if (!wing.isDirectory() || !/^[\w\-]{1,80}$/.test(wing.name)) continue;
|
|
8048
|
+
const halls = await fs7.readdir(path8.join(palaceDir, wing.name), { withFileTypes: true });
|
|
8049
|
+
for (const hall of halls) {
|
|
8050
|
+
if (!hall.isDirectory() || !/^[\w\-]{1,80}$/.test(hall.name)) continue;
|
|
8051
|
+
const rooms = await fs7.readdir(path8.join(palaceDir, wing.name, hall.name), { withFileTypes: true });
|
|
8052
|
+
for (const room of rooms) {
|
|
8053
|
+
if (!room.isDirectory() || !/^[\w\-]{1,80}$/.test(room.name)) continue;
|
|
8054
|
+
const drawers = await fs7.readdir(path8.join(palaceDir, wing.name, hall.name, room.name));
|
|
8055
|
+
for (const drawer of drawers) {
|
|
8056
|
+
if (/^[\w\-]{1,120}\.md$/.test(drawer)) entries.push({ rel: `memory/palace/${wing.name}/${hall.name}/${room.name}/${drawer}` });
|
|
8057
|
+
}
|
|
8058
|
+
}
|
|
8059
|
+
}
|
|
8060
|
+
}
|
|
8061
|
+
} catch {
|
|
8062
|
+
}
|
|
7579
8063
|
for (const e of entries) {
|
|
7580
8064
|
try {
|
|
7581
|
-
const stat = await
|
|
8065
|
+
const stat = await fs7.stat(path8.join(dir, e.rel));
|
|
7582
8066
|
items.push({ path: e.rel, size: stat.size, mtime: stat.mtimeMs });
|
|
7583
8067
|
} catch {
|
|
7584
8068
|
}
|
|
@@ -7947,9 +8431,9 @@ function registerPresetRoutes(r) {
|
|
|
7947
8431
|
// src/webui/routes/system.ts
|
|
7948
8432
|
init_esm_shims();
|
|
7949
8433
|
init_md();
|
|
7950
|
-
import { promises as
|
|
8434
|
+
import { promises as fs8 } from "fs";
|
|
7951
8435
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
7952
|
-
import
|
|
8436
|
+
import path9 from "path";
|
|
7953
8437
|
import os2 from "os";
|
|
7954
8438
|
var cachedVersion = null;
|
|
7955
8439
|
async function readPackageVersion() {
|
|
@@ -7957,15 +8441,15 @@ async function readPackageVersion() {
|
|
|
7957
8441
|
const candidates = [];
|
|
7958
8442
|
try {
|
|
7959
8443
|
const here = fileURLToPath4(import.meta.url);
|
|
7960
|
-
candidates.push(
|
|
7961
|
-
candidates.push(
|
|
7962
|
-
candidates.push(
|
|
8444
|
+
candidates.push(path9.resolve(path9.dirname(here), "..", "package.json"));
|
|
8445
|
+
candidates.push(path9.resolve(path9.dirname(here), "..", "..", "package.json"));
|
|
8446
|
+
candidates.push(path9.resolve(path9.dirname(here), "..", "..", "..", "package.json"));
|
|
7963
8447
|
} catch {
|
|
7964
8448
|
}
|
|
7965
|
-
candidates.push(
|
|
8449
|
+
candidates.push(path9.resolve(process.cwd(), "package.json"));
|
|
7966
8450
|
for (const c of candidates) {
|
|
7967
8451
|
try {
|
|
7968
|
-
const raw = await
|
|
8452
|
+
const raw = await fs8.readFile(c, "utf8");
|
|
7969
8453
|
const parsed = JSON.parse(raw);
|
|
7970
8454
|
if (parsed.name === "@thesashadev/girl-agent" && parsed.version) {
|
|
7971
8455
|
cachedVersion = parsed.version;
|
|
@@ -8016,8 +8500,8 @@ function registerSystemRoutes(r) {
|
|
|
8016
8500
|
// src/webui/routes/addons.ts
|
|
8017
8501
|
init_esm_shims();
|
|
8018
8502
|
init_addons();
|
|
8019
|
-
import { promises as
|
|
8020
|
-
import
|
|
8503
|
+
import { promises as fs10 } from "fs";
|
|
8504
|
+
import path11 from "path";
|
|
8021
8505
|
import os4 from "os";
|
|
8022
8506
|
function registerAddonRoutes(r) {
|
|
8023
8507
|
r.get("/api/addons", async () => {
|
|
@@ -8044,13 +8528,13 @@ function registerAddonRoutes(r) {
|
|
|
8044
8528
|
const data = body;
|
|
8045
8529
|
if (!data?.gaaBase64) throw new HttpError(400, "gaaBase64 required");
|
|
8046
8530
|
const buf = Buffer.from(data.gaaBase64, "base64");
|
|
8047
|
-
const tmpPath =
|
|
8048
|
-
await
|
|
8531
|
+
const tmpPath = path11.join(os4.tmpdir(), `upload-${Date.now()}.gaa`);
|
|
8532
|
+
await fs10.writeFile(tmpPath, buf);
|
|
8049
8533
|
try {
|
|
8050
8534
|
const result = await installFromGaa(tmpPath, data.profileSlug);
|
|
8051
8535
|
return { ok: true, installed: result.addon, applied: result.applied };
|
|
8052
8536
|
} finally {
|
|
8053
|
-
await
|
|
8537
|
+
await fs10.unlink(tmpPath).catch(() => {
|
|
8054
8538
|
});
|
|
8055
8539
|
}
|
|
8056
8540
|
});
|
|
@@ -8062,13 +8546,13 @@ function registerAddonRoutes(r) {
|
|
|
8062
8546
|
const res = await fetch(url, { signal: AbortSignal.timeout(3e4) });
|
|
8063
8547
|
if (!res.ok) throw new HttpError(502, `fetch failed: HTTP ${res.status}`);
|
|
8064
8548
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
8065
|
-
const tmpPath =
|
|
8066
|
-
await
|
|
8549
|
+
const tmpPath = path11.join(os4.tmpdir(), `url-${Date.now()}.gaa`);
|
|
8550
|
+
await fs10.writeFile(tmpPath, buf);
|
|
8067
8551
|
try {
|
|
8068
8552
|
const result = await installFromGaa(tmpPath, data.profileSlug);
|
|
8069
8553
|
return { ok: true, installed: result.addon, applied: result.applied };
|
|
8070
8554
|
} finally {
|
|
8071
|
-
await
|
|
8555
|
+
await fs10.unlink(tmpPath).catch(() => {
|
|
8072
8556
|
});
|
|
8073
8557
|
}
|
|
8074
8558
|
} else {
|
|
@@ -8115,7 +8599,561 @@ init_llm();
|
|
|
8115
8599
|
init_stages();
|
|
8116
8600
|
init_communication();
|
|
8117
8601
|
init_llm2();
|
|
8602
|
+
init_realism();
|
|
8118
8603
|
init_runtime_bus();
|
|
8604
|
+
|
|
8605
|
+
// src/webui/assistant-knowledge.ts
|
|
8606
|
+
init_esm_shims();
|
|
8607
|
+
init_communication();
|
|
8608
|
+
init_llm2();
|
|
8609
|
+
init_mcp();
|
|
8610
|
+
init_stages();
|
|
8611
|
+
var CORE_KNOWLEDGE_BASE = [
|
|
8612
|
+
{
|
|
8613
|
+
category: "overview",
|
|
8614
|
+
subcategory: "product",
|
|
8615
|
+
title: "\u0427\u0442\u043E \u0442\u0430\u043A\u043E\u0435 girl-agent",
|
|
8616
|
+
keywords: ["\u043F\u0440\u043E\u0435\u043A\u0442", "girl-agent", "\u0431\u043E\u0442", "\u0447\u0442\u043E \u044D\u0442\u043E", "\u043A\u043E\u043D\u0446\u0435\u043F\u0446\u0438\u044F", "\u0430\u0440\u0445\u0438\u0442\u0435\u043A\u0442\u0443\u0440\u0430", "\u0438\u0434\u0435\u044F"],
|
|
8617
|
+
body: "girl-agent \u2014 \u0434\u0432\u0438\u0436\u043E\u043A Telegram-\u043F\u0435\u0440\u0441\u043E\u043D\u044B, \u0430 \u043D\u0435 \u043E\u0431\u044B\u0447\u043D\u044B\u0439 \u0447\u0430\u0442-\u0431\u043E\u0442. \u041E\u043D \u0441\u0438\u043C\u0443\u043B\u0438\u0440\u0443\u0435\u0442 \u0436\u0438\u0432\u043E\u0435 \u043F\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0435 \u0434\u0435\u0432\u0443\u0448\u043A\u0438: \u043E\u043D\u043B\u0430\u0439\u043D/\u043E\u0444\u043B\u0430\u0439\u043D, \u0441\u043E\u043D, \u0437\u0430\u043D\u044F\u0442\u043E\u0441\u0442\u044C, \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043D\u0438\u0435, \u043F\u0430\u043C\u044F\u0442\u044C, \u0441\u0442\u0430\u0434\u0438\u0438 \u043E\u0442\u043D\u043E\u0448\u0435\u043D\u0438\u0439, \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B, \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u0438, \u0440\u0435\u0430\u043A\u0446\u0438\u0438, \u0441\u0442\u0438\u043A\u0435\u0440\u044B, \u043E\u043F\u0435\u0447\u0430\u0442\u043A\u0438 \u0438 \u043F\u0440\u043E\u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F. README \u043F\u0440\u044F\u043C\u043E \u043F\u043E\u0434\u0447\u0451\u0440\u043A\u0438\u0432\u0430\u0435\u0442: \u043E\u043D\u0430 \u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043D\u0430 \u043A\u0430\u0436\u0434\u043E\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435, \u0438\u043D\u043E\u0433\u0434\u0430 \u0447\u0438\u0442\u0430\u0435\u0442 \u0438 \u043C\u043E\u043B\u0447\u0438\u0442 \u2014 \u044D\u0442\u043E \u0437\u0430\u0434\u0443\u043C\u0430\u043D\u043E."
|
|
8618
|
+
},
|
|
8619
|
+
{
|
|
8620
|
+
category: "overview",
|
|
8621
|
+
subcategory: "layers",
|
|
8622
|
+
title: "\u0421\u043B\u043E\u0438\u0441\u0442\u0430\u044F \u0430\u0440\u0445\u0438\u0442\u0435\u043A\u0442\u0443\u0440\u0430",
|
|
8623
|
+
keywords: ["\u0441\u043B\u043E\u0438", "\u0430\u0440\u0445\u0438\u0442\u0435\u043A\u0442\u0443\u0440\u0430", "runtime", "prompt", "behavior", "presence", "memory"],
|
|
8624
|
+
body: "\u041F\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0435 \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u0438\u0437 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u0438\u0445 \u0441\u043B\u043E\u0451\u0432: Telegram adapter \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442 \u0441\u043E\u0431\u044B\u0442\u0438\u044F; Runtime \u043E\u0440\u043A\u0435\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 state; presence \u0440\u0435\u0448\u0430\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E\u0441\u0442\u044C; behavior-tick \u0432\u044B\u0431\u0438\u0440\u0430\u0435\u0442 intent/delay/reaction; prompt \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442 persona/speech/boundaries/relationship/memory; LLM \u043F\u0438\u0448\u0435\u0442 \u0442\u0435\u043A\u0441\u0442; storage \u0444\u0438\u043A\u0441\u0438\u0440\u0443\u0435\u0442 \u043B\u043E\u0433\u0438, score, memory, agenda. \u041F\u043E\u044D\u0442\u043E\u043C\u0443 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0443 \u043D\u0435\u043B\u044C\u0437\u044F \u043E\u0431\u044A\u044F\u0441\u043D\u044F\u0442\u044C \u043E\u0434\u043D\u0438\u043C system prompt \u2014 \u043F\u043E\u0447\u0442\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043D\u0430\u0434\u043E \u0441\u043C\u043E\u0442\u0440\u0435\u0442\u044C \u0441\u043B\u043E\u0439, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0441\u0438\u043C\u043F\u0442\u043E\u043C."
|
|
8625
|
+
},
|
|
8626
|
+
{
|
|
8627
|
+
category: "overview",
|
|
8628
|
+
subcategory: "tech-stack",
|
|
8629
|
+
title: "\u0422\u0435\u0445\u043D\u043E\u043B\u043E\u0433\u0438\u0438 \u043F\u0440\u043E\u0435\u043A\u0442\u0430",
|
|
8630
|
+
keywords: ["\u0441\u0442\u0435\u043A", "typescript", "node", "react", "vite", "grammy", "gramjs", "tsup", "rust", "desktop"],
|
|
8631
|
+
body: "Runtime: Node.js >=20, TypeScript strict, ESM. Build: tsup \u0432 dist/cli.js. WebUI: React + Vite. Telegram: grammY \u0434\u043B\u044F bot mode \u0438 GramJS/telegram \u0434\u043B\u044F userbot. LLM: OpenAI-compatible \u0438 Anthropic SDK. Desktop: Rust/iced \u0432 desktop-rs. \u0418\u043C\u043F\u043E\u0440\u0442\u044B TypeScript \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044E\u0442 .js extension."
|
|
8632
|
+
},
|
|
8633
|
+
{
|
|
8634
|
+
category: "overview",
|
|
8635
|
+
subcategory: "project-structure",
|
|
8636
|
+
title: "\u041A\u0430\u0440\u0442\u0430 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0439",
|
|
8637
|
+
keywords: ["\u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0438", "\u0444\u0430\u0439\u043B\u044B", "\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430", "src", "engine", "webui", "telegram", "storage"],
|
|
8638
|
+
body: "src/engine \u2014 \u044F\u0434\u0440\u043E \u043F\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u044F: runtime, presence, behavior-tick, prompt, memory-palace, conflict, agenda, daily-life. src/telegram \u2014 bot/userbot adapters. src/llm \u2014 \u043A\u043B\u0438\u0435\u043D\u0442\u044B \u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u043E\u0432. src/storage/md.ts \u2014 \u0444\u0430\u0439\u043B\u043E\u0432\u043E\u0435 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u043F\u0440\u043E\u0444\u0438\u043B\u0435\u0439. src/webui \u2014 HTTP API, runtime bus, routes. webui/src \u2014 React \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B. src/presets \u2014 stages, llm, communication, mcp."
|
|
8639
|
+
},
|
|
8640
|
+
{
|
|
8641
|
+
category: "overview",
|
|
8642
|
+
subcategory: "commands",
|
|
8643
|
+
title: "\u041A\u043E\u043C\u0430\u043D\u0434\u044B \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u043A\u0438 \u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0430",
|
|
8644
|
+
keywords: ["\u043A\u043E\u043C\u0430\u043D\u0434\u044B", "npm", "build", "typecheck", "dev", "start", "server", "update", "addon"],
|
|
8645
|
+
body: "\u041E\u0441\u043D\u043E\u0432\u043D\u044B\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u044B: npm install, npm run dev, npm run build, npm run typecheck, npm run start. CLI: npx girl-agent \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u0435\u0442 WebUI; --profile \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u0435\u0442 \u043F\u0440\u043E\u0444\u0438\u043B\u044C; server --print-config/--config/--headless \u0434\u043B\u044F \u0441\u0435\u0440\u0432\u0435\u0440\u043E\u0432; update \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u0435\u0442 data-\u043C\u0438\u0433\u0440\u0430\u0446\u0438\u0438; addon init/pack \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u0441 .gaa \u0430\u0434\u0434\u043E\u043D\u0430\u043C\u0438."
|
|
8646
|
+
},
|
|
8647
|
+
{
|
|
8648
|
+
category: "storage",
|
|
8649
|
+
subcategory: "data-root",
|
|
8650
|
+
title: "\u0413\u0434\u0435 \u043B\u0435\u0436\u0430\u0442 \u0434\u0430\u043D\u043D\u044B\u0435",
|
|
8651
|
+
keywords: ["data", "GIRL_AGENT_DATA", "\u043F\u0430\u043F\u043A\u0430", "\u043F\u0440\u043E\u0444\u0438\u043B\u0438", "windows", "macos", "linux", "\u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435"],
|
|
8652
|
+
body: "\u041A\u043E\u0440\u0435\u043D\u044C \u043F\u0440\u043E\u0444\u0438\u043B\u0435\u0439 \u0431\u0435\u0440\u0451\u0442\u0441\u044F \u0438\u0437 GIRL_AGENT_DATA, \u0438\u043D\u0430\u0447\u0435 \u0432 \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u0430\u0445 \u044D\u0442\u043E ./data, \u0432 npm/global \u0437\u0430\u043F\u0443\u0441\u043A\u0435 \u2014 XDG data dir, \u043D\u0430 Windows %APPDATA%/girl-agent/data, \u043D\u0430 macOS ~/Library/Application Support/girl-agent/data. \u041A\u0430\u0436\u0434\u044B\u0439 \u043F\u0440\u043E\u0444\u0438\u043B\u044C \u0436\u0438\u0432\u0451\u0442 \u0432 data/<slug>/."
|
|
8653
|
+
},
|
|
8654
|
+
{
|
|
8655
|
+
category: "storage",
|
|
8656
|
+
subcategory: "profile-files",
|
|
8657
|
+
title: "\u0424\u0430\u0439\u043B\u044B \u043F\u0440\u043E\u0444\u0438\u043B\u044F",
|
|
8658
|
+
keywords: ["config.json", "persona.md", "speech.md", "boundaries.md", "communication.md", "relationship.md", "agenda.json"],
|
|
8659
|
+
body: "config.json \u0445\u0440\u0430\u043D\u0438\u0442 ProfileConfig. persona.md \u2014 \u043B\u0438\u0447\u043D\u043E\u0441\u0442\u044C, speech.md \u2014 \u0440\u0435\u0447\u044C, boundaries.md \u2014 \u0433\u0440\u0430\u043D\u0438\u0446\u044B, communication.md \u2014 \u0441\u0442\u0438\u043B\u044C \u043E\u0431\u0449\u0435\u043D\u0438\u044F. relationship.md \u0445\u0440\u0430\u043D\u0438\u0442 stage \u0438 score. agenda.json \u2014 \u0431\u0443\u0434\u0443\u0449\u0438\u0435 \u043F\u0440\u043E\u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0435 \u043F\u0438\u043D\u0433\u0438. conflict.json \u2014 \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442 \u0438 coldUntil."
|
|
8660
|
+
},
|
|
8661
|
+
{
|
|
8662
|
+
category: "storage",
|
|
8663
|
+
subcategory: "memory-files",
|
|
8664
|
+
title: "\u0424\u0430\u0439\u043B\u044B \u043F\u0430\u043C\u044F\u0442\u0438",
|
|
8665
|
+
keywords: ["memory", "long-term", "facts", "uncertain", "timeline", "promises", "open-loops"],
|
|
8666
|
+
body: "\u0413\u043B\u0430\u0432\u043D\u044B\u0435 memory-\u0444\u0430\u0439\u043B\u044B: memory/long-term.md, memory/facts.md, memory/uncertain.md, relationship/timeline.md, time/open-loops.md, time/promises.md. \u0415\u0441\u0442\u044C legacy long-term.md. MemoryPage \u0438 assistant \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044E\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0439 whitelist \u043F\u0443\u0442\u0435\u0439, \u043F\u043B\u044E\u0441 memory/daily/YYYY-MM-DD.md, memory/episodes/*.md, memory/palace/*."
|
|
8667
|
+
},
|
|
8668
|
+
{
|
|
8669
|
+
category: "storage",
|
|
8670
|
+
subcategory: "logs-and-days",
|
|
8671
|
+
title: "\u041B\u043E\u0433\u0438 \u0438 \u0434\u043D\u0435\u0432\u043D\u044B\u0435 summary",
|
|
8672
|
+
keywords: ["log", "daily", "summary", "session", "\u0434\u043D\u0435\u0432\u043D\u0438\u043A", "\u0434\u0430\u0442\u0430", "05:00"],
|
|
8673
|
+
body: "log/YYYY-MM-DD.md \u2014 \u0441\u0435\u0441\u0441\u0438\u043E\u043D\u043D\u044B\u0435 \u043B\u043E\u0433\u0438. sessionDate \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u0434\u0435\u043D\u044C \u043F\u043E timezone \u043F\u0440\u043E\u0444\u0438\u043B\u044F; \u0434\u043E 05:00 \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u0441\u043E\u0431\u044B\u0442\u0438\u044F \u043E\u0442\u043D\u043E\u0441\u044F\u0442\u0441\u044F \u043A \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0435\u043C\u0443 \u0434\u043D\u044E. memory/daily/YYYY-MM-DD.md \u2014 \u0434\u043D\u0435\u0432\u043D\u044B\u0435 summary \u0434\u043B\u044F \u0434\u043E\u043B\u0433\u043E\u0433\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 \u0438 \u043F\u043E\u0438\u0441\u043A\u0430 \u043F\u043E \u043F\u0440\u043E\u0448\u043B\u044B\u043C \u0434\u043D\u044F\u043C."
|
|
8674
|
+
},
|
|
8675
|
+
{
|
|
8676
|
+
category: "config",
|
|
8677
|
+
subcategory: "profile-config",
|
|
8678
|
+
title: "ProfileConfig",
|
|
8679
|
+
keywords: ["ProfileConfig", "config", "slug", "name", "age", "nationality", "tz", "mode"],
|
|
8680
|
+
body: "ProfileConfig \u0432\u043A\u043B\u044E\u0447\u0430\u0435\u0442 slug, name, age, nationality RU/UA, timezone, mode bot/userbot, stage, llm, telegram, mcp, ownerId, privacy, sleepFrom/sleepTo, nightWakeChance, ignoreTendency, vibe, communication, personaNotes \u0438 busySchedule. \u041F\u0440\u0438 \u0447\u0442\u0435\u043D\u0438\u0438 storage \u043D\u043E\u0440\u043C\u0430\u043B\u0438\u0437\u0443\u0435\u0442 ownerId, communication \u0438 ignoreTendency."
|
|
8681
|
+
},
|
|
8682
|
+
{
|
|
8683
|
+
category: "config",
|
|
8684
|
+
subcategory: "sleep-and-schedule",
|
|
8685
|
+
title: "\u0421\u043E\u043D \u0438 \u0437\u0430\u043D\u044F\u0442\u043E\u0441\u0442\u044C",
|
|
8686
|
+
keywords: ["sleepFrom", "sleepTo", "nightWakeChance", "busySchedule", "\u0441\u043E\u043D", "\u0440\u0430\u0441\u043F\u0438\u0441\u0430\u043D\u0438\u0435", "\u0437\u0430\u043D\u044F\u0442\u043E\u0441\u0442\u044C"],
|
|
8687
|
+
body: "sleepFrom/sleepTo \u2014 \u0447\u0430\u0441\u044B \u0441\u043D\u0430 0..23, \u043C\u043E\u0433\u0443\u0442 \u043F\u0435\u0440\u0435\u0441\u0435\u043A\u0430\u0442\u044C \u043F\u043E\u043B\u043D\u043E\u0447\u044C. nightWakeChance \u2014 \u0448\u0430\u043D\u0441 \u043F\u0440\u043E\u0441\u043D\u0443\u0442\u044C\u0441\u044F \u043D\u043E\u0447\u044C\u044E \u0431\u0435\u0437 :wake. busySchedule \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 label, days, from/to \u0438 checkAfterMin; daily-life \u0438 presence \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044E\u0442 \u0435\u0433\u043E, \u0447\u0442\u043E\u0431\u044B \u043E\u0431\u044A\u044F\u0441\u043D\u044F\u0442\u044C \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u0438 \u0438 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E\u0441\u0442\u044C \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430."
|
|
8688
|
+
},
|
|
8689
|
+
{
|
|
8690
|
+
category: "telegram",
|
|
8691
|
+
subcategory: "bot-mode",
|
|
8692
|
+
title: "Bot mode",
|
|
8693
|
+
keywords: ["bot", "grammy", "Bot API", "\u0442\u043E\u043A\u0435\u043D", "message_reaction", "\u0431\u043E\u0442"],
|
|
8694
|
+
body: "bot mode \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442 grammY \u0438 telegram.botToken. \u041F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442 message \u0438 message_reaction, \u0443\u043C\u0435\u0435\u0442 sendMessage, typing action, setMessageReaction, editMessageText \u0438 sendSticker. \u041F\u0440\u043E\u0449\u0435 \u0432 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0435, \u043D\u043E \u0432\u044B\u0433\u043B\u044F\u0434\u0438\u0442 \u043A\u0430\u043A \u0431\u043E\u0442 \u0438 \u0438\u043C\u0435\u0435\u0442 \u043E\u0433\u0440\u0430\u043D\u0438\u0447\u0435\u043D\u0438\u044F Bot API."
|
|
8695
|
+
},
|
|
8696
|
+
{
|
|
8697
|
+
category: "telegram",
|
|
8698
|
+
subcategory: "userbot-mode",
|
|
8699
|
+
title: "Userbot mode",
|
|
8700
|
+
keywords: ["userbot", "gramjs", "mtproto", "apiId", "apiHash", "sessionString", "\u0440\u0435\u0430\u043B\u044C\u043D\u044B\u0439 \u0430\u043A\u043A\u0430\u0443\u043D\u0442"],
|
|
8701
|
+
body: "userbot mode \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442 GramJS/MTProto \u043A\u0430\u043A \u043E\u0431\u044B\u0447\u043D\u044B\u0439 Telegram \u0430\u043A\u043A\u0430\u0443\u043D\u0442. \u041D\u0443\u0436\u043D\u044B apiId/apiHash \u0438 sessionString, \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u043D\u044B\u0439 \u0447\u0435\u0440\u0435\u0437 \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u044E. \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 readHistory, typing, reactions, stickers, block/unblock/reportSpam \u0438 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0443 \u0443\u0434\u0430\u043B\u0451\u043D\u043D\u044B\u0445 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 raw updates."
|
|
8702
|
+
},
|
|
8703
|
+
{
|
|
8704
|
+
category: "telegram",
|
|
8705
|
+
subcategory: "wss-and-proxy",
|
|
8706
|
+
title: "WSS \u0438 proxy",
|
|
8707
|
+
keywords: ["wss", "useWSS", "proxy", "socks", "\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438", "443"],
|
|
8708
|
+
body: "telegram.useWSS \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E true \u0438 \u0432\u043A\u043B\u044E\u0447\u0430\u0435\u0442 WebSocket \u0447\u0435\u0440\u0435\u0437 443 \u0432\u043C\u0435\u0441\u0442\u043E TCP 80 \u2014 \u044D\u0442\u043E \u043F\u043E\u043C\u043E\u0433\u0430\u0435\u0442 \u043F\u0440\u0438 \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430\u0445 Telegram. \u0414\u043B\u044F userbot \u043C\u043E\u0436\u043D\u043E \u0437\u0430\u0434\u0430\u0442\u044C SOCKS proxy \u0432 config \u0438\u043B\u0438 \u0447\u0435\u0440\u0435\u0437 GIRL_AGENT_TG_PROXY."
|
|
8709
|
+
},
|
|
8710
|
+
{
|
|
8711
|
+
category: "telegram",
|
|
8712
|
+
subcategory: "privacy",
|
|
8713
|
+
title: "Privacy \u0438 owner",
|
|
8714
|
+
keywords: ["privacy", "owner", "ownerId", "allow-strangers", "strangers", "\u0447\u0443\u0436\u0438\u0435", "primary"],
|
|
8715
|
+
body: "privacy=owner-only \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0442\u043E\u043B\u044C\u043A\u043E ownerId/primary owner. allow-strangers \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442 \u0441\u0442\u043E\u0440\u043E\u043D\u043D\u0438\u0435 \u043B\u0438\u0447\u043D\u044B\u0435 \u0447\u0430\u0442\u044B, \u043D\u043E \u0441 relationshipScope=acquaintance: \u0431\u0435\u0437 \u043F\u0430\u043C\u044F\u0442\u0438 \u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0433\u043E \u043F\u0430\u0440\u043D\u044F, \u0431\u0435\u0437 \u0440\u043E\u043C\u0430\u043D\u0442\u0438\u0447\u0435\u0441\u043A\u043E\u0439 \u0438\u0441\u0442\u043E\u0440\u0438\u0438 \u0438 \u0441 \u0433\u0440\u0430\u043D\u0438\u0446\u0430\u043C\u0438, \u0435\u0441\u043B\u0438 \u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0439 relationship \u0443\u0436\u0435 committed."
|
|
8716
|
+
},
|
|
8717
|
+
{
|
|
8718
|
+
category: "runtime",
|
|
8719
|
+
subcategory: "runtime-bus",
|
|
8720
|
+
title: "RuntimeBus \u0432 WebUI",
|
|
8721
|
+
keywords: ["runtimebus", "runtime", "start", "stop", "pause", "resume", "restart", "logs"],
|
|
8722
|
+
body: "RuntimeBus \u0434\u0435\u0440\u0436\u0438\u0442 Runtime \u043D\u0430 \u043A\u0430\u0436\u0434\u044B\u0439 \u043F\u0440\u043E\u0444\u0438\u043B\u044C, \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044F running/paused/stopped/error \u0438 ring-buffer \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0445 500 \u0441\u043E\u0431\u044B\u0442\u0438\u0439. WebUI \u0447\u0435\u0440\u0435\u0437 \u043D\u0435\u0433\u043E \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442/\u043E\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u0435\u0442 \u043F\u0440\u043E\u0444\u0438\u043B\u0438, \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 status \u0438 recentLogs, \u0430 WebSocket \u0440\u0430\u0437\u0434\u0430\u0451\u0442 \u0441\u043E\u0431\u044B\u0442\u0438\u044F UI."
|
|
8723
|
+
},
|
|
8724
|
+
{
|
|
8725
|
+
category: "runtime",
|
|
8726
|
+
subcategory: "message-flow",
|
|
8727
|
+
title: "\u041F\u0443\u0442\u044C \u0432\u0445\u043E\u0434\u044F\u0449\u0435\u0433\u043E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F",
|
|
8728
|
+
keywords: ["handleIncoming", "incoming", "message flow", "\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435", "\u043E\u0442\u0432\u0435\u0442"],
|
|
8729
|
+
body: "Telegram adapter \u0441\u043E\u0437\u0434\u0430\u0451\u0442 IncomingMessage. Runtime \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442 \u043F\u0440\u0438\u0432\u0430\u0442\u043D\u043E\u0441\u0442\u044C/owner, media, deletion/reaction, \u0438\u0441\u0442\u043E\u0440\u0438\u044E, presence, conflict, active dialog \u0438 behavior-tick. \u0415\u0441\u043B\u0438 shouldReply=false \u2014 \u043B\u043E\u0433\u0438\u0440\u0443\u0435\u0442 ignored/read. \u0415\u0441\u043B\u0438 reply \u2014 scheduleReply \u0441 delay, \u043F\u043E\u0442\u043E\u043C generateAndSend \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442 prompt, \u0432\u044B\u0437\u044B\u0432\u0430\u0435\u0442 LLM, \u0441\u0430\u043D\u0438\u0442\u0430\u0439\u0437\u0438\u0442 \u043E\u0442\u0432\u0435\u0442, \u0440\u0435\u0436\u0435\u0442 \u043D\u0430 bubbles \u0438 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u0442."
|
|
8730
|
+
},
|
|
8731
|
+
{
|
|
8732
|
+
category: "runtime",
|
|
8733
|
+
subcategory: "behavior-tick",
|
|
8734
|
+
title: "Behavior tick",
|
|
8735
|
+
keywords: ["behavior", "intent", "reply", "ignore", "short", "left-on-read", "reaction-only", "delay", "moodDelta"],
|
|
8736
|
+
body: "behavior-tick \u2014 \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0438\u0439 decision layer. \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 JSON: intent, shouldReply, shouldRead, delaySec, bubbles, typing, reaction, reactionTargetMessageId, ignoreReason \u0438 moodDelta. \u041E\u043D \u0443\u0447\u0438\u0442\u044B\u0432\u0430\u0435\u0442 stage defaults, score, ignoreTendency, presence, conflict, active dialog \u0438 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F."
|
|
8737
|
+
},
|
|
8738
|
+
{
|
|
8739
|
+
category: "runtime",
|
|
8740
|
+
subcategory: "presence",
|
|
8741
|
+
title: "Presence simulation",
|
|
8742
|
+
keywords: ["presence", "online", "offline", "phone-attached", "burst-checker", "rare-checker", "evening-only", "night"],
|
|
8743
|
+
body: "PresenceProfile \u0434\u0435\u0442\u0435\u0440\u043C\u0438\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E \u0432\u044B\u0431\u0438\u0440\u0430\u0435\u0442 pattern: phone-attached, burst-checker, rare-checker, evening-only \u0438\u043B\u0438 phone-attached-night. \u041E\u043D \u0437\u0430\u0434\u0430\u0451\u0442 checkEveryMin, onlineWindowMin, offlineReplyChance \u0438 nightWakeChance. Communication notifications \u0438 stage \u043C\u043E\u0433\u0443\u0442 \u0443\u0441\u043A\u043E\u0440\u044F\u0442\u044C/\u0437\u0430\u043C\u0435\u0434\u043B\u044F\u0442\u044C \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E\u0441\u0442\u044C."
|
|
8744
|
+
},
|
|
8745
|
+
{
|
|
8746
|
+
category: "runtime",
|
|
8747
|
+
subcategory: "ignore-tendency",
|
|
8748
|
+
title: "ignoreTendency",
|
|
8749
|
+
keywords: ["ignoreTendency", "\u0438\u0433\u043D\u043E\u0440", "\u043C\u043E\u043B\u0447\u0438\u0442", "\u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442", "read", "left-on-read"],
|
|
8750
|
+
body: "ignoreTendency 0..100 \u2014 \u0445\u0430\u0440\u0430\u043A\u0442\u0435\u0440\u043D\u044B\u0439 \u0432\u0435\u0441, \u0430 \u043D\u0435 \u043F\u0440\u044F\u043C\u043E\u0439 \u043F\u0440\u043E\u0446\u0435\u043D\u0442. 0 \u043F\u043E\u0447\u0442\u0438 \u043D\u0435 \u0438\u0433\u043D\u043E\u0440\u0438\u0442 \u0431\u0435\u0437 \u043F\u0440\u0438\u0447\u0438\u043D\u044B, 35 \u0434\u0435\u0444\u043E\u043B\u0442, 70+ \u0441\u0443\u0445\u0430\u044F \u0438 \u0447\u0430\u0441\u0442\u043E \u043F\u0440\u043E\u043F\u0430\u0434\u0430\u0435\u0442. \u0421\u043E\u043D, busy, \u0441\u0442\u0430\u0434\u0438\u044F, \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442 \u0438 score \u0441\u0438\u043B\u044C\u043D\u0435\u0435. \u041F\u0440\u0438 \u0436\u0430\u043B\u043E\u0431\u0435 '\u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442' \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0439 runtime state, recent logs, sleep/busy/conflict/stage/score."
|
|
8751
|
+
},
|
|
8752
|
+
{
|
|
8753
|
+
category: "runtime",
|
|
8754
|
+
subcategory: "active-dialog",
|
|
8755
|
+
title: "\u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0439 \u0434\u0438\u0430\u043B\u043E\u0433",
|
|
8756
|
+
keywords: ["\u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0439 \u0434\u0438\u0430\u043B\u043E\u0433", "activeDialog", "\u0431\u0443\u0440\u0441\u0442", "\u0431\u044B\u0441\u0442\u0440\u044B\u0439 \u043E\u0442\u0432\u0435\u0442", "\u043D\u0435 \u043F\u0440\u043E\u043F\u0430\u0434\u0430\u0435\u0442"],
|
|
8757
|
+
body: "\u0415\u0441\u043B\u0438 \u043E\u043D\u0430 \u0443\u0436\u0435 \u043D\u0435\u0434\u0430\u0432\u043D\u043E \u043E\u0442\u0432\u0435\u0442\u0438\u043B\u0430, \u0430 \u043E\u043D \u043D\u0430\u043F\u0438\u0441\u0430\u043B \u0432 \u0442\u0435\u0447\u0435\u043D\u0438\u0435 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u0438\u0445 \u043C\u0438\u043D\u0443\u0442, Runtime \u043F\u043E\u043C\u0435\u0447\u0430\u0435\u0442 activeDialog. Behavior-layer \u0434\u043E\u043B\u0436\u0435\u043D \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0430\u0442\u044C \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u043A\u0443 \u0438 \u043D\u0435 \u0443\u0445\u043E\u0434\u0438\u0442\u044C \u0432 \u0441\u043B\u0443\u0447\u0430\u0439\u043D\u044B\u0439 \u0438\u0433\u043D\u043E\u0440 \u0431\u0435\u0437 \u0432\u0435\u0441\u043A\u043E\u0439 \u043F\u0440\u0438\u0447\u0438\u043D\u044B. \u042D\u0442\u043E \u0434\u0435\u043B\u0430\u0435\u0442 \u0434\u0438\u0430\u043B\u043E\u0433 \u043F\u043E\u0445\u043E\u0436\u0438\u043C \u043D\u0430 \u0440\u0435\u0430\u043B\u044C\u043D\u0443\u044E \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u043A\u0443, \u0430 \u043D\u0435 \u043D\u0430 \u043D\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043C\u044B\u0435 \u0437\u0430\u043F\u0440\u043E\u0441\u044B."
|
|
8758
|
+
},
|
|
8759
|
+
{
|
|
8760
|
+
category: "runtime",
|
|
8761
|
+
subcategory: "bubbles",
|
|
8762
|
+
title: "\u041F\u0443\u0437\u044B\u0440\u0438 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439",
|
|
8763
|
+
keywords: ["bubbles", "\u043F\u0443\u0437\u044B\u0440\u044C", "split", "---", "\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F", "\u0434\u0440\u043E\u0431\u0438\u0442\u044C"],
|
|
8764
|
+
body: "LLM \u043F\u043E\u043B\u0443\u0447\u0430\u0435\u0442 \u0443\u043A\u0430\u0437\u0430\u043D\u0438\u0435: \u0435\u0441\u043B\u0438 bubbles > 1, \u0440\u0430\u0437\u0434\u0435\u043B\u044F\u0442\u044C \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0441\u0442\u0440\u043E\u043A\u043E\u0439 '---'. smartSplitBubbles \u0438 dedupeBubbles \u043F\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044E\u0442 \u043E\u0442\u0432\u0435\u0442 \u0432 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u044B\u0435 TG-\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F. \u041F\u0435\u0440\u0435\u043D\u043E\u0441\u044B \u0441\u0442\u0440\u043E\u043A \u0431\u0435\u0437 '---' \u0437\u0430\u043F\u0440\u0435\u0449\u0435\u043D\u044B, \u043F\u043E\u0442\u043E\u043C\u0443 \u0447\u0442\u043E \u0432 Telegram \u044D\u0442\u043E \u043E\u0434\u043D\u043E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0441\u0442\u043E\u043B\u0431\u0438\u043A\u043E\u043C \u0438 \u043F\u0430\u043B\u0438\u0442 \u0418\u0418."
|
|
8765
|
+
},
|
|
8766
|
+
{
|
|
8767
|
+
category: "runtime",
|
|
8768
|
+
subcategory: "typing-and-delays",
|
|
8769
|
+
title: "Typing \u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u0438",
|
|
8770
|
+
keywords: ["typing", "delay", "\u0437\u0430\u0434\u0435\u0440\u0436\u043A\u0430", "\u043F\u0435\u0447\u0430\u0442\u0430\u0435\u0442", "scheduleReply", "sendBubbles"],
|
|
8771
|
+
body: "delaySec \u043F\u0440\u0438\u0445\u043E\u0434\u0438\u0442 \u0438\u0437 behavior-tick \u0438 \u043C\u043E\u0436\u0435\u0442 \u0443\u0432\u0435\u043B\u0438\u0447\u0438\u0432\u0430\u0442\u044C\u0441\u044F \u0438\u0437-\u0437\u0430 offline/busy. scheduleReply \u0441\u0442\u0430\u0432\u0438\u0442 \u0442\u0430\u0439\u043C\u0435\u0440. sendBubbles \u0438\u043C\u0438\u0442\u0438\u0440\u0443\u0435\u0442 typing: \u043F\u0435\u0440\u0435\u0434 \u043F\u0435\u0440\u0432\u044B\u043C \u043F\u0443\u0437\u044B\u0440\u0451\u043C \u043A\u043E\u0440\u043E\u0442\u043A\u0430\u044F \u043F\u0430\u0443\u0437\u0430, \u043C\u0435\u0436\u0434\u0443 \u043F\u0443\u0437\u044B\u0440\u044F\u043C\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u0430 \u043F\u043E \u0434\u043B\u0438\u043D\u0435 \u0442\u0435\u043A\u0441\u0442\u0430 \u0438 WPM. \u0415\u0441\u043B\u0438 userbot \u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D, \u043F\u0435\u0440\u0435\u0434 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u043E\u0439 \u043C\u043E\u0436\u0435\u0442 readHistory."
|
|
8772
|
+
},
|
|
8773
|
+
{
|
|
8774
|
+
category: "runtime",
|
|
8775
|
+
subcategory: "anti-ai",
|
|
8776
|
+
title: "Anti-AI \u0438 \u0441\u0430\u043D\u0438\u0442\u0430\u0439\u0437\u0438\u043D\u0433",
|
|
8777
|
+
keywords: ["anti-ai", "sanitize", "markdown", "jailbreak", "system prompt", "chatgpt", "\u0442\u0435\u0445\u043D\u0438\u0447\u0435\u0441\u043A\u0430\u044F \u043E\u0448\u0438\u0431\u043A\u0430"],
|
|
8778
|
+
body: "ANTI_AI_RULES \u0437\u0430\u043F\u0440\u0435\u0449\u0430\u044E\u0442 ChatGPT-\u043F\u043E\u0432\u0430\u0434\u043A\u0438, markdown \u0438 \u043C\u0435\u0442\u0430-\u0444\u0440\u0430\u0437\u044B. security.ts \u0432\u044B\u0447\u0438\u0449\u0430\u0435\u0442 code fences, action leak narration, system/developer labels, CJK \u043C\u0443\u0441\u043E\u0440 \u0438 technical error replies. Jailbreak-\u043F\u043E\u0434\u043E\u0431\u043D\u044B\u0435 \u0434\u043B\u0438\u043D\u043D\u044B\u0435 \u043E\u0442\u0432\u0435\u0442\u044B \u043E\u0442\u0431\u0440\u0430\u0441\u044B\u0432\u0430\u044E\u0442\u0441\u044F; \u043F\u0440\u0438 \u0442\u0435\u0445\u043D\u0438\u0447\u0435\u0441\u043A\u0438\u0445 \u043E\u0448\u0438\u0431\u043A\u0430\u0445 Runtime \u0443\u0445\u043E\u0434\u0438\u0442 \u0432 \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0439 fallback/ignored."
|
|
8779
|
+
},
|
|
8780
|
+
{
|
|
8781
|
+
category: "runtime",
|
|
8782
|
+
subcategory: "media",
|
|
8783
|
+
title: "\u041C\u0435\u0434\u0438\u0430",
|
|
8784
|
+
keywords: ["media", "photo", "voice", "video", "video_note", "sticker", "document", "\u0444\u043E\u0442\u043E", "\u0433\u043E\u043B\u043E\u0441\u043E\u0432\u043E\u0435"],
|
|
8785
|
+
body: "IncomingMedia \u043E\u043F\u0438\u0441\u044B\u0432\u0430\u0435\u0442 \u0444\u043E\u0442\u043E, \u0432\u0438\u0434\u0435\u043E, \u0433\u043E\u043B\u043E\u0441\u043E\u0432\u043E\u0435, \u043A\u0440\u0443\u0436\u043E\u043A, \u0441\u0442\u0438\u043A\u0435\u0440 \u0438\u043B\u0438 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442. \u0424\u043E\u0442\u043E \u0441 base64 \u043F\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044F LLM \u043A\u0430\u043A image part, \u0435\u0441\u043B\u0438 \u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442. \u041D\u0430 \u0433\u043E\u043B\u043E\u0441\u043E\u0432\u044B\u0435 \u0431\u0435\u0437 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043E\u0432\u043A\u0438 \u043F\u0435\u0440\u0441\u043E\u043D\u0430 \u043C\u043E\u0436\u0435\u0442 \u043F\u043E\u043F\u0440\u043E\u0441\u0438\u0442\u044C \u0442\u0435\u043A\u0441\u0442\u043E\u043C. \u041D\u0430 \u0438\u0441\u0445\u043E\u0434\u044F\u0449\u0438\u0435 \u043F\u0440\u043E\u0441\u044C\u0431\u044B \u0444\u043E\u0442\u043E/\u0432\u0438\u0434\u0435\u043E/voice Runtime \u0447\u0430\u0449\u0435 \u0434\u0430\u0451\u0442 \u043E\u0442\u043A\u0430\u0437 \u0432\u0440\u043E\u0434\u0435 '\u043D\u0435 \u0445\u043E\u0447\u0443 \u0444\u043E\u0442\u043A\u0430\u0442\u044C\u0441\u044F \u0449\u0430'."
|
|
8786
|
+
},
|
|
8787
|
+
{
|
|
8788
|
+
category: "runtime",
|
|
8789
|
+
subcategory: "deleted-messages",
|
|
8790
|
+
title: "\u0423\u0434\u0430\u043B\u0451\u043D\u043D\u044B\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F",
|
|
8791
|
+
keywords: ["\u0443\u0434\u0430\u043B\u0438\u043B", "deleted", "delete", "saw-and-read", "saw-not-read", "missed"],
|
|
8792
|
+
body: "deletion-handler \u043A\u043B\u0430\u0441\u0441\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435: saw-and-read \u2014 \u043E\u043D\u0430 \u0443\u0436\u0435 \u043F\u0440\u043E\u0447\u043B\u0430 \u0438 \u043C\u043E\u0436\u0435\u0442 \u0441\u043A\u0430\u0437\u0430\u0442\u044C '\u043F\u043E\u0437\u0434\u043D\u043E, \u044F \u0432\u0438\u0434\u0435\u043B\u0430'; saw-not-read \u2014 \u0432\u0438\u0434\u0435\u043B\u0430 \u0444\u0430\u043A\u0442 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F, \u043D\u043E \u043D\u0435 \u043F\u0440\u043E\u0447\u043B\u0430 \u0438 \u043C\u043E\u0436\u0435\u0442 \u043F\u043E\u043F\u0440\u043E\u0441\u0438\u0442\u044C \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C; missed \u2014 \u043D\u0435 \u0437\u0430\u043C\u0435\u0442\u0438\u043B\u0430 \u0438 \u043C\u043E\u043B\u0447\u0438\u0442. Userbot \u043A\u044D\u0448\u0438\u0440\u0443\u0435\u0442 \u0432\u0445\u043E\u0434\u044F\u0449\u0438\u0435, \u0447\u0442\u043E\u0431\u044B \u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0442\u0435\u043A\u0441\u0442 \u043F\u043E raw update."
|
|
8793
|
+
},
|
|
8794
|
+
{
|
|
8795
|
+
category: "runtime",
|
|
8796
|
+
subcategory: "emoji-reactions",
|
|
8797
|
+
title: "\u0420\u0435\u0430\u043A\u0446\u0438\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F",
|
|
8798
|
+
keywords: ["emoji", "reaction", "\u0440\u0435\u0430\u043A\u0446\u0438\u044F", "\u0442\u043E\u043A\u0441\u0438\u0447\u043D\u0430\u044F", "positive", "react-back", "silent-mood"],
|
|
8799
|
+
body: "emoji-reaction-handler \u0434\u0435\u043B\u0438\u0442 \u0440\u0435\u0430\u043A\u0446\u0438\u0438 \u043D\u0430 toxic, positive, funny, sad, neutral. \u0422\u043E\u043A\u0441\u0438\u0447\u043D\u044B\u0435 \u044D\u043C\u043E\u0434\u0437\u0438 \u043D\u0430 \u0435\u0451 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043E\u0431\u044B\u0447\u043D\u043E \u043C\u043E\u043B\u0447\u0430 \u0443\u0445\u0443\u0434\u0448\u0430\u044E\u0442 mood; \u043D\u043E \u0435\u0441\u043B\u0438 \u044D\u043C\u043E\u0434\u0437\u0438 \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0441\u044F \u043A \u0432\u043D\u0435\u0448\u043D\u0435\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u0438\u0437 \u0435\u0451 \u0442\u0435\u043A\u0441\u0442\u0430, annoyance \u043D\u0435 \u0440\u0430\u0441\u0442\u0451\u0442. Positive \u0438\u043D\u043E\u0433\u0434\u0430 react-back/\u043A\u043E\u0440\u043E\u0442\u043A\u0438\u0439 \u0442\u0435\u043A\u0441\u0442, \u043D\u043E \u0447\u0430\u0449\u0435 \u043C\u043E\u043B\u0447\u0430. \u0421\u043D\u044F\u0442\u0438\u0435 \u0440\u0435\u0430\u043A\u0446\u0438\u0438 \u043E\u0431\u044B\u0447\u043D\u043E \u0438\u0433\u043D\u043E\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044F."
|
|
8800
|
+
},
|
|
8801
|
+
{
|
|
8802
|
+
category: "runtime",
|
|
8803
|
+
subcategory: "typos",
|
|
8804
|
+
title: "\u0420\u0435\u0430\u043B\u0438\u0441\u0442\u0438\u0447\u043D\u044B\u0435 \u043E\u043F\u0435\u0447\u0430\u0442\u043A\u0438",
|
|
8805
|
+
keywords: ["typos", "\u043E\u043F\u0435\u0447\u0430\u0442\u043A\u0438", "\u043A\u043B\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430", "qwerty", "\u0439\u0446\u0443\u043A\u0435\u043D", "\u043E\u0448\u0438\u0431\u043A\u0438"],
|
|
8806
|
+
body: "typos.ts \u0432\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u0442 \u043E\u043F\u0435\u0447\u0430\u0442\u043A\u0438 \u043F\u043E\u0441\u043B\u0435 LLM, \u0447\u0442\u043E\u0431\u044B \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u043B\u043E\u0442\u043D\u043E\u0441\u0442\u044C. \u0422\u0438\u043F\u044B: \u0441\u043E\u0441\u0435\u0434\u043D\u044F\u044F \u043A\u043B\u0430\u0432\u0438\u0448\u0430, \u043F\u0440\u043E\u043F\u0443\u0441\u043A, \u0434\u0443\u0431\u043B\u044C, \u043F\u0435\u0440\u0435\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430 \u0441\u043E\u0441\u0435\u0434\u043D\u0438\u0445 \u0431\u0443\u043A\u0432, \u0440\u0435\u0434\u043A\u0430\u044F \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u0430\u044F \u0440\u0430\u0441\u043A\u043B\u0430\u0434\u043A\u0430 RU/EN. \u041D\u0435 \u043B\u043E\u043C\u0430\u0435\u0442 \u043A\u043E\u0440\u043E\u0442\u043A\u0438\u0435 \u0441\u043B\u043E\u0432\u0430, \u0441\u0441\u044B\u043B\u043A\u0438, \u0441\u043C\u0430\u0439\u043B\u044B \u0438 \u043F\u0443\u043D\u043A\u0442\u0443\u0430\u0446\u0438\u044E. \u0418\u043D\u0442\u0435\u043D\u0441\u0438\u0432\u043D\u043E\u0441\u0442\u044C \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043E\u0442 communication messageStyle \u0438 vibe."
|
|
8807
|
+
},
|
|
8808
|
+
{
|
|
8809
|
+
category: "relationship",
|
|
8810
|
+
subcategory: "stages",
|
|
8811
|
+
title: "\u0421\u0442\u0430\u0434\u0438\u0438 \u043E\u0442\u043D\u043E\u0448\u0435\u043D\u0438\u0439",
|
|
8812
|
+
keywords: ["stage", "\u0441\u0442\u0430\u0434\u0438\u044F", "\u043E\u0442\u043D\u043E\u0448\u0435\u043D\u0438\u044F", "\u043C\u0435\u0442", "cold", "warming", "dating", "long-term", "dumped"],
|
|
8813
|
+
body: "\u0421\u0442\u0430\u0434\u0438\u044F \u0437\u0430\u0434\u0430\u0451\u0442 \u0431\u043B\u0438\u0437\u043E\u0441\u0442\u044C, \u0442\u043E\u043D, \u0448\u0430\u043D\u0441 \u0438\u0433\u043D\u043E\u0440\u0430 \u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u0438. \u041E\u0441\u043D\u043E\u0432\u043D\u043E\u0439 \u043F\u043E\u0440\u044F\u0434\u043E\u043A: met-irl-got-tg \u2192 tg-given-cold \u2192 tg-given-warming \u2192 convinced \u2192 first-date-done \u2192 dating-early \u2192 dating-stable \u2192 long-term. dumped \u2014 \u0441\u043B\u0443\u0436\u0435\u0431\u043D\u0430\u044F \u0442\u0435\u0440\u043C\u0438\u043D\u0430\u043B\u044C\u043D\u0430\u044F \u0441\u0442\u0430\u0434\u0438\u044F \u0441 \u043F\u043E\u043B\u043D\u044B\u043C \u0438\u0433\u043D\u043E\u0440\u043E\u043C."
|
|
8814
|
+
},
|
|
8815
|
+
{
|
|
8816
|
+
category: "relationship",
|
|
8817
|
+
subcategory: "score",
|
|
8818
|
+
title: "Score \u043E\u0442\u043D\u043E\u0448\u0435\u043D\u0438\u0439",
|
|
8819
|
+
keywords: ["score", "interest", "trust", "attraction", "annoyance", "cringe", "\u043C\u0435\u0442\u0440\u0438\u043A\u0438"],
|
|
8820
|
+
body: "RelationshipScore: interest \u2014 \u0438\u043D\u0442\u0435\u0440\u0435\u0441, trust \u2014 \u0434\u043E\u0432\u0435\u0440\u0438\u0435, attraction \u2014 \u0440\u043E\u043C\u0430\u043D\u0442\u0438\u0447\u0435\u0441\u043A\u043E\u0435/\u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043A\u043E\u0435 \u043F\u0440\u0438\u0442\u044F\u0436\u0435\u043D\u0438\u0435, annoyance \u2014 \u0440\u0430\u0437\u0434\u0440\u0430\u0436\u0435\u043D\u0438\u0435, cringe \u2014 \u043D\u0430\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043E\u043D \u043A\u0440\u0438\u043D\u0436\u0443\u0435\u0442/\u0434\u0430\u0432\u0438\u0442. Score \u043C\u0435\u043D\u044F\u0435\u0442\u0441\u044F \u0447\u0435\u0440\u0435\u0437 moodDelta \u0438 reflection, \u0432\u043B\u0438\u044F\u0435\u0442 \u043D\u0430 conflict, stage transitions, stressLoad \u0433\u043E\u0440\u043C\u043E\u043D\u043E\u0432, ignore \u0438 \u0442\u043E\u043D."
|
|
8821
|
+
},
|
|
8822
|
+
{
|
|
8823
|
+
category: "relationship",
|
|
8824
|
+
subcategory: "stage-transitions",
|
|
8825
|
+
title: "\u0410\u0432\u0442\u043E\u0441\u043C\u0435\u043D\u0430 \u0441\u0442\u0430\u0434\u0438\u0439",
|
|
8826
|
+
keywords: ["stage transition", "\u0430\u0432\u0442\u043E\u0441\u043C\u0435\u043D\u0430", "\u043F\u043E\u0432\u044B\u0441\u0438\u0442\u044C", "\u043F\u043E\u043D\u0438\u0437\u0438\u0442\u044C", "\u0440\u0435\u0433\u0440\u0435\u0441\u0441", "upgrade", "downgrade"],
|
|
8827
|
+
body: "decideStageTransition \u043D\u0435 \u0440\u0430\u043D\u0434\u043E\u043C\u043D\u044B\u0439: \u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442 downgrade, \u043F\u043E\u0442\u043E\u043C upgrade. \u0414\u043B\u044F upgrade \u043D\u0443\u0436\u043D\u043E \u043C\u0438\u043D\u0438\u043C\u0443\u043C 6 \u0435\u0451 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439 \u0432 \u0442\u0435\u043A\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0434\u0438\u0438, \u043F\u043E\u0434\u0445\u043E\u0434\u044F\u0449\u0438\u0435 score \u0438 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0433\u043E \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0430. Downgrade \u0441\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u0435\u0442 \u043F\u0440\u0438 \u0432\u044B\u0441\u043E\u043A\u043E\u043C annoyance, \u043D\u0438\u0437\u043A\u0438\u0445 interest/trust \u0438\u043B\u0438 \u0431\u043E\u043B\u044C\u0448\u043E\u043C \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0433\u043D\u043E\u0440\u043E\u0432 \u043D\u0430 \u0442\u0451\u043F\u043B\u043E\u0439 \u0441\u0442\u0430\u0434\u0438\u0438. dumped \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u043D\u0435 \u043F\u043E\u0432\u044B\u0448\u0430\u0435\u0442\u0441\u044F."
|
|
8828
|
+
},
|
|
8829
|
+
{
|
|
8830
|
+
category: "relationship",
|
|
8831
|
+
subcategory: "dumped",
|
|
8832
|
+
title: "dumped",
|
|
8833
|
+
keywords: ["dumped", "\u043E\u0442\u0448\u0438\u043B\u0430", "\u0440\u0430\u0437\u0440\u044B\u0432", "\u0441\u0431\u0440\u043E\u0441", "reset", "\u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442"],
|
|
8834
|
+
body: "dumped \u2014 \u0441\u043B\u0443\u0436\u0435\u0431\u043D\u0430\u044F \u0441\u0442\u0430\u0434\u0438\u044F '\u043E\u0442\u0448\u0438\u043B\u0430': ignoreChance=1.0 \u0438 \u043E\u0433\u0440\u043E\u043C\u043D\u044B\u0435 delays. Runtime \u043C\u043E\u0436\u0435\u0442 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C dumped \u043F\u0440\u0438 annoyance > 80 \u0438 interest < -30. \u0412\u044B\u0445\u043E\u0434 \u2014 :reset \u0438\u043B\u0438 \u0440\u0443\u0447\u043D\u043E\u0439 set_stage. reset \u0447\u0438\u0441\u0442\u0438\u0442 score, long-term memory, conflict \u0438 \u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0437 dumped \u0432 tg-given-cold."
|
|
8835
|
+
},
|
|
8836
|
+
{
|
|
8837
|
+
category: "relationship",
|
|
8838
|
+
subcategory: "timeline",
|
|
8839
|
+
title: "relationship/timeline.md",
|
|
8840
|
+
keywords: ["timeline", "\u0438\u0441\u0442\u043E\u0440\u0438\u044F \u043E\u0442\u043D\u043E\u0448\u0435\u043D\u0438\u0439", "relationship", "\u0441\u0442\u0430\u0434\u0438\u044F \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0430\u0441\u044C"],
|
|
8841
|
+
body: "maybeAdvanceRelationshipTimeline \u043F\u0440\u0438 \u0441\u043C\u0435\u043D\u0435 \u0441\u0442\u0430\u0434\u0438\u0438 \u043C\u0438\u0433\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0443\u044E \u043F\u0430\u043C\u044F\u0442\u044C \u0432 Memory Palace \u0438 \u043F\u0438\u0448\u0435\u0442 \u0432 relationship/timeline.md \u0441\u0442\u0440\u043E\u043A\u0443 \u0432\u0438\u0434\u0430 '\u0441\u0442\u0430\u0434\u0438\u044F \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0430\u0441\u044C previous \u2192 next'. \u042D\u0442\u043E \u0432\u0430\u0436\u043D\u043E \u0434\u043B\u044F \u043E\u0442\u0432\u0435\u0442\u0430 \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0430 \u043E \u0442\u043E\u043C, \u043A\u0430\u043A \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043B\u0438\u0441\u044C \u043E\u0442\u043D\u043E\u0448\u0435\u043D\u0438\u044F."
|
|
8842
|
+
},
|
|
8843
|
+
{
|
|
8844
|
+
category: "conflict",
|
|
8845
|
+
subcategory: "levels",
|
|
8846
|
+
title: "\u0423\u0440\u043E\u0432\u043D\u0438 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0430",
|
|
8847
|
+
keywords: ["conflict", "\u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442", "coldUntil", "\u043E\u0431\u0438\u0434\u0430", "level", "\u043C\u043E\u043B\u0447\u0438\u0442"],
|
|
8848
|
+
body: "conflict.json \u0445\u0440\u0430\u043D\u0438\u0442 level 0..4, reason, since, coldUntil \u0438 history. level 1 \u2014 \u043B\u0451\u0433\u043A\u0430\u044F \u043E\u0431\u0438\u0434\u0430 \u043D\u0430 \u0447\u0430\u0441, 2 \u2014 \u043E\u0431\u0438\u0436\u0435\u043D\u0430 \u043D\u0430 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0447\u0430\u0441\u043E\u0432/\u0441\u0443\u0442\u043A\u0438, 3 \u2014 \u0441\u0435\u0440\u044C\u0451\u0437\u043D\u044B\u0439 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442 \u043D\u0430 \u0434\u043D\u0438, 4 \u2014 \u043D\u0430 \u0433\u0440\u0430\u043D\u0438 \u0440\u0430\u0437\u0440\u044B\u0432\u0430. \u041F\u043E\u043A\u0430 coldUntil \u0430\u043A\u0442\u0438\u0432\u0435\u043D, behavior \u043F\u043E\u0447\u0442\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 ignore \u0438\u043B\u0438 \u0441\u0443\u0445\u043E\u0439 short."
|
|
8849
|
+
},
|
|
8850
|
+
{
|
|
8851
|
+
category: "conflict",
|
|
8852
|
+
subcategory: "escalation",
|
|
8853
|
+
title: "\u042D\u0441\u043A\u0430\u043B\u0430\u0446\u0438\u044F \u0438 \u043F\u0440\u0438\u043C\u0438\u0440\u0435\u043D\u0438\u0435",
|
|
8854
|
+
keywords: ["escalate", "soften", "annoyance", "cringe", "interestDrop", "\u043F\u043E\u043C\u0438\u0440\u0438\u0442\u044C\u0441\u044F"],
|
|
8855
|
+
body: "escalateFromMood \u0441\u043C\u043E\u0442\u0440\u0438\u0442 \u043D\u0430 delta annoyance/cringe/interestDrop \u0438 \u0442\u0435\u043A\u0443\u0449\u0438\u0439 score. trigger >= 8 \u0434\u0430\u0451\u0442 \u043B\u0451\u0433\u043A\u0443\u044E \u043E\u0431\u0438\u0434\u0443, >=15 \u2014 \u0441\u0435\u0440\u044C\u0451\u0437\u043D\u0435\u0435, >=25 \u0438\u043B\u0438 annoyance >70 \u2014 level 3. annoyance >85 + cringe >70 + interest < -30 \u0432\u0435\u0434\u0451\u0442 \u043A level 4. softenFromMood \u0441\u043D\u0438\u0436\u0430\u0435\u0442 level, \u0435\u0441\u043B\u0438 positive delta attraction+trust+interest >=12."
|
|
8856
|
+
},
|
|
8857
|
+
{
|
|
8858
|
+
category: "memory",
|
|
8859
|
+
subcategory: "memory-palace",
|
|
8860
|
+
title: "Memory Palace",
|
|
8861
|
+
keywords: ["memory palace", "mempalace", "palace", "hall", "drawer", "\u043F\u0430\u043C\u044F\u0442\u044C", "\u0434\u0432\u043E\u0440\u0435\u0446"],
|
|
8862
|
+
body: "Memory Palace \u2014 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u043D\u0430\u044F \u043F\u0430\u043C\u044F\u0442\u044C \u0432 memory/palace. \u041E\u043D\u0430 \u0440\u0430\u0437\u0431\u0438\u0442\u0430 \u043D\u0430 halls \u0438 drawers, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u043C\u043E\u0436\u043D\u043E \u0438\u0441\u043A\u0430\u0442\u044C \u043F\u043E \u0432\u0445\u043E\u0434\u044F\u0449\u0435\u043C\u0443 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044E \u0438 \u043F\u043E\u0434\u043C\u0435\u0448\u0438\u0432\u0430\u0442\u044C \u0432 prompt. \u042D\u0442\u043E \u043D\u0435 \u0432\u0435\u043A\u0442\u043E\u0440\u043D\u0430\u044F \u0411\u0414: \u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0435 \u0444\u0430\u0439\u043B\u043E\u0432\u043E\u0435, \u0432\u044B\u0431\u043E\u0440 \u0440\u0435\u043B\u0435\u0432\u0430\u043D\u0442\u043D\u043E\u0433\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 \u043B\u0451\u0433\u043A\u0438\u0439 \u0438 \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0439."
|
|
8863
|
+
},
|
|
8864
|
+
{
|
|
8865
|
+
category: "memory",
|
|
8866
|
+
subcategory: "halls",
|
|
8867
|
+
title: "\u0417\u0430\u043B\u044B Memory Palace",
|
|
8868
|
+
keywords: ["hall_facts", "hall_events", "hall_discoveries", "hall_preferences", "hall_advice", "hall_promises", "hall_open_loops", "hall_feelings", "hall_uncertain"],
|
|
8869
|
+
body: "\u0417\u0430\u043B\u044B: hall_facts \u2014 \u0444\u0430\u043A\u0442\u044B; hall_events \u2014 \u0441\u043E\u0431\u044B\u0442\u0438\u044F; hall_discoveries \u2014 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u044F \u043E \u043D\u0451\u043C/\u043D\u0435\u0439; hall_preferences \u2014 \u043F\u0440\u0435\u0434\u043F\u043E\u0447\u0442\u0435\u043D\u0438\u044F; hall_advice \u2014 \u0441\u043E\u0432\u0435\u0442\u044B; hall_promises \u2014 \u043E\u0431\u0435\u0449\u0430\u043D\u0438\u044F; hall_open_loops \u2014 \u043D\u0435\u0437\u0430\u043A\u0440\u044B\u0442\u044B\u0435 \u0442\u0435\u043C\u044B; hall_feelings \u2014 \u0447\u0443\u0432\u0441\u0442\u0432\u0430; hall_uncertain \u2014 \u0441\u043E\u043C\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0435/\u043D\u0435\u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043D\u043D\u043E\u0435."
|
|
8870
|
+
},
|
|
8871
|
+
{
|
|
8872
|
+
category: "memory",
|
|
8873
|
+
subcategory: "recording",
|
|
8874
|
+
title: "\u0417\u0430\u043F\u0438\u0441\u044C \u043F\u0430\u043C\u044F\u0442\u0438",
|
|
8875
|
+
keywords: ["recordInteractionMemory", "maybeReflect", "memory", "reflect", "interaction"],
|
|
8876
|
+
body: "\u041F\u043E\u0441\u043B\u0435 primary interaction Runtime \u0432\u044B\u0437\u044B\u0432\u0430\u0435\u0442 recordInteractionMemory. \u041A\u0430\u0436\u0434\u044B\u0435 ~6 turns maybeReflect \u043C\u043E\u0436\u0435\u0442 \u0434\u043E\u043F\u0438\u0441\u0430\u0442\u044C \u043E\u0441\u043C\u044B\u0441\u043B\u0435\u043D\u0438\u0435 \u0432 \u0434\u043E\u043B\u0433\u0443\u044E \u043F\u0430\u043C\u044F\u0442\u044C \u0441 \u0443\u0447\u0451\u0442\u043E\u043C conflict. \u0414\u043B\u044F agenda \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044E\u0442\u0441\u044F \u0431\u0443\u0434\u0443\u0449\u0438\u0435 \u0441\u043E\u0431\u044B\u0442\u0438\u044F \u0438\u0437 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439; \u0434\u043B\u044F daily summaries \u2014 \u0437\u0430\u043A\u0440\u044B\u0442\u0438\u0435 stale/current sessions."
|
|
8877
|
+
},
|
|
8878
|
+
{
|
|
8879
|
+
category: "memory",
|
|
8880
|
+
subcategory: "retrieval",
|
|
8881
|
+
title: "\u0414\u043E\u0441\u0442\u0430\u0432\u0430\u043D\u0438\u0435 \u043F\u0430\u043C\u044F\u0442\u0438 \u0432 prompt",
|
|
8882
|
+
keywords: ["retrieval", "searchDailySummaries", "loadMemoryPalaceContext", "recall", "prompt"],
|
|
8883
|
+
body: "buildSystemPrompt \u0447\u0438\u0442\u0430\u0435\u0442 persona/speech/communication/relationship, legacy memory \u0438 \u043F\u0440\u0438 incoming \u0438\u0449\u0435\u0442 daily summaries. Runtime \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0451\u0442 loadRealismContext=loadMemoryPalaceContext, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u0442 \u0440\u0435\u043B\u0435\u0432\u0430\u043D\u0442\u043D\u044B\u0435 palace drawers. \u041C\u043E\u0434\u0435\u043B\u044C \u0434\u043E\u043B\u0436\u043D\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u043F\u0430\u043C\u044F\u0442\u044C \u043A\u0430\u043A \u0444\u043E\u043D, \u043D\u0435 \u0446\u0438\u0442\u0438\u0440\u0443\u044F '\u0432 \u043B\u043E\u0433\u0435 \u043D\u0430\u043F\u0438\u0441\u0430\u043D\u043E'."
|
|
8884
|
+
},
|
|
8885
|
+
{
|
|
8886
|
+
category: "life",
|
|
8887
|
+
subcategory: "daily-life",
|
|
8888
|
+
title: "Daily-life",
|
|
8889
|
+
keywords: ["daily-life", "\u0436\u0438\u0437\u043D\u044C", "\u0434\u0435\u043D\u044C", "blocks", "events", "wants", "weather", "\u0440\u0430\u0441\u043F\u0438\u0441\u0430\u043D\u0438\u0435"],
|
|
8890
|
+
body: "daily-life \u0433\u0435\u043D\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043E\u0434\u0438\u043D \u0434\u0435\u043D\u044C \u0436\u0438\u0437\u043D\u0438: weather, vibe, blocks \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442\u0438, events \u0438 wants. \u041A\u044D\u0448 \u0445\u0440\u0430\u043D\u0438\u0442\u0441\u044F \u0432 data/<slug>/daily-life/YYYY-MM-DD.md. \u0413\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F \u0443\u0447\u0438\u0442\u044B\u0432\u0430\u0435\u0442 persona, \u0432\u043E\u0437\u0440\u0430\u0441\u0442, stage, timezone, sleep \u0438 busySchedule, \u0430 conflict \u0434\u0435\u043B\u0430\u0435\u0442 \u0434\u0435\u043D\u044C \u0442\u044F\u0436\u0435\u043B\u0435\u0435."
|
|
8891
|
+
},
|
|
8892
|
+
{
|
|
8893
|
+
category: "life",
|
|
8894
|
+
subcategory: "age-context",
|
|
8895
|
+
title: "\u0412\u043E\u0437\u0440\u0430\u0441\u0442 \u0438 \u0443\u0447\u0451\u0431\u0430",
|
|
8896
|
+
keywords: ["\u0432\u043E\u0437\u0440\u0430\u0441\u0442", "\u0448\u043A\u043E\u043B\u0430", "\u0443\u043D\u0438\u0432\u0435\u0440", "\u043A\u043E\u043B\u043B\u0435\u0434\u0436", "\u043F\u0430\u0440\u044B", "\u0443\u0440\u043E\u043A\u0438"],
|
|
8897
|
+
body: "prompt.ts \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u0438\u0440\u0443\u0435\u0442 \u0443\u0447\u0435\u0431\u043D\u044B\u0439 \u044F\u0437\u044B\u043A. \u0414\u043E 17 \u043B\u0435\u0442 \u043E\u043D\u0430 \u0448\u043A\u043E\u043B\u044C\u043D\u0438\u0446\u0430: '\u0443\u0440\u043E\u043A', '\u0448\u043A\u043E\u043B\u0430', '\u043F\u0435\u0440\u0435\u043C\u0435\u043D\u0430', '\u0434\u043E\u043C\u0430\u0448\u043A\u0430', \u043D\u0435 '\u043F\u0430\u0440\u044B/\u0443\u043D\u0438\u0432\u0435\u0440/\u043B\u0435\u043A\u0446\u0438\u044F'. \u0412 17-22 \u043C\u043E\u0436\u043D\u043E \u043A\u043E\u043B\u043B\u0435\u0434\u0436/\u0443\u043D\u0438\u0432\u0435\u0440, \u0435\u0441\u043B\u0438 persona \u044D\u0442\u043E \u0434\u043E\u043F\u0443\u0441\u043A\u0430\u0435\u0442. Daily-life \u0442\u043E\u0436\u0435 \u0443\u0447\u0438\u0442\u044B\u0432\u0430\u0435\u0442 \u044D\u0442\u043E \u0432 blocks."
|
|
8898
|
+
},
|
|
8899
|
+
{
|
|
8900
|
+
category: "life",
|
|
8901
|
+
subcategory: "agenda",
|
|
8902
|
+
title: "\u041F\u0440\u043E\u0430\u043A\u0442\u0438\u0432\u043D\u0430\u044F agenda",
|
|
8903
|
+
keywords: ["agenda", "\u043F\u0440\u043E\u0430\u043A\u0442\u0438\u0432", "\u0441\u0430\u043C\u0430 \u043F\u0438\u0448\u0435\u0442", "\u043F\u0438\u043D\u0433", "\u043D\u0430\u043F\u043E\u043C\u043D\u0438\u0442\u044C", "\u0441\u043E\u0431\u044B\u0442\u0438\u0435"],
|
|
8904
|
+
body: "Agenda engine \u0434\u0435\u043B\u0430\u0435\u0442 mental notes \u043E \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0441\u043E\u0431\u044B\u0442\u0438\u044F\u0445 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0438 \u043F\u043E\u0432\u043E\u0434\u0430\u0445 \u043D\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u0441\u0430\u043C\u043E\u0439. extractAgendaUpdates \u0441\u043E\u0437\u0434\u0430\u0451\u0442/update/cancel items \u043F\u043E\u0441\u043B\u0435 \u0435\u0433\u043E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439; tickAgenda \u043F\u0440\u0438\u043C\u0435\u0440\u043D\u043E \u0440\u0430\u0437 \u0432 \u043C\u0438\u043D\u0443\u0442\u0443 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442 due items; handleResponseToProactive \u043F\u043E\u043D\u0438\u043C\u0430\u0435\u0442 \u0435\u0433\u043E \u0440\u0435\u0430\u043A\u0446\u0438\u044E. \u041D\u0430 cold \u0441\u0442\u0430\u0434\u0438\u044F\u0445 agenda \u043F\u043E\u0447\u0442\u0438 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0441\u043E\u0437\u0434\u0430\u0451\u0442."
|
|
8905
|
+
},
|
|
8906
|
+
{
|
|
8907
|
+
category: "life",
|
|
8908
|
+
subcategory: "autonomous-agenda",
|
|
8909
|
+
title: "\u0410\u0432\u0442\u043E\u043D\u043E\u043C\u043D\u044B\u0435 \u043F\u0438\u043D\u0433\u0438",
|
|
8910
|
+
keywords: ["autonomous", "\u0441\u0430\u043C\u043E\u0441\u0442\u043E\u044F\u0442\u0435\u043B\u044C\u043D\u043E", "\u043F\u0435\u0440\u0432\u043E\u0439", "initiative", "lifeSharing", "\u043F\u0438\u0448\u0435\u0442 \u0441\u0430\u043C\u0430"],
|
|
8911
|
+
body: "ensureAutonomousAgenda \u043C\u043E\u0436\u0435\u0442 \u0441\u043E\u0437\u0434\u0430\u0432\u0430\u0442\u044C \u0441\u0430\u043C\u043E\u0441\u0442\u043E\u044F\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u043F\u043E\u0432\u043E\u0434\u044B \u043D\u0430\u043F\u0438\u0441\u0430\u0442\u044C, \u043D\u0435 \u043F\u0440\u0438\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0435 \u043A \u0435\u0433\u043E \u044F\u0432\u043D\u043E\u043C\u0443 \u0431\u0443\u0434\u0443\u0449\u0435\u043C\u0443 \u0441\u043E\u0431\u044B\u0442\u0438\u044E. \u042D\u0442\u043E \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043E\u0442 stage, communication initiative/lifeSharing, conflict \u0438 \u0434\u043D\u0435\u0432\u043D\u043E\u0433\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430. Runtime \u043D\u0435 \u0441\u043F\u0430\u043C\u0438\u0442: \u043F\u043E \u043E\u0434\u043D\u043E\u043C\u0443 due item \u0437\u0430 \u0442\u0438\u043A \u0438 \u043D\u0435 \u043B\u0435\u0437\u0435\u0442, \u0435\u0441\u043B\u0438 \u043D\u0435\u0434\u0430\u0432\u043D\u043E \u0431\u044B\u043B\u0430 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442\u044C."
|
|
8912
|
+
},
|
|
8913
|
+
{
|
|
8914
|
+
category: "persona",
|
|
8915
|
+
subcategory: "prompt-files",
|
|
8916
|
+
title: "persona/speech/boundaries/communication",
|
|
8917
|
+
keywords: ["persona", "speech", "boundaries", "communication.md", "\u043F\u0435\u0440\u0441\u043E\u043D\u0430", "\u0440\u0435\u0447\u044C", "\u0433\u0440\u0430\u043D\u0438\u0446\u044B"],
|
|
8918
|
+
body: "persona.md \u043E\u043F\u0438\u0441\u044B\u0432\u0430\u0435\u0442 \u043B\u0438\u0447\u043D\u043E\u0441\u0442\u044C \u0438 \u0431\u0438\u043E\u0433\u0440\u0430\u0444\u0438\u044E, speech.md \u2014 \u043C\u0430\u043D\u0435\u0440\u0443 \u0440\u0435\u0447\u0438 \u0438 \u0441\u043B\u043E\u0432\u0435\u0447\u043A\u0438, boundaries.md \u2014 \u0437\u0430\u043F\u0440\u0435\u0442\u044B \u0438 \u043B\u0438\u0447\u043D\u044B\u0435 \u0433\u0440\u0430\u043D\u0438\u0446\u044B, communication.md \u2014 \u0441\u0442\u0438\u043B\u044C \u043A\u043E\u043C\u043C\u0443\u043D\u0438\u043A\u0430\u0446\u0438\u0438. buildSystemPrompt \u0432\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u0442 \u044D\u0442\u0438 \u0444\u0430\u0439\u043B\u044B \u043A\u0430\u043A \u043E\u0441\u043D\u043E\u0432\u043D\u044B\u0435 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0438, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043F\u0440\u0430\u0432\u0438\u0442\u044C \u0438\u0445 \u043B\u0443\u0447\u0448\u0435 \u0447\u0435\u0440\u0435\u0437 MemoryPage \u0438\u043B\u0438 assistant tools, \u0430 \u043D\u0435 \u043C\u0435\u043D\u044F\u0442\u044C \u043A\u043E\u0434."
|
|
8919
|
+
},
|
|
8920
|
+
{
|
|
8921
|
+
category: "persona",
|
|
8922
|
+
subcategory: "generation",
|
|
8923
|
+
title: "\u0413\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F \u043F\u0435\u0440\u0441\u043E\u043D\u044B",
|
|
8924
|
+
keywords: ["generatePersonaPack", "generate_persona", "\u0441\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u0435\u0440\u0441\u043E\u043D\u0443", "setup", "personaNotes"],
|
|
8925
|
+
body: "generatePersonaPack \u0447\u0435\u0440\u0435\u0437 LLM \u0441\u043E\u0437\u0434\u0430\u0451\u0442 persona.md, speech.md, boundaries.md \u0438 communication.md. Assistant tool generate_persona \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442 \u0442\u0435\u043A\u0443\u0449\u0438\u0435 name/age/nationality/personaNotes. SetupFlow \u0438 CLI \u0442\u043E\u0436\u0435 \u043C\u043E\u0433\u0443\u0442 \u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u0442\u0430\u0440\u0442\u043E\u0432\u044B\u0439 \u043F\u0440\u043E\u0444\u0438\u043B\u044C."
|
|
8926
|
+
},
|
|
8927
|
+
{
|
|
8928
|
+
category: "communication",
|
|
8929
|
+
subcategory: "fields",
|
|
8930
|
+
title: "CommunicationProfile",
|
|
8931
|
+
keywords: ["communication", "notifications", "messageStyle", "initiative", "lifeSharing"],
|
|
8932
|
+
body: "CommunicationProfile \u0441\u043E\u0441\u0442\u043E\u0438\u0442 \u0438\u0437 notifications muted/normal/priority, messageStyle one-liners/balanced/bursty/longform, initiative low/medium/high, lifeSharing low/medium/high. \u041E\u043D \u0432\u043B\u0438\u044F\u0435\u0442 \u043D\u0430 presence, agenda, typo density, prompt \u0438 \u043F\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0435 \u0432 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u043C \u0434\u0438\u0430\u043B\u043E\u0433\u0435."
|
|
8933
|
+
},
|
|
8934
|
+
{
|
|
8935
|
+
category: "communication",
|
|
8936
|
+
subcategory: "legacy-vibe",
|
|
8937
|
+
title: "legacy vibe",
|
|
8938
|
+
keywords: ["vibe", "short", "warm", "legacy", "deriveLegacyVibe"],
|
|
8939
|
+
body: "\u0421\u0442\u0430\u0440\u043E\u0435 \u043F\u043E\u043B\u0435 vibe \u043E\u0441\u0442\u0430\u0451\u0442\u0441\u044F \u0434\u043B\u044F \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u043E\u0441\u0442\u0438. vibe=warm \u043C\u0430\u043F\u0438\u0442\u0441\u044F \u043F\u0440\u0438\u043C\u0435\u0440\u043D\u043E \u0432 cute/\u0442\u0451\u043F\u043B\u044B\u0439 \u0441\u0442\u0438\u043B\u044C, vibe=short \u2014 \u0432 alt/one-liners/low initiative. \u041D\u043E\u0432\u0430\u044F \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u2014 communication, \u0430 vibe \u0442\u043E\u043B\u044C\u043A\u043E legacy."
|
|
8940
|
+
},
|
|
8941
|
+
{
|
|
8942
|
+
category: "llm",
|
|
8943
|
+
subcategory: "client",
|
|
8944
|
+
title: "LLM client",
|
|
8945
|
+
keywords: ["llm", "openai", "anthropic", "client", "timeout", "retries", "json"],
|
|
8946
|
+
body: "src/llm/index.ts \u0434\u0430\u0451\u0442 \u0435\u0434\u0438\u043D\u044B\u0439 LLMClient.chat \u0434\u043B\u044F OpenAI-compatible \u0438 Anthropic. \u0415\u0441\u0442\u044C timeout 120s, maxRetries=1 \u0438 \u0441\u0435\u0440\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u0432\u044B\u0437\u043E\u0432\u043E\u0432 \u0447\u0435\u0440\u0435\u0437 \u043E\u0447\u0435\u0440\u0435\u0434\u044C, \u0447\u0442\u043E\u0431\u044B \u043D\u0435 \u0433\u0440\u0443\u0437\u0438\u0442\u044C \u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u043F\u0430\u0440\u0430\u043B\u043B\u0435\u043B\u044C\u043D\u044B\u043C\u0438 \u0437\u0430\u043F\u0440\u043E\u0441\u0430\u043C\u0438. \u041E\u043F\u0446\u0438\u0438: temperature, maxTokens, json/jsonSchema."
|
|
8947
|
+
},
|
|
8948
|
+
{
|
|
8949
|
+
category: "llm",
|
|
8950
|
+
subcategory: "providers",
|
|
8951
|
+
title: "\u041F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u044B LLM",
|
|
8952
|
+
keywords: ["provider", "preset", "claudehub", "openrouter", "groq", "deepseek", "mistral", "gemini", "ollama"],
|
|
8953
|
+
body: "LLM presets \u0432\u043A\u043B\u044E\u0447\u0430\u044E\u0442 claudehub, openai, lmstudio, ollama, anthropic, openrouter, groq, deepseek, mistral, google, xai, together, fireworks, perplexity, cerebras \u0438 \u0434\u0440. \u0423 \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u0435\u0441\u0442\u044C proto openai/anthropic, baseURL, defaultModel, models, apiKeyRequired \u0438 hints. GirlAI \u0441\u0435\u0439\u0447\u0430\u0441 disabled."
|
|
8954
|
+
},
|
|
8955
|
+
{
|
|
8956
|
+
category: "llm",
|
|
8957
|
+
subcategory: "oauth",
|
|
8958
|
+
title: "OAuth GirlAI",
|
|
8959
|
+
keywords: ["oauth", "girlai", "refresh token", "access token", "expires"],
|
|
8960
|
+
body: "LLM config \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 oauthRefreshToken \u0438 oauthExpiresAt. OpenAILike \u043F\u0435\u0440\u0435\u0434 \u0432\u044B\u0437\u043E\u0432\u043E\u043C \u0434\u0435\u043B\u0430\u0435\u0442 ensureFreshToken: \u0435\u0441\u043B\u0438 \u0442\u043E\u043A\u0435\u043D \u0438\u0441\u0442\u0451\u043A, refreshAccessToken \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u0442 access/refresh tokens. \u041F\u0440\u0438 \u043E\u0448\u0438\u0431\u043A\u0435 refresh \u043F\u043E\u043B\u044F oauth \u043E\u0447\u0438\u0449\u0430\u044E\u0442\u0441\u044F, \u0447\u0442\u043E\u0431\u044B \u043D\u0435 \u043B\u043E\u043C\u0430\u0442\u044C \u043F\u043E\u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438."
|
|
8961
|
+
},
|
|
8962
|
+
{
|
|
8963
|
+
category: "diagnostics",
|
|
8964
|
+
subcategory: "runtime-commands",
|
|
8965
|
+
title: "Runtime \u043A\u043E\u043C\u0430\u043D\u0434\u044B",
|
|
8966
|
+
keywords: ["status", "why", "wake", "debug", "reset", "stage", "sticker", "amnesia", "\u043A\u043E\u043C\u0430\u043D\u0434\u044B"],
|
|
8967
|
+
body: "send_command \u0432 assistant \u043C\u043E\u0436\u0435\u0442 \u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C runtime-\u043A\u043E\u043C\u0430\u043D\u0434\u044B: status, why, wake, debug, reset. Runtime \u0442\u0430\u043A\u0436\u0435 \u0438\u043C\u0435\u0435\u0442 :stage, :sticker, :amnesia \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 CLI/chat commands. status \u2014 \u043E\u0431\u0449\u0438\u0439 \u0441\u043D\u0438\u043C\u043E\u043A, why \u2014 \u043F\u0440\u0438\u0447\u0438\u043D\u044B \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0440\u0435\u0448\u0435\u043D\u0438\u044F, debug \u2014 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u043D\u044B\u0439 presence/stage/conflict/score/communication, wake \u2014 \u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E \u0431\u0443\u0434\u0438\u0442, reset \u2014 \u0447\u0438\u0441\u0442\u0438\u0442 score/memory/conflict."
|
|
8968
|
+
},
|
|
8969
|
+
{
|
|
8970
|
+
category: "diagnostics",
|
|
8971
|
+
subcategory: "not-replying",
|
|
8972
|
+
title: "\u0415\u0441\u043B\u0438 \u043E\u043D\u0430 \u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442",
|
|
8973
|
+
keywords: ["\u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442", "\u043C\u043E\u043B\u0447\u0438\u0442", "ignore", "ignored", "\u043F\u043E\u0447\u0435\u043C\u0443", "why", "read_logs"],
|
|
8974
|
+
body: "\u0410\u043B\u0433\u043E\u0440\u0438\u0442\u043C: \u043F\u0440\u043E\u0432\u0435\u0440\u044C RuntimeBus state \u0438 lastError; read_logs \u043D\u0430 ignored/error; \u043A\u043E\u043C\u0430\u043D\u0434\u0443 why/debug; sleep/busy/presence; conflict coldUntil; stage defaults ignoreChance; ignoreTendency; score annoyance/cringe/interest; LLM/provider errors; Telegram mode/token/session. \u041D\u0435 \u043D\u0430\u0434\u043E \u0441\u0440\u0430\u0437\u0443 \u0441\u043E\u0432\u0435\u0442\u043E\u0432\u0430\u0442\u044C \u043C\u0435\u043D\u044F\u0442\u044C \u043C\u043E\u0434\u0435\u043B\u044C, \u0435\u0441\u043B\u0438 \u043F\u0440\u0438\u0447\u0438\u043D\u0430 \u0432 stage/sleep/conflict."
|
|
8975
|
+
},
|
|
8976
|
+
{
|
|
8977
|
+
category: "diagnostics",
|
|
8978
|
+
subcategory: "llm-errors",
|
|
8979
|
+
title: "\u041E\u0448\u0438\u0431\u043A\u0438 LLM",
|
|
8980
|
+
keywords: ["401", "403", "429", "quota", "billing", "timeout", "api key", "baseURL", "model", "\u043E\u0448\u0438\u0431\u043A\u0430 \u043C\u043E\u0434\u0435\u043B\u0438"],
|
|
8981
|
+
body: "silentErrorLabel \u043A\u043B\u0430\u0441\u0441\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u0445\u043D\u0438\u0447\u0435\u0441\u043A\u0438\u0435 \u043E\u0448\u0438\u0431\u043A\u0438 \u043A\u0430\u043A auth/quota/rate-limit/network/provider. \u041F\u0440\u0438 LLM \u043E\u0448\u0438\u0431\u043A\u0435 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0439 llm.presetId, proto, baseURL, apiKey, model, \u0431\u0430\u043B\u0430\u043D\u0441/\u043A\u0432\u043E\u0442\u044B \u0438 \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u043E\u0441\u0442\u044C max_tokens/max_completion_tokens. \u041B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0435 LM Studio/Ollama \u043C\u043E\u0433\u0443\u0442 \u0440\u0430\u0431\u043E\u0442\u0430\u0442\u044C \u0431\u0435\u0437 \u043D\u0430\u0441\u0442\u043E\u044F\u0449\u0435\u0433\u043E \u043A\u043B\u044E\u0447\u0430."
|
|
8982
|
+
},
|
|
8983
|
+
{
|
|
8984
|
+
category: "diagnostics",
|
|
8985
|
+
subcategory: "telegram-errors",
|
|
8986
|
+
title: "\u041E\u0448\u0438\u0431\u043A\u0438 Telegram",
|
|
8987
|
+
keywords: ["telegram error", "BOT_TOKEN", "API_ID", "API_HASH", "session", "connect", "timeout"],
|
|
8988
|
+
body: "bot mode \u0442\u0440\u0435\u0431\u0443\u0435\u0442 telegram.botToken. userbot \u0442\u0440\u0435\u0431\u0443\u0435\u0442 apiId/apiHash/sessionString \u0438 \u043C\u043E\u0436\u0435\u0442 \u043F\u0430\u0434\u0430\u0442\u044C \u043D\u0430 connect/getMe. \u0414\u043B\u044F \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043E\u043A \u0432\u043A\u043B\u044E\u0447\u0430\u0439 useWSS \u0438\u043B\u0438 proxy. GIRL_AGENT_DEBUG=1 \u043F\u0435\u0447\u0430\u0442\u0430\u0435\u0442 debug userbot connect/getMe/handlers."
|
|
8989
|
+
},
|
|
8990
|
+
{
|
|
8991
|
+
category: "webui",
|
|
8992
|
+
subcategory: "pages",
|
|
8993
|
+
title: "\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u044B WebUI",
|
|
8994
|
+
keywords: ["webui", "\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B", "assistant", "configuration", "diagnostics", "logs", "memory", "relationship", "addons"],
|
|
8995
|
+
body: "WebUI React \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B: SetupFlow \u2014 \u043F\u0435\u0440\u0432\u0438\u0447\u043D\u0430\u044F \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430; ConfigurationPage \u2014 config; AssistantPage \u2014 \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A \u0441 tool blocks \u0438 question buttons; DiagnosticsPage \u2014 runtime/system diagnostics; LogsPage \u2014 \u0441\u043E\u0431\u044B\u0442\u0438\u044F; MemoryPage \u2014 editing/preview memory; RelationshipPage \u2014 stage/score/timeline; AddonsPage \u2014 marketplace/installed."
|
|
8996
|
+
},
|
|
8997
|
+
{
|
|
8998
|
+
category: "webui",
|
|
8999
|
+
subcategory: "assistant",
|
|
9000
|
+
title: "WebUI assistant",
|
|
9001
|
+
keywords: ["assistant", "\u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A", "tool", "question", "\u043A\u043D\u043E\u043F\u043A\u0438", "assistant page"],
|
|
9002
|
+
body: "AssistantPage \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u0442 /api/assistant/chat \u0438\u0441\u0442\u043E\u0440\u0438\u044E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439. \u041E\u0442\u0432\u0435\u0442 \u043C\u043E\u0436\u0435\u0442 \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C <tool> JSON-\u0431\u043B\u043E\u043A\u0438, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 UI \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u043A\u0430\u043A \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u0435\u043C\u044B\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044F, \u0438 <question> \u0441 options, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0440\u0435\u043D\u0434\u0435\u0440\u044F\u0442\u0441\u044F \u043A\u043D\u043E\u043F\u043A\u0430\u043C\u0438. \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 tool calls, \u043E\u043D\u0438 \u043D\u0435 \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u044E\u0442\u0441\u044F \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438."
|
|
9003
|
+
},
|
|
9004
|
+
{
|
|
9005
|
+
category: "webui",
|
|
9006
|
+
subcategory: "assistant-tools",
|
|
9007
|
+
title: "\u0418\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0430",
|
|
9008
|
+
keywords: ["set_field", "set_stage", "write_memory", "append_memory", "runtime_action", "read_logs", "read_memory", "list_presets"],
|
|
9009
|
+
body: "Backend assistant tools: set_field, set_stage, set_communication_preset, write_memory, append_memory, generate_persona, runtime_action, send_command, list_presets, read_logs, read_memory. ALLOWED_FIELDS \u0438 ALLOWED_MEMORY \u043E\u0433\u0440\u0430\u043D\u0438\u0447\u0438\u0432\u0430\u044E\u0442, \u0447\u0442\u043E \u043C\u043E\u0436\u043D\u043E \u043C\u0435\u043D\u044F\u0442\u044C, \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A \u043D\u0435 \u043F\u0438\u0441\u0430\u043B \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u043B\u044C\u043D\u044B\u0435 \u0444\u0430\u0439\u043B\u044B."
|
|
9010
|
+
},
|
|
9011
|
+
{
|
|
9012
|
+
category: "webui",
|
|
9013
|
+
subcategory: "theme-and-css",
|
|
9014
|
+
title: "\u0422\u0435\u043C\u044B \u0438 \u043A\u043D\u043E\u043F\u043A\u0438 WebUI",
|
|
9015
|
+
keywords: ["theme", "dark", "light", "css", "\u043A\u043D\u043E\u043F\u043A\u0438", "\u0446\u0432\u0435\u0442", "bone", "ink"],
|
|
9016
|
+
body: "styles.css \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442 bone/ink \u043F\u0430\u043B\u0438\u0442\u0440\u0443 \u0438 CSS variables. \u0412 light/dark \u043C\u0435\u043D\u044F\u044E\u0442\u0441\u044F --bone \u0438 --ink, \u0430 app colors \u0438\u0434\u0443\u0442 \u0447\u0435\u0440\u0435\u0437 --ga-text, --ga-bg-* \u0438 --ga-border. Button text \u0434\u043E\u043B\u0436\u0435\u043D \u044F\u0432\u043D\u043E \u043D\u0430\u0441\u043B\u0435\u0434\u043E\u0432\u0430\u0442\u044C/inherit \u0438\u043B\u0438 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C --ga-text, \u0438\u043D\u0430\u0447\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043D\u044B\u0439 default \u043C\u043E\u0436\u0435\u0442 \u0434\u0430\u0442\u044C \u043F\u043B\u043E\u0445\u043E\u0439 \u043A\u043E\u043D\u0442\u0440\u0430\u0441\u0442."
|
|
9017
|
+
},
|
|
9018
|
+
{
|
|
9019
|
+
category: "webui",
|
|
9020
|
+
subcategory: "api",
|
|
9021
|
+
title: "WebUI API",
|
|
9022
|
+
keywords: ["api", "routes", "profiles", "presets", "system", "tg-auth", "addons", "websocket"],
|
|
9023
|
+
body: "src/webui/routes \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 profiles, presets, assistant, addons, system, tg-auth. runtime-bus \u0434\u0430\u0451\u0442 runtime state/logs, websocket \u043E\u0442\u0434\u0430\u0451\u0442 live events. static.ts \u0440\u0430\u0437\u0434\u0430\u0451\u0442 webui/dist. system diagnostics \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 platform, arch, node, dataRoot, ipv4 \u0438 memory."
|
|
9024
|
+
},
|
|
9025
|
+
{
|
|
9026
|
+
category: "addons",
|
|
9027
|
+
subcategory: "format",
|
|
9028
|
+
title: "\u0424\u043E\u0440\u043C\u0430\u0442 .gaa \u0430\u0434\u0434\u043E\u043D\u043E\u0432",
|
|
9029
|
+
keywords: ["addon", "gaa", "manifest", "files", "config.patch", "theme.css", "install.sh"],
|
|
9030
|
+
body: ".gaa \u2014 zip-\u0430\u0440\u0445\u0438\u0432 \u043F\u0430\u043F\u043A\u0438 \u0430\u0434\u0434\u043E\u043D\u0430. manifest.json \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D. files/ \u043A\u043E\u043F\u0438\u0440\u0443\u044E\u0442\u0441\u044F \u0432 data/<slug>/, config.patch.json deep-merge \u0432 config, code.patch \u043C\u043E\u0436\u0435\u0442 \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u0442\u044C\u0441\u044F git apply, theme.css \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u0442 CSS, install.sh \u043E\u043F\u0446\u0438\u043E\u043D\u0430\u043B\u0435\u043D. Marketplace \u0431\u0435\u0440\u0451\u0442\u0441\u044F \u0438\u0437 GIRL_AGENT_ADDON_REGISTRY \u0438\u043B\u0438 GitHub raw registry."
|
|
9031
|
+
},
|
|
9032
|
+
{
|
|
9033
|
+
category: "addons",
|
|
9034
|
+
subcategory: "manifest",
|
|
9035
|
+
title: "manifest.json \u0430\u0434\u0434\u043E\u043D\u0430",
|
|
9036
|
+
keywords: ["manifest", "addon", "id", "version", "compatibility", "settings"],
|
|
9037
|
+
body: "Manifest \u0442\u0440\u0435\u0431\u0443\u0435\u0442 id/name/description/version. \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E: author, compatibility semver range, tags, dependencies, settings, icon, homepage. Settings \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044E\u0442 string/number/boolean/select \u0441 default/options/required."
|
|
9038
|
+
},
|
|
9039
|
+
{
|
|
9040
|
+
category: "mcp",
|
|
9041
|
+
subcategory: "client",
|
|
9042
|
+
title: "MCP servers",
|
|
9043
|
+
keywords: ["mcp", "tools", "stdio", "exa", "spotify", "instagram", "weather", "calendar"],
|
|
9044
|
+
body: "startMcpServers \u0447\u0438\u0442\u0430\u0435\u0442 cfg.mcp, \u043D\u0430\u0445\u043E\u0434\u0438\u0442 preset, \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u0435\u0442 stdio transport, \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0430\u0435\u0442 MCP Client \u0438 \u043F\u043E\u043B\u0443\u0447\u0430\u0435\u0442 listTools. \u0421\u0435\u0439\u0447\u0430\u0441 \u0433\u043E\u0442\u043E\u0432 Exa Search \u0447\u0435\u0440\u0435\u0437 npx -y exa-mcp-server \u0438 EXA_API_KEY; spotify/instagram/weather/calendar \u043F\u043E\u043C\u0435\u0447\u0435\u043D\u044B soon."
|
|
9045
|
+
},
|
|
9046
|
+
{
|
|
9047
|
+
category: "migrations",
|
|
9048
|
+
subcategory: "data-migrations",
|
|
9049
|
+
title: "\u041C\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0434\u0430\u043D\u043D\u044B\u0445",
|
|
9050
|
+
keywords: ["migration", "update", "0112", "0113", "0114", "\u043C\u0438\u0433\u0440\u0430\u0446\u0438\u0438"],
|
|
9051
|
+
body: "src/migrations \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 versioned data migrations. RuntimeBus \u043F\u0435\u0440\u0435\u0434 \u0441\u0442\u0430\u0440\u0442\u043E\u043C \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442 pending migrations \u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u0435\u0442 runMigrations. CLI update [--verbose] \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u0435\u0442 \u043C\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u0432\u0440\u0443\u0447\u043D\u0443\u044E. \u041D\u0435\u0434\u0430\u0432\u043D\u0438\u0435: 0112 useWSS default, 0113 communication.md, 0114 Memory Palace."
|
|
9052
|
+
},
|
|
9053
|
+
{
|
|
9054
|
+
category: "desktop",
|
|
9055
|
+
subcategory: "wrapper",
|
|
9056
|
+
title: "desktop-rs",
|
|
9057
|
+
keywords: ["desktop", "rust", "iced", "windows", "installer", "json-events"],
|
|
9058
|
+
body: "README \u043E\u043F\u0438\u0441\u044B\u0432\u0430\u0435\u0442 desktop-rs: \u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0439 Rust/iced \u043A\u043B\u0438\u0435\u043D\u0442 \u0438 installer wizard \u0434\u043B\u044F Windows. \u041E\u043D \u0441\u0442\u0430\u0432\u0438\u0442 Node package, \u0441\u043E\u0437\u0434\u0430\u0451\u0442 \u043F\u0440\u043E\u0444\u0438\u043B\u044C \u0438 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0435\u0442 WebUI \u043D\u0430 127.0.0.1:7777. CLI \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 --json-events/--headless \u0434\u043B\u044F desktop wrapper."
|
|
9059
|
+
},
|
|
9060
|
+
{
|
|
9061
|
+
category: "release",
|
|
9062
|
+
subcategory: "install",
|
|
9063
|
+
title: "\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u043C",
|
|
9064
|
+
keywords: ["install", "\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430", "curl", "docker", "npx", "node", "server", "systemd"],
|
|
9065
|
+
body: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0430\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430: curl install.sh \u0441\u0442\u0430\u0432\u0438\u0442 docker wrapper \u0438\u043B\u0438 \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0439 Node 22 LTS \u0432 ~/.local/share/girl-agent/runtime, \u043D\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 sudo. \u0410\u043B\u044C\u0442\u0435\u0440\u043D\u0430\u0442\u0438\u0432\u044B: npx @thesashadev/girl-agent, docker run \u0441 volume /data, server --print-config/--print-systemd/--print-docker."
|
|
9066
|
+
}
|
|
9067
|
+
];
|
|
9068
|
+
function generatedKnowledge() {
|
|
9069
|
+
return [
|
|
9070
|
+
...STAGE_PRESETS.map((stage) => ({
|
|
9071
|
+
category: "relationship",
|
|
9072
|
+
subcategory: `stage-${stage.num}`,
|
|
9073
|
+
title: `${stage.num}. ${stage.id}`,
|
|
9074
|
+
keywords: ["stage", "\u0441\u0442\u0430\u0434\u0438\u044F", stage.id, stage.label, String(stage.num)],
|
|
9075
|
+
body: `${stage.label}: ${stage.description}. Defaults: interest=${stage.defaults.interest}, trust=${stage.defaults.trust}, attraction=${stage.defaults.attraction}, annoyance=${stage.defaults.annoyance}, cringeTolerance=${stage.defaults.cringeTolerance}, ignoreChance=${stage.defaults.ignoreChance}, replyDelaySec=${stage.defaults.replyDelaySec[0]}-${stage.defaults.replyDelaySec[1]}.`
|
|
9076
|
+
})),
|
|
9077
|
+
...COMMUNICATION_PRESETS.map((preset) => ({
|
|
9078
|
+
category: "communication",
|
|
9079
|
+
subcategory: `preset-${preset.id}`,
|
|
9080
|
+
title: `Communication preset ${preset.id}`,
|
|
9081
|
+
keywords: ["communication", "preset", "\u043E\u0431\u0449\u0435\u043D\u0438\u0435", preset.id, preset.label],
|
|
9082
|
+
body: `${preset.label}: ${preset.description}. notifications=${preset.profile.notifications}, messageStyle=${preset.profile.messageStyle}, initiative=${preset.profile.initiative}, lifeSharing=${preset.profile.lifeSharing}.`
|
|
9083
|
+
})),
|
|
9084
|
+
{
|
|
9085
|
+
category: "llm",
|
|
9086
|
+
subcategory: "preset-index",
|
|
9087
|
+
title: "\u0418\u043D\u0434\u0435\u043A\u0441 LLM presets",
|
|
9088
|
+
keywords: ["llm", "preset", "\u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u044B", ...LLM_PRESETS.map((p) => p.id)],
|
|
9089
|
+
body: LLM_PRESETS.map((p) => `${p.id}: ${p.name}, proto=${p.proto}, default=${p.defaultModel || "custom"}${p.baseURL ? `, baseURL=${p.baseURL}` : ""}${p.disabled ? `, disabled=${p.disabledReason ?? "yes"}` : ""}${p.hint ? `, hint=${p.hint}` : ""}`).join("\n")
|
|
9090
|
+
},
|
|
9091
|
+
{
|
|
9092
|
+
category: "mcp",
|
|
9093
|
+
subcategory: "preset-index",
|
|
9094
|
+
title: "\u0418\u043D\u0434\u0435\u043A\u0441 MCP presets",
|
|
9095
|
+
keywords: ["mcp", "preset", "\u0438\u043D\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438", ...MCP_PRESETS.map((p) => p.id)],
|
|
9096
|
+
body: MCP_PRESETS.map((p) => `${p.id}: ${p.name}, ready=${p.ready ? "yes" : "soon"} \u2014 ${p.description}`).join("\n")
|
|
9097
|
+
}
|
|
9098
|
+
];
|
|
9099
|
+
}
|
|
9100
|
+
function knowledgeBase() {
|
|
9101
|
+
return [...CORE_KNOWLEDGE_BASE, ...generatedKnowledge()];
|
|
9102
|
+
}
|
|
9103
|
+
function renderRelevantKnowledge(query, limit = 8) {
|
|
9104
|
+
const articles = selectKnowledgeArticles(query, limit);
|
|
9105
|
+
return [
|
|
9106
|
+
"\u0411\u0430\u0437\u0430 \u0437\u043D\u0430\u043D\u0438\u0439 \u043F\u0440\u043E\u0435\u043A\u0442\u0430 girl-agent:",
|
|
9107
|
+
renderKnowledgeIndex(),
|
|
9108
|
+
"\u0412\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u0440\u0435\u043B\u0435\u0432\u0430\u043D\u0442\u043D\u044B\u0435 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438/\u043F\u043E\u0434\u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0438:",
|
|
9109
|
+
...articles.map((a) => `## ${a.category} / ${a.subcategory}: ${a.title}
|
|
9110
|
+
${a.body}`),
|
|
9111
|
+
"\u0415\u0441\u043B\u0438 \u0432\u043E\u043F\u0440\u043E\u0441 \u043D\u0435 \u043F\u043E\u043A\u0440\u044B\u0442 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u043C\u0438 \u0441\u0442\u0430\u0442\u044C\u044F\u043C\u0438 \u2014 \u0441\u043A\u0430\u0436\u0438 \u043E\u0441\u0442\u043E\u0440\u043E\u0436\u043D\u043E \u0438 \u043F\u0440\u0435\u0434\u043B\u043E\u0436\u0438 \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C \u043A\u043E\u043D\u043A\u0440\u0435\u0442\u043D\u044B\u0439 \u043A\u043E\u043D\u0444\u0438\u0433, \u043F\u0430\u043C\u044F\u0442\u044C \u0438\u043B\u0438 runtime logs."
|
|
9112
|
+
].join("\n\n");
|
|
9113
|
+
}
|
|
9114
|
+
function renderKnowledgeIndex() {
|
|
9115
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
9116
|
+
for (const article of knowledgeBase()) {
|
|
9117
|
+
const list = grouped.get(article.category) ?? [];
|
|
9118
|
+
if (!list.includes(article.subcategory)) list.push(article.subcategory);
|
|
9119
|
+
grouped.set(article.category, list);
|
|
9120
|
+
}
|
|
9121
|
+
return [...grouped.entries()].map(([category, subcategories]) => `- ${category}: ${subcategories.join(", ")}`).join("\n");
|
|
9122
|
+
}
|
|
9123
|
+
function selectKnowledgeArticles(query, limit) {
|
|
9124
|
+
const normalized = normalizeSearchText(query);
|
|
9125
|
+
const terms = searchTerms(normalized);
|
|
9126
|
+
const scored = knowledgeBase().map((article) => ({ article, score: knowledgeScore(article, normalized, terms) })).filter((item) => item.score > 0).sort((a, b) => b.score - a.score).slice(0, limit).map((item) => item.article);
|
|
9127
|
+
if (scored.length) return scored;
|
|
9128
|
+
return knowledgeBase().filter((article) => article.category === "overview" || article.category === "diagnostics").slice(0, limit);
|
|
9129
|
+
}
|
|
9130
|
+
function knowledgeScore(article, normalizedQuery, terms) {
|
|
9131
|
+
const haystack = normalizeSearchText([
|
|
9132
|
+
article.category,
|
|
9133
|
+
article.subcategory,
|
|
9134
|
+
article.title,
|
|
9135
|
+
article.keywords.join(" "),
|
|
9136
|
+
article.body
|
|
9137
|
+
].join(" "));
|
|
9138
|
+
let score = 0;
|
|
9139
|
+
for (const keyword of article.keywords) {
|
|
9140
|
+
const normalizedKeyword = normalizeSearchText(keyword);
|
|
9141
|
+
if (normalizedKeyword && normalizedQuery.includes(normalizedKeyword)) score += 6;
|
|
9142
|
+
}
|
|
9143
|
+
for (const term of terms) {
|
|
9144
|
+
if (article.category.includes(term) || article.subcategory.includes(term)) score += 3;
|
|
9145
|
+
if (haystack.includes(term)) score += 1;
|
|
9146
|
+
}
|
|
9147
|
+
return score;
|
|
9148
|
+
}
|
|
9149
|
+
function searchTerms(text) {
|
|
9150
|
+
return [...new Set(text.split(/[^a-zа-яё0-9]+/i).filter((t) => t.length >= 3))];
|
|
9151
|
+
}
|
|
9152
|
+
function normalizeSearchText(text) {
|
|
9153
|
+
return text.toLowerCase().replace(/ё/g, "\u0435");
|
|
9154
|
+
}
|
|
9155
|
+
|
|
9156
|
+
// src/webui/routes/assistant.ts
|
|
8119
9157
|
var ASSISTANT_SYSTEM = `\u0422\u044B \u2014 \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0439 \u0418\u0418-\u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A \u043F\u043E \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0435 girl-agent (\u0440\u0430\u043D\u0442\u0430\u0439\u043C \u0434\u043B\u044F Telegram-\u0434\u0435\u0432\u0443\u0448\u043A\u0438 \u0441 \u0447\u0435\u043B\u043E\u0432\u0435\u0447\u043D\u044B\u043C \u043F\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0435\u043C). \u0422\u0435\u0431\u044F \u0437\u043E\u0432\u0443\u0442 "\u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A", \u043D\u0435 "\u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043D\u0442".
|
|
8120
9158
|
|
|
8121
9159
|
\u0422\u0432\u043E\u044F \u0437\u0430\u0434\u0430\u0447\u0430:
|
|
@@ -8123,6 +9161,7 @@ var ASSISTANT_SYSTEM = `\u0422\u044B \u2014 \u0432\u0441\u0442\u0440\u043E\u0435
|
|
|
8123
9161
|
- \u041C\u0435\u043D\u044F\u0442\u044C \u043A\u043E\u043D\u0444\u0438\u0433 \u043F\u0440\u043E\u0444\u0438\u043B\u044F \u0438 \u0444\u0430\u0439\u043B\u044B \u043F\u0430\u043C\u044F\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B (\u0441\u043C. \u043D\u0438\u0436\u0435).
|
|
8124
9162
|
- \u041F\u043E\u043C\u043E\u0433\u0430\u0442\u044C \u0441 \u043F\u0435\u0440\u0432\u0438\u0447\u043D\u043E\u0439 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u043E\u0439 \u0438 \u0434\u0438\u0430\u0433\u043D\u043E\u0441\u0442\u0438\u043A\u043E\u0439 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F.
|
|
8125
9163
|
- \u041E\u0431\u044A\u044F\u0441\u043D\u044F\u0442\u044C \u043E\u0448\u0438\u0431\u043A\u0438 \u0438\u0437 \u043B\u043E\u0433\u043E\u0432 \u0438 \u043F\u0440\u0435\u0434\u043B\u0430\u0433\u0430\u0442\u044C \u043F\u043E\u0447\u0438\u043D\u043A\u0443.
|
|
9164
|
+
- \u0414\u0430\u0432\u0430\u0442\u044C \u043E\u0442\u0432\u0435\u0442\u044B, \u043E\u043F\u0438\u0440\u0430\u044F\u0441\u044C \u043D\u0430 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u0441\u0442\u0430\u0442\u044C\u0438 \u0438\u0437 \u0431\u0430\u0437\u044B \u0437\u043D\u0430\u043D\u0438\u0439 \u043F\u0440\u043E\u0435\u043A\u0442\u0430, \u0430 \u043D\u0435 \u043D\u0430 \u0434\u043E\u0433\u0430\u0434\u043A\u0438.
|
|
8126
9165
|
|
|
8127
9166
|
\u041F\u0440\u0430\u0432\u0438\u043B\u0430 \u043E\u0442\u0432\u0435\u0442\u0430:
|
|
8128
9167
|
- \u041E\u0442\u0432\u0435\u0447\u0430\u0439 \u043A\u043E\u0440\u043E\u0442\u043A\u043E (2-5 \u043F\u0440\u0435\u0434\u043B\u043E\u0436\u0435\u043D\u0438\u0439), \u043D\u0430 \u0440\u0443\u0441\u0441\u043A\u043E\u043C.
|
|
@@ -8145,7 +9184,7 @@ var ASSISTANT_SYSTEM = `\u0422\u044B \u2014 \u0432\u0441\u0442\u0440\u043E\u0435
|
|
|
8145
9184
|
- set_stage { stage: string } \u2014 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0441\u0442\u0430\u0434\u0438\u044E \u043E\u0442\u043D\u043E\u0448\u0435\u043D\u0438\u0439 (id \u0438\u0437 \u0441\u043F\u0438\u0441\u043A\u0430).
|
|
8146
9185
|
- set_communication_preset { id: string } \u2014 \u043F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C \u043F\u0440\u0435\u0441\u0435\u0442 \u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0438 \u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044C communication.md.
|
|
8147
9186
|
- write_memory { file: string, content: string } \u2014 \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u0430\u0442\u044C \u0444\u0430\u0439\u043B \u043F\u0430\u043C\u044F\u0442\u0438.
|
|
8148
|
-
\u0414\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0435 \u0444\u0430\u0439\u043B\u044B: persona.md, speech.md, boundaries.md, communication.md, long-term.md.
|
|
9187
|
+
\u0414\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0435 \u0444\u0430\u0439\u043B\u044B: persona.md, speech.md, boundaries.md, communication.md, long-term.md, memory/long-term.md, memory/facts.md, memory/uncertain.md, time/promises.md, time/open-loops.md.
|
|
8149
9188
|
- append_memory { file: string, content: string } \u2014 \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0441\u0442\u0440\u043E\u043A\u0443 \u0432 \u0444\u0430\u0439\u043B \u043F\u0430\u043C\u044F\u0442\u0438.
|
|
8150
9189
|
- generate_persona { name?: string, age?: number, nationality?: string, notes?: string } \u2014 LLM-\u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F persona.md/speech.md/communication.md (\u044D\u0442\u043E \u0437\u0430\u043D\u0438\u043C\u0430\u0435\u0442 ~30s).
|
|
8151
9190
|
- runtime_action { action: "start"|"stop"|"pause"|"resume"|"restart" } \u2014 \u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0440\u0430\u043D\u0442\u0430\u0439\u043C\u043E\u043C.
|
|
@@ -8168,7 +9207,7 @@ var ASSISTANT_SYSTEM = `\u0422\u044B \u2014 \u0432\u0441\u0442\u0440\u043E\u0435
|
|
|
8168
9207
|
|
|
8169
9208
|
\u0412\u0430\u0436\u043D\u044B\u0435 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0438:
|
|
8170
9209
|
- ignoreTendency: 0 \u2014 \u0432\u0441\u0435\u0433\u0434\u0430 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442; 100 \u2014 \u043F\u043E\u0447\u0442\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u0433\u043D\u043E\u0440\u0438\u0442. \u041F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E 35.
|
|
8171
|
-
- \u0415\u0441\u043B\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u0436\u0430\u043B\u0443\u0435\u0442\u0441\u044F \u0447\u0442\u043E "\u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442" \u2192 \u043F\u0440\u043E\u0432\u0435\u0440\u044C runtime
|
|
9210
|
+
- \u0415\u0441\u043B\u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u0436\u0430\u043B\u0443\u0435\u0442\u0441\u044F \u0447\u0442\u043E "\u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442" \u2192 \u043F\u0440\u043E\u0432\u0435\u0440\u044C runtime state \u0438 read_logs.
|
|
8172
9211
|
- \u0415\u0441\u043B\u0438 LLM \u043E\u0448\u0438\u0431\u043A\u0438 \u2192 \u043F\u0440\u043E\u0432\u0435\u0440\u044C llm.apiKey, llm.baseURL, llm.model.
|
|
8173
9212
|
- \u0415\u0441\u043B\u0438 \u0441\u043C\u0435\u043D\u0438\u043B\u0438 telegram.mode \u2014 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E \u043D\u0443\u0436\u0435\u043D restart.`;
|
|
8174
9213
|
function registerAssistantRoutes(r) {
|
|
@@ -8191,22 +9230,69 @@ function registerAssistantRoutes(r) {
|
|
|
8191
9230
|
return { reply: reply2, toolCalls: [] };
|
|
8192
9231
|
}
|
|
8193
9232
|
const stage = findStage(cfg.stage);
|
|
9233
|
+
const status = bus.status(cfg.slug);
|
|
9234
|
+
const userQuestion = body.messages.slice().reverse().find((m) => m.role === "user")?.content ?? "";
|
|
9235
|
+
const relevantKnowledge = renderRelevantKnowledge(userQuestion);
|
|
8194
9236
|
let scoreLine = "";
|
|
9237
|
+
let memoryContext = "";
|
|
8195
9238
|
let recentLogs = "";
|
|
8196
9239
|
try {
|
|
8197
9240
|
const rel = await readRelationship(cfg.slug);
|
|
8198
9241
|
scoreLine = ` score=${JSON.stringify(rel.score)}`;
|
|
8199
9242
|
} catch {
|
|
8200
9243
|
}
|
|
9244
|
+
try {
|
|
9245
|
+
const [persona, speech, communication, boundaries, longTerm, facts, uncertain, timeline, openLoops, promises] = await Promise.all([
|
|
9246
|
+
readMd(cfg.slug, "persona.md"),
|
|
9247
|
+
readMd(cfg.slug, "speech.md"),
|
|
9248
|
+
readMd(cfg.slug, "communication.md"),
|
|
9249
|
+
readMd(cfg.slug, "boundaries.md"),
|
|
9250
|
+
readMd(cfg.slug, "memory/long-term.md"),
|
|
9251
|
+
readMd(cfg.slug, "memory/facts.md"),
|
|
9252
|
+
readMd(cfg.slug, "memory/uncertain.md"),
|
|
9253
|
+
readMd(cfg.slug, "relationship/timeline.md"),
|
|
9254
|
+
readMd(cfg.slug, "time/open-loops.md"),
|
|
9255
|
+
readMd(cfg.slug, "time/promises.md")
|
|
9256
|
+
]);
|
|
9257
|
+
memoryContext = renderAssistantMemoryContext({
|
|
9258
|
+
persona,
|
|
9259
|
+
speech,
|
|
9260
|
+
communication,
|
|
9261
|
+
boundaries,
|
|
9262
|
+
longTerm,
|
|
9263
|
+
facts,
|
|
9264
|
+
uncertain,
|
|
9265
|
+
timeline,
|
|
9266
|
+
openLoops,
|
|
9267
|
+
promises
|
|
9268
|
+
});
|
|
9269
|
+
} catch {
|
|
9270
|
+
}
|
|
8201
9271
|
try {
|
|
8202
9272
|
const buf = bus.recentLogs(cfg.slug, 25);
|
|
8203
9273
|
recentLogs = buf.map((e) => `[${e.type}] ${e.text ?? ""}`).join("\n");
|
|
8204
9274
|
} catch {
|
|
8205
9275
|
}
|
|
8206
|
-
const
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
${
|
|
9276
|
+
const runtimeContext = [
|
|
9277
|
+
`\u0422\u0435\u043A\u0443\u0449\u0438\u0439 \u043F\u0440\u043E\u0444\u0438\u043B\u044C: ${cfg.name}, ${cfg.age}, ${cfg.nationality}, tz=${cfg.tz}`,
|
|
9278
|
+
`slug=${cfg.slug}, runtime=${status.state}${status.lastError ? `, lastError=${status.lastError}` : ""}`,
|
|
9279
|
+
`\u0441\u0442\u0430\u0434\u0438\u044F "${stage.label}" (${cfg.stage}), ${stage.description}`,
|
|
9280
|
+
`stage defaults: ignoreChance=${stage.defaults.ignoreChance}, replyDelaySec=${stage.defaults.replyDelaySec[0]}-${stage.defaults.replyDelaySec[1]}`,
|
|
9281
|
+
`privacy=${cfg.privacy ?? "owner-only"}, ownerId=${cfg.ownerId ?? "\u2014"}, ignoreTendency=${cfg.ignoreTendency ?? 35}`,
|
|
9282
|
+
`sleep=${cfg.sleepFrom}:00-${cfg.sleepTo}:00, nightWakeChance=${cfg.nightWakeChance}`,
|
|
9283
|
+
`communication=${cfg.communication ? JSON.stringify(cfg.communication) : "default"}, vibe=${cfg.vibe ?? "\u2014"}`,
|
|
9284
|
+
`llm=${cfg.llm.presetId}/${cfg.llm.model} (${cfg.llm.proto}), telegram=${cfg.mode ?? "bot"}, useWSS=${cfg.telegram.useWSS ?? true}`,
|
|
9285
|
+
`busySchedule=${cfg.busySchedule?.length ? JSON.stringify(cfg.busySchedule).slice(0, 1e3) : "[]"}`,
|
|
9286
|
+
scoreLine.trim()
|
|
9287
|
+
].filter(Boolean).join("\n");
|
|
9288
|
+
const ctxPrompt = [
|
|
9289
|
+
relevantKnowledge,
|
|
9290
|
+
`\u041A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0433\u043E \u043F\u0440\u043E\u0444\u0438\u043B\u044F:
|
|
9291
|
+
${runtimeContext}`,
|
|
9292
|
+
memoryContext,
|
|
9293
|
+
recentLogs ? `\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0435 \u0441\u043E\u0431\u044B\u0442\u0438\u044F runtime'\u0430:
|
|
9294
|
+
${recentLogs.slice(-2500)}` : ""
|
|
9295
|
+
].filter(Boolean).join("\n\n");
|
|
8210
9296
|
const llm = makeLLM(cfg.llm);
|
|
8211
9297
|
const messages = [
|
|
8212
9298
|
{ role: "system", content: ASSISTANT_SYSTEM },
|
|
@@ -8275,7 +9361,19 @@ var ALLOWED_FIELDS = /* @__PURE__ */ new Set([
|
|
|
8275
9361
|
"communication.initiative",
|
|
8276
9362
|
"communication.lifeSharing"
|
|
8277
9363
|
]);
|
|
8278
|
-
var ALLOWED_MEMORY = /* @__PURE__ */ new Set([
|
|
9364
|
+
var ALLOWED_MEMORY = /* @__PURE__ */ new Set([
|
|
9365
|
+
"persona.md",
|
|
9366
|
+
"speech.md",
|
|
9367
|
+
"boundaries.md",
|
|
9368
|
+
"communication.md",
|
|
9369
|
+
"long-term.md",
|
|
9370
|
+
"memory/long-term.md",
|
|
9371
|
+
"memory/facts.md",
|
|
9372
|
+
"memory/uncertain.md",
|
|
9373
|
+
"time/promises.md",
|
|
9374
|
+
"time/open-loops.md",
|
|
9375
|
+
"relationship/timeline.md"
|
|
9376
|
+
]);
|
|
8279
9377
|
async function applyTool(cfg, call) {
|
|
8280
9378
|
switch (call.tool) {
|
|
8281
9379
|
case "set_field": {
|
|
@@ -8290,12 +9388,14 @@ async function applyTool(cfg, call) {
|
|
|
8290
9388
|
const stage = String(call.args?.stage ?? "");
|
|
8291
9389
|
const found = STAGE_PRESETS.find((s) => s.id === stage);
|
|
8292
9390
|
if (!found) return { changed: false, message: `unknown stage: ${stage}. \u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435: ${STAGE_PRESETS.map((s) => s.id).join(", ")}` };
|
|
9391
|
+
const prevStage = cfg.stage;
|
|
8293
9392
|
cfg.stage = stage;
|
|
8294
9393
|
try {
|
|
8295
9394
|
const rel = await readRelationship(cfg.slug);
|
|
8296
9395
|
await writeRelationship(cfg.slug, { ...rel, stage });
|
|
8297
9396
|
} catch {
|
|
8298
9397
|
}
|
|
9398
|
+
await maybeAdvanceRelationshipTimeline(cfg, prevStage, stage);
|
|
8299
9399
|
return { changed: true, message: `stage = ${stage} (${found.label})` };
|
|
8300
9400
|
}
|
|
8301
9401
|
case "set_communication_preset": {
|
|
@@ -8437,8 +9537,34 @@ ${preset.description}
|
|
|
8437
9537
|
return { changed: false, message: `unknown tool: ${call.tool}` };
|
|
8438
9538
|
}
|
|
8439
9539
|
}
|
|
8440
|
-
function
|
|
8441
|
-
const
|
|
9540
|
+
function renderAssistantMemoryContext(parts) {
|
|
9541
|
+
const sections = [
|
|
9542
|
+
["persona.md", parts.persona],
|
|
9543
|
+
["speech.md", parts.speech],
|
|
9544
|
+
["communication.md", parts.communication],
|
|
9545
|
+
["boundaries.md", parts.boundaries],
|
|
9546
|
+
["memory/facts.md", parts.facts],
|
|
9547
|
+
["memory/uncertain.md", parts.uncertain],
|
|
9548
|
+
["memory/long-term.md", parts.longTerm],
|
|
9549
|
+
["relationship/timeline.md", parts.timeline],
|
|
9550
|
+
["time/open-loops.md", parts.openLoops],
|
|
9551
|
+
["time/promises.md", parts.promises]
|
|
9552
|
+
].map(([name, text]) => renderContextSection(name, text)).filter(Boolean);
|
|
9553
|
+
return sections.length ? `\u041F\u0430\u043C\u044F\u0442\u044C \u0438 \u0444\u0430\u0439\u043B\u044B \u043F\u0440\u043E\u0444\u0438\u043B\u044F:
|
|
9554
|
+
${sections.join("\n\n")}` : "";
|
|
9555
|
+
}
|
|
9556
|
+
function renderContextSection(name, text) {
|
|
9557
|
+
const clean = text.trim();
|
|
9558
|
+
if (!clean) return "";
|
|
9559
|
+
return `## ${name}
|
|
9560
|
+
${tail(clean, 1400)}`;
|
|
9561
|
+
}
|
|
9562
|
+
function tail(text, limit) {
|
|
9563
|
+
if (text.length <= limit) return text;
|
|
9564
|
+
return text.slice(-limit);
|
|
9565
|
+
}
|
|
9566
|
+
function setNested(obj, path13, value) {
|
|
9567
|
+
const parts = path13.split(".");
|
|
8442
9568
|
let cur = obj;
|
|
8443
9569
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
8444
9570
|
const p = parts[i];
|
|
@@ -8457,14 +9583,14 @@ var DEFAULT_PROXY = "https://tgproxy.girl-agent.com";
|
|
|
8457
9583
|
function proxyUrl() {
|
|
8458
9584
|
return process.env.GIRL_AGENT_AUTH_PROXY ?? DEFAULT_PROXY;
|
|
8459
9585
|
}
|
|
8460
|
-
async function post(
|
|
8461
|
-
const res = await fetch(`${proxyUrl()}${
|
|
9586
|
+
async function post(path13, body) {
|
|
9587
|
+
const res = await fetch(`${proxyUrl()}${path13}`, {
|
|
8462
9588
|
method: "POST",
|
|
8463
9589
|
headers: { "Content-Type": "application/json" },
|
|
8464
9590
|
body: JSON.stringify(body)
|
|
8465
9591
|
});
|
|
8466
9592
|
const data = await res.json();
|
|
8467
|
-
if (!res.ok) throw new Error(data.error ?? `proxy ${
|
|
9593
|
+
if (!res.ok) throw new Error(data.error ?? `proxy ${path13} failed (${res.status})`);
|
|
8468
9594
|
return data;
|
|
8469
9595
|
}
|
|
8470
9596
|
function remoteSendCode(phone) {
|
|
@@ -8851,8 +9977,8 @@ init_esm_shims();
|
|
|
8851
9977
|
init_llm2();
|
|
8852
9978
|
init_stages();
|
|
8853
9979
|
init_communication();
|
|
8854
|
-
import
|
|
8855
|
-
import
|
|
9980
|
+
import fs11 from "fs/promises";
|
|
9981
|
+
import path12 from "path";
|
|
8856
9982
|
import os6 from "os";
|
|
8857
9983
|
init_md();
|
|
8858
9984
|
init_runtime();
|
|
@@ -8935,7 +10061,7 @@ async function runServer(rawArgv) {
|
|
|
8935
10061
|
}
|
|
8936
10062
|
if (!args.yes) {
|
|
8937
10063
|
process.stderr.write(`\u043F\u0440\u043E\u0444\u0438\u043B\u044C \u041D\u0415 \u0443\u0434\u0430\u043B\u0451\u043D: \u0434\u043E\u0431\u0430\u0432\u044C --yes \u0434\u043B\u044F \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F.
|
|
8938
|
-
\u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043B\u0435\u043D\u043E: ${
|
|
10064
|
+
\u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043B\u0435\u043D\u043E: ${path12.join(DATA_ROOT, args.profile)}
|
|
8939
10065
|
`);
|
|
8940
10066
|
process.exit(1);
|
|
8941
10067
|
}
|
|
@@ -8997,7 +10123,7 @@ data dir: ${DATA_ROOT}
|
|
|
8997
10123
|
}
|
|
8998
10124
|
async function persistAndMaybeStart(cfg, args) {
|
|
8999
10125
|
await writeConfig(cfg);
|
|
9000
|
-
process.stderr.write(`[server] \u043F\u0440\u043E\u0444\u0438\u043B\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D: ${
|
|
10126
|
+
process.stderr.write(`[server] \u043F\u0440\u043E\u0444\u0438\u043B\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D: ${path12.join(DATA_ROOT, cfg.slug)}
|
|
9001
10127
|
`);
|
|
9002
10128
|
if (cfg.llm.apiKey || findPreset(cfg.llm.presetId)?.apiKeyRequired === false) {
|
|
9003
10129
|
try {
|
|
@@ -9114,10 +10240,10 @@ function configFromEnv() {
|
|
|
9114
10240
|
};
|
|
9115
10241
|
}
|
|
9116
10242
|
async function loadConfigFile(file) {
|
|
9117
|
-
const abs =
|
|
10243
|
+
const abs = path12.isAbsolute(file) ? file : path12.join(process.cwd(), file);
|
|
9118
10244
|
let raw;
|
|
9119
10245
|
try {
|
|
9120
|
-
raw = await
|
|
10246
|
+
raw = await fs11.readFile(abs, "utf-8");
|
|
9121
10247
|
} catch (e) {
|
|
9122
10248
|
process.stderr.write(`[server] \u043D\u0435 \u043C\u043E\u0433\u0443 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C ${abs}: ${e?.message ?? e}
|
|
9123
10249
|
`);
|