spora 0.7.6 → 0.7.8
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/{autonomy-E3DWYRJM.js → autonomy-ZMFZRXDZ.js} +7 -7
- package/dist/{chunk-BBXHECZ5.js → chunk-6WBIVXOY.js} +1 -1
- package/dist/chunk-6WBIVXOY.js.map +1 -0
- package/dist/{chunk-E5PEY36J.js → chunk-73CWOI44.js} +344 -4
- package/dist/chunk-73CWOI44.js.map +1 -0
- package/dist/{chunk-ZLSDFYBR.js → chunk-AIGSCHZK.js} +2 -2
- package/dist/{chunk-CP6JWCLY.js → chunk-ER6TILYZ.js} +1 -25
- package/dist/{chunk-CP6JWCLY.js.map → chunk-ER6TILYZ.js.map} +1 -1
- package/dist/chunk-OLYPPXKP.js +69 -0
- package/dist/chunk-OLYPPXKP.js.map +1 -0
- package/dist/{chunk-5R4AJZHN.js → chunk-TKGB5LIN.js} +2 -2
- package/dist/chunk-TTDQZI5W.js +1699 -0
- package/dist/chunk-TTDQZI5W.js.map +1 -0
- package/dist/cli.js +28 -28
- package/dist/{client-AR5ZD6S4.js → client-3APKWQ6O.js} +3 -3
- package/dist/{colony-UGVYALOS.js → colony-7GZ2ODF2.js} +2 -2
- package/dist/{heartbeat-GVBLNAFM.js → heartbeat-CUM7FIHS.js} +23 -7
- package/dist/heartbeat-CUM7FIHS.js.map +1 -0
- package/dist/heartbeat-narrative-B3RD3OPJ.js +11 -0
- package/dist/{init-C4OZPGUC.js → init-KL6XSI7E.js} +3 -3
- package/dist/mcp-server.js +20 -20
- package/dist/{memory-DTSLVSQG.js → memory-G4DNIGLT.js} +2 -2
- package/dist/{prompt-builder-NTN4FCBD.js → prompt-builder-S6PJVEC5.js} +4 -4
- package/dist/{queue-QCGNDHH2.js → queue-YPBUUP22.js} +2 -2
- package/dist/web-chat/chat.html +15 -5
- package/dist/{web-chat-2N2RN6J7.js → web-chat-XNTIDKAS.js} +37 -15
- package/dist/web-chat-XNTIDKAS.js.map +1 -0
- package/dist/{x-client-S2LUVEKV.js → x-client-2HFEHHVE.js} +2 -2
- package/dist/x-client-2HFEHHVE.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-BBXHECZ5.js.map +0 -1
- package/dist/chunk-E5PEY36J.js.map +0 -1
- package/dist/chunk-FBHLDOMC.js +0 -2436
- package/dist/chunk-FBHLDOMC.js.map +0 -1
- package/dist/heartbeat-GVBLNAFM.js.map +0 -1
- package/dist/web-chat-2N2RN6J7.js.map +0 -1
- /package/dist/{autonomy-E3DWYRJM.js.map → autonomy-ZMFZRXDZ.js.map} +0 -0
- /package/dist/{chunk-ZLSDFYBR.js.map → chunk-AIGSCHZK.js.map} +0 -0
- /package/dist/{chunk-5R4AJZHN.js.map → chunk-TKGB5LIN.js.map} +0 -0
- /package/dist/{client-AR5ZD6S4.js.map → client-3APKWQ6O.js.map} +0 -0
- /package/dist/{colony-UGVYALOS.js.map → colony-7GZ2ODF2.js.map} +0 -0
- /package/dist/{memory-DTSLVSQG.js.map → heartbeat-narrative-B3RD3OPJ.js.map} +0 -0
- /package/dist/{init-C4OZPGUC.js.map → init-KL6XSI7E.js.map} +0 -0
- /package/dist/{prompt-builder-NTN4FCBD.js.map → memory-G4DNIGLT.js.map} +0 -0
- /package/dist/{queue-QCGNDHH2.js.map → prompt-builder-S6PJVEC5.js.map} +0 -0
- /package/dist/{x-client-S2LUVEKV.js.map → queue-YPBUUP22.js.map} +0 -0
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runAutonomyCycle
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-TTDQZI5W.js";
|
|
4
|
+
import "./chunk-TKGB5LIN.js";
|
|
5
|
+
import "./chunk-AIGSCHZK.js";
|
|
6
|
+
import "./chunk-73CWOI44.js";
|
|
7
7
|
import "./chunk-OTZNHIXT.js";
|
|
8
8
|
import "./chunk-CAWWG3MD.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-ER6TILYZ.js";
|
|
10
10
|
import "./chunk-IULO3GRE.js";
|
|
11
11
|
import "./chunk-SXNZVKLJ.js";
|
|
12
12
|
import "./chunk-342ZX72W.js";
|
|
13
13
|
import "./chunk-RSNEVBEI.js";
|
|
14
14
|
import "./chunk-QYFNAGNI.js";
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-6WBIVXOY.js";
|
|
16
16
|
import "./chunk-ZWKTKWS6.js";
|
|
17
17
|
export {
|
|
18
18
|
runAutonomyCycle
|
|
19
19
|
};
|
|
20
|
-
//# sourceMappingURL=autonomy-
|
|
20
|
+
//# sourceMappingURL=autonomy-ZMFZRXDZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/memory/index.ts"],"sourcesContent":["import { readFileSync, writeFileSync, appendFileSync, existsSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { paths, ensureDirectories } from \"../utils/paths.js\";\n\nexport interface InteractionEntry {\n id: string;\n timestamp: string;\n type: \"post\" | \"reply\" | \"like\" | \"retweet\" | \"follow\" | \"mention_received\" | \"heartbeat\";\n tweetId?: string;\n targetUserId?: string;\n targetHandle?: string;\n content?: string;\n inReplyTo?: string;\n sentiment?: \"positive\" | \"negative\" | \"neutral\";\n creditsUsed: number;\n success: boolean;\n error?: string;\n}\n\nexport interface Learning {\n id: string;\n timestamp: string;\n content: string;\n source: string;\n tags: string[];\n}\n\nexport interface Relationship {\n handle: string;\n firstSeen: string;\n lastInteraction: string;\n interactionCount: number;\n sentiment: number;\n tags: string[];\n notes: string[];\n isSpore: boolean;\n}\n\nexport interface RelationshipsData {\n accounts: Record<string, Relationship>;\n}\n\nexport interface LearningsData {\n learnings: Learning[];\n}\n\n// --- Interaction Log ---\n\nfunction todayLogPath(): string {\n const date = new Date().toISOString().split(\"T\")[0];\n return join(paths.interactions, `${date}.jsonl`);\n}\n\nexport function logInteraction(entry: InteractionEntry): void {\n ensureDirectories();\n appendFileSync(todayLogPath(), JSON.stringify(entry) + \"\\n\");\n}\n\nexport function getInteractions(date?: string): InteractionEntry[] {\n const targetDate = date ?? new Date().toISOString().split(\"T\")[0];\n const filePath = join(paths.interactions, `${targetDate}.jsonl`);\n\n if (!existsSync(filePath)) return [];\n\n return readFileSync(filePath, \"utf-8\")\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => JSON.parse(line) as InteractionEntry);\n}\n\nexport function getRecentInteractions(count: number = 20): InteractionEntry[] {\n ensureDirectories();\n const files = readdirSync(paths.interactions)\n .filter((f) => f.endsWith(\".jsonl\"))\n .sort()\n .reverse();\n\n const entries: InteractionEntry[] = [];\n for (const file of files) {\n if (entries.length >= count) break;\n const filePath = join(paths.interactions, file);\n const lines = readFileSync(filePath, \"utf-8\").trim().split(\"\\n\").filter(Boolean);\n for (const line of lines.reverse()) {\n if (entries.length >= count) break;\n entries.push(JSON.parse(line) as InteractionEntry);\n }\n }\n\n return entries;\n}\n\n// --- Learnings ---\n\nexport function loadLearnings(): LearningsData {\n if (!existsSync(paths.learnings)) {\n return { learnings: [] };\n }\n return JSON.parse(readFileSync(paths.learnings, \"utf-8\")) as LearningsData;\n}\n\nexport function saveLearnings(data: LearningsData): void {\n ensureDirectories();\n writeFileSync(paths.learnings, JSON.stringify(data, null, 2));\n}\n\nexport function addLearning(content: string, source: string, tags: string[] = []): void {\n const data = loadLearnings();\n data.learnings.push({\n id: `learn-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n timestamp: new Date().toISOString(),\n content,\n source,\n tags,\n });\n saveLearnings(data);\n}\n\n// --- Relationships ---\n\nexport function loadRelationships(): RelationshipsData {\n if (!existsSync(paths.relationships)) {\n return { accounts: {} };\n }\n return JSON.parse(readFileSync(paths.relationships, \"utf-8\")) as RelationshipsData;\n}\n\nexport function saveRelationships(data: RelationshipsData): void {\n ensureDirectories();\n writeFileSync(paths.relationships, JSON.stringify(data, null, 2));\n}\n\nexport function updateRelationship(\n userId: string,\n update: Partial<Relationship> & { handle: string }\n): void {\n const data = loadRelationships();\n const existing = data.accounts[userId];\n\n if (existing) {\n data.accounts[userId] = {\n ...existing,\n ...update,\n lastInteraction: new Date().toISOString(),\n interactionCount: existing.interactionCount + 1,\n };\n } else {\n data.accounts[userId] = {\n handle: update.handle,\n firstSeen: new Date().toISOString(),\n lastInteraction: new Date().toISOString(),\n interactionCount: 1,\n sentiment: update.sentiment ?? 0,\n tags: update.tags ?? [],\n notes: update.notes ?? [],\n isSpore: update.isSpore ?? false,\n };\n }\n\n saveRelationships(data);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
getPerformanceSummary,
|
|
11
11
|
rateLimiter
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ER6TILYZ.js";
|
|
13
13
|
import {
|
|
14
14
|
loadIdentity,
|
|
15
15
|
renderIdentityDocument
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
getRecentInteractions,
|
|
22
22
|
loadLearnings,
|
|
23
23
|
loadRelationships
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-6WBIVXOY.js";
|
|
25
25
|
|
|
26
26
|
// src/runtime/persona-constraints.ts
|
|
27
27
|
function normalizeHandle(handle) {
|
|
@@ -37,6 +37,63 @@ function extractHandles(text) {
|
|
|
37
37
|
[...fromMentions, ...fromUrls].map(normalizeHandle).filter((handle) => handle.length > 0)
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
|
+
var BARE_HANDLE_STOPWORDS = /* @__PURE__ */ new Set([
|
|
41
|
+
"him",
|
|
42
|
+
"her",
|
|
43
|
+
"them",
|
|
44
|
+
"someone",
|
|
45
|
+
"anyone",
|
|
46
|
+
"everyone",
|
|
47
|
+
"anybody",
|
|
48
|
+
"everybody",
|
|
49
|
+
"people",
|
|
50
|
+
"person",
|
|
51
|
+
"users",
|
|
52
|
+
"user",
|
|
53
|
+
"others",
|
|
54
|
+
"other",
|
|
55
|
+
"my",
|
|
56
|
+
"me",
|
|
57
|
+
"you",
|
|
58
|
+
"to",
|
|
59
|
+
"with",
|
|
60
|
+
"for",
|
|
61
|
+
"only",
|
|
62
|
+
"just",
|
|
63
|
+
"reply",
|
|
64
|
+
"respond",
|
|
65
|
+
"interact",
|
|
66
|
+
"engage"
|
|
67
|
+
]);
|
|
68
|
+
var NAME_TO_HANDLE = [
|
|
69
|
+
[/\bgrok\b/i, "grok"],
|
|
70
|
+
[/\bgork\b/i, "grok"],
|
|
71
|
+
[/\belon musk\b/i, "elonmusk"],
|
|
72
|
+
[/\belon\b/i, "elonmusk"],
|
|
73
|
+
[/\bmark zuckerberg\b/i, "zuck"],
|
|
74
|
+
[/\bzuck\b/i, "zuck"],
|
|
75
|
+
[/\bspora\s*ai\b/i, "sporaai"],
|
|
76
|
+
[/\bsporaai\b/i, "sporaai"]
|
|
77
|
+
];
|
|
78
|
+
function extractBareConstraintTargets(text) {
|
|
79
|
+
const found = /* @__PURE__ */ new Set();
|
|
80
|
+
const candidates = [
|
|
81
|
+
...text.matchAll(/\bonly\s+(?:reply|respond|interact|engage|talk|speak)(?:\s+\w+){0,3}\s+(?:to|with)\s+@?([a-zA-Z0-9_]{2,15})\b/gi),
|
|
82
|
+
...text.matchAll(/\b(?:reply|respond|interact|engage|talk|speak)\s+only(?:\s+\w+){0,3}\s+(?:to|with)\s+@?([a-zA-Z0-9_]{2,15})\b/gi)
|
|
83
|
+
];
|
|
84
|
+
for (const match of candidates) {
|
|
85
|
+
const raw = String(match[1] ?? "").replace(/'s$/i, "");
|
|
86
|
+
const handle = normalizeHandle(raw);
|
|
87
|
+
if (!handle) continue;
|
|
88
|
+
if (!/^[a-z0-9_]{2,15}$/.test(handle)) continue;
|
|
89
|
+
if (BARE_HANDLE_STOPWORDS.has(handle)) continue;
|
|
90
|
+
found.add(handle);
|
|
91
|
+
}
|
|
92
|
+
for (const [pattern, handle] of NAME_TO_HANDLE) {
|
|
93
|
+
if (pattern.test(text)) found.add(handle);
|
|
94
|
+
}
|
|
95
|
+
return [...found];
|
|
96
|
+
}
|
|
40
97
|
function includesOnlyQualifier(text) {
|
|
41
98
|
return /\b(only|just|exclusively|strictly)\b/i.test(text);
|
|
42
99
|
}
|
|
@@ -70,7 +127,10 @@ function getPersonaConstraints(identityArg) {
|
|
|
70
127
|
let replyOnlyMode = false;
|
|
71
128
|
let noOriginalPosts = false;
|
|
72
129
|
for (const line of lines) {
|
|
73
|
-
const handles =
|
|
130
|
+
const handles = unique([
|
|
131
|
+
...extractHandles(line),
|
|
132
|
+
...extractBareConstraintTargets(line)
|
|
133
|
+
]);
|
|
74
134
|
const hasOnly = includesOnlyQualifier(line);
|
|
75
135
|
const hasReply = includesReplyIntent(line);
|
|
76
136
|
const hasInteract = includesInteractionIntent(line);
|
|
@@ -133,6 +193,277 @@ function buildPersonaConstraintLines(constraints) {
|
|
|
133
193
|
return lines;
|
|
134
194
|
}
|
|
135
195
|
|
|
196
|
+
// src/runtime/persona-action-profile.ts
|
|
197
|
+
function clamp(value, min, max) {
|
|
198
|
+
return Math.max(min, Math.min(max, value));
|
|
199
|
+
}
|
|
200
|
+
function unique2(values) {
|
|
201
|
+
return [...new Set(values)];
|
|
202
|
+
}
|
|
203
|
+
function normalizeText(text) {
|
|
204
|
+
return text.toLowerCase().trim();
|
|
205
|
+
}
|
|
206
|
+
function hasAny(text, terms) {
|
|
207
|
+
const lower = normalizeText(text);
|
|
208
|
+
return terms.some((term) => lower.includes(term));
|
|
209
|
+
}
|
|
210
|
+
function applyGoalBias(actionBias, sourceBias, goals, rationale) {
|
|
211
|
+
for (const goal of goals) {
|
|
212
|
+
if (hasAny(goal, ["grow followers", "go viral", "audience", "reach"])) {
|
|
213
|
+
actionBias.reply += 0.35;
|
|
214
|
+
actionBias.post += 0.45;
|
|
215
|
+
sourceBias.mention += 0.2;
|
|
216
|
+
rationale.push("growth goals favor reply+post mix");
|
|
217
|
+
}
|
|
218
|
+
if (hasAny(goal, ["build community", "community", "connect", "relationships"])) {
|
|
219
|
+
actionBias.reply += 0.4;
|
|
220
|
+
actionBias.like += 0.3;
|
|
221
|
+
actionBias.follow += 0.45;
|
|
222
|
+
sourceBias.people_watch += 0.35;
|
|
223
|
+
rationale.push("community goals favor social interaction actions");
|
|
224
|
+
}
|
|
225
|
+
if (hasAny(goal, ["debate", "challenge", "argue", "provoc"])) {
|
|
226
|
+
actionBias.reply += 0.5;
|
|
227
|
+
sourceBias.mention += 0.25;
|
|
228
|
+
rationale.push("debate goals bias toward replies in active conversations");
|
|
229
|
+
}
|
|
230
|
+
if (hasAny(goal, ["curate", "signal", "filter"])) {
|
|
231
|
+
actionBias.retweet += 0.8;
|
|
232
|
+
actionBias.like += 0.2;
|
|
233
|
+
sourceBias.topic_search += 0.35;
|
|
234
|
+
rationale.push("curation goals bias toward retweet/like actions");
|
|
235
|
+
}
|
|
236
|
+
if (hasAny(goal, ["seek truth", "research", "facts", "evidence"])) {
|
|
237
|
+
actionBias.reply += 0.25;
|
|
238
|
+
actionBias.post += 0.2;
|
|
239
|
+
sourceBias.topic_search += 0.45;
|
|
240
|
+
rationale.push("truth-seeking goals bias toward topic-search grounded actions");
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function compilePersonaActionProfile(input) {
|
|
245
|
+
const { identity, strategy, constraints } = input;
|
|
246
|
+
const rationale = [];
|
|
247
|
+
const actionBias = {
|
|
248
|
+
reply: 0,
|
|
249
|
+
like: 0,
|
|
250
|
+
retweet: 0,
|
|
251
|
+
follow: 0,
|
|
252
|
+
post: 0
|
|
253
|
+
};
|
|
254
|
+
const sourceBias = {
|
|
255
|
+
mention: 0,
|
|
256
|
+
timeline: 0,
|
|
257
|
+
topic_search: 0,
|
|
258
|
+
people_watch: 0,
|
|
259
|
+
synthesis: 0
|
|
260
|
+
};
|
|
261
|
+
const mix = identity.engagementStrategy.contentMix;
|
|
262
|
+
actionBias.post += (mix.originalPosts - 25) / 25;
|
|
263
|
+
actionBias.reply += (mix.replies - 30) / 25;
|
|
264
|
+
actionBias.retweet += (mix.retweets - 15) / 20;
|
|
265
|
+
actionBias.like += (mix.likes - 15) / 20;
|
|
266
|
+
rationale.push("contentMix translated into action priors");
|
|
267
|
+
if (identity.engagementStrategy.replyStyle === "strategic") {
|
|
268
|
+
actionBias.reply += 0.3;
|
|
269
|
+
sourceBias.people_watch += 0.35;
|
|
270
|
+
sourceBias.topic_search += 0.25;
|
|
271
|
+
sourceBias.timeline -= 0.15;
|
|
272
|
+
rationale.push("strategic replyStyle favors selective people/topic opportunities");
|
|
273
|
+
} else if (identity.engagementStrategy.replyStyle === "reactive") {
|
|
274
|
+
actionBias.reply += 0.4;
|
|
275
|
+
sourceBias.mention += 0.45;
|
|
276
|
+
sourceBias.timeline += 0.2;
|
|
277
|
+
rationale.push("reactive replyStyle favors mentions/timeline");
|
|
278
|
+
} else if (identity.engagementStrategy.replyStyle === "generous") {
|
|
279
|
+
actionBias.reply += 0.25;
|
|
280
|
+
actionBias.like += 0.25;
|
|
281
|
+
sourceBias.mention += 0.25;
|
|
282
|
+
sourceBias.timeline += 0.2;
|
|
283
|
+
rationale.push("generous replyStyle favors broader conversation participation");
|
|
284
|
+
} else if (identity.engagementStrategy.replyStyle === "selective") {
|
|
285
|
+
sourceBias.people_watch += 0.25;
|
|
286
|
+
sourceBias.topic_search += 0.2;
|
|
287
|
+
sourceBias.timeline -= 0.2;
|
|
288
|
+
rationale.push("selective replyStyle favors quality-filtered contexts");
|
|
289
|
+
}
|
|
290
|
+
if (identity.engagementStrategy.followStrategy === "aggressive") {
|
|
291
|
+
actionBias.follow += 0.7;
|
|
292
|
+
rationale.push("aggressive followStrategy boosts follow actions");
|
|
293
|
+
} else if (identity.engagementStrategy.followStrategy === "none") {
|
|
294
|
+
actionBias.follow -= 2;
|
|
295
|
+
rationale.push("followStrategy=none suppresses follow actions");
|
|
296
|
+
} else if (identity.engagementStrategy.followStrategy === "curated") {
|
|
297
|
+
actionBias.follow -= 0.25;
|
|
298
|
+
sourceBias.people_watch += 0.15;
|
|
299
|
+
rationale.push("curated followStrategy slightly restricts follow actions");
|
|
300
|
+
}
|
|
301
|
+
const traits = identity.traits;
|
|
302
|
+
if (traits.curiosity >= 0.65) {
|
|
303
|
+
actionBias.reply += 0.35;
|
|
304
|
+
sourceBias.mention += 0.2;
|
|
305
|
+
sourceBias.people_watch += 0.2;
|
|
306
|
+
rationale.push("high curiosity increases reply preference");
|
|
307
|
+
}
|
|
308
|
+
if (traits.empathy >= 0.65) {
|
|
309
|
+
actionBias.like += 0.35;
|
|
310
|
+
actionBias.follow += 0.25;
|
|
311
|
+
rationale.push("high empathy increases supportive actions");
|
|
312
|
+
}
|
|
313
|
+
if (traits.confidence >= 0.7 || traits.aggression >= 0.65) {
|
|
314
|
+
actionBias.reply += 0.25;
|
|
315
|
+
actionBias.post += 0.15;
|
|
316
|
+
actionBias.like -= 0.15;
|
|
317
|
+
rationale.push("assertive traits increase reply/post decisiveness");
|
|
318
|
+
}
|
|
319
|
+
if (traits.originality >= 0.7) {
|
|
320
|
+
actionBias.post += 0.25;
|
|
321
|
+
actionBias.reply += 0.1;
|
|
322
|
+
sourceBias.synthesis += 0.25;
|
|
323
|
+
rationale.push("high originality favors fresh synthesis posts");
|
|
324
|
+
}
|
|
325
|
+
if (traits.humor >= 0.7) {
|
|
326
|
+
actionBias.reply += 0.15;
|
|
327
|
+
actionBias.post += 0.15;
|
|
328
|
+
sourceBias.timeline += 0.15;
|
|
329
|
+
rationale.push("high humor increases conversational/timeline engagement");
|
|
330
|
+
}
|
|
331
|
+
if (identity.vocabularyStyle === "casual" || identity.vocabularyStyle === "internet-native") {
|
|
332
|
+
actionBias.reply += 0.2;
|
|
333
|
+
actionBias.like += 0.1;
|
|
334
|
+
sourceBias.timeline += 0.2;
|
|
335
|
+
sourceBias.synthesis -= 0.15;
|
|
336
|
+
rationale.push("casual/internet-native vocabulary favors timeline-native interactions");
|
|
337
|
+
}
|
|
338
|
+
if (identity.tweetStyle === "one-liners" || identity.tweetStyle === "short-form") {
|
|
339
|
+
actionBias.reply += 0.25;
|
|
340
|
+
actionBias.like += 0.15;
|
|
341
|
+
actionBias.post -= 0.15;
|
|
342
|
+
sourceBias.timeline += 0.2;
|
|
343
|
+
rationale.push("short tweet style favors reactive conversational actions");
|
|
344
|
+
} else if (identity.tweetStyle === "threads") {
|
|
345
|
+
actionBias.post += 0.25;
|
|
346
|
+
sourceBias.synthesis += 0.2;
|
|
347
|
+
rationale.push("thread style favors synthesis-driven posting");
|
|
348
|
+
}
|
|
349
|
+
if (identity.framework !== "philosopher") {
|
|
350
|
+
sourceBias.synthesis -= 0.1;
|
|
351
|
+
rationale.push("non-philosopher frameworks slightly downweight abstract synthesis");
|
|
352
|
+
}
|
|
353
|
+
switch (identity.framework) {
|
|
354
|
+
case "conqueror":
|
|
355
|
+
actionBias.post += 0.45;
|
|
356
|
+
actionBias.reply += 0.35;
|
|
357
|
+
actionBias.follow += 0.25;
|
|
358
|
+
actionBias.like -= 0.2;
|
|
359
|
+
sourceBias.mention += 0.15;
|
|
360
|
+
rationale.push("conqueror framework favors decisive high-visibility actions");
|
|
361
|
+
break;
|
|
362
|
+
case "authentic":
|
|
363
|
+
actionBias.reply += 0.45;
|
|
364
|
+
actionBias.like += 0.4;
|
|
365
|
+
actionBias.follow += 0.2;
|
|
366
|
+
actionBias.post += 0.1;
|
|
367
|
+
sourceBias.mention += 0.25;
|
|
368
|
+
sourceBias.timeline += 0.2;
|
|
369
|
+
sourceBias.synthesis -= 0.15;
|
|
370
|
+
rationale.push("authentic framework favors relational and grounded conversation");
|
|
371
|
+
break;
|
|
372
|
+
case "curator":
|
|
373
|
+
actionBias.retweet += 0.8;
|
|
374
|
+
actionBias.like += 0.3;
|
|
375
|
+
actionBias.post -= 0.2;
|
|
376
|
+
rationale.push("curator framework favors retweets/likes");
|
|
377
|
+
break;
|
|
378
|
+
case "community-builder":
|
|
379
|
+
actionBias.reply += 0.35;
|
|
380
|
+
actionBias.like += 0.3;
|
|
381
|
+
actionBias.follow += 0.35;
|
|
382
|
+
rationale.push("community-builder framework favors relationship actions");
|
|
383
|
+
break;
|
|
384
|
+
case "growth-hacker":
|
|
385
|
+
actionBias.post += 0.3;
|
|
386
|
+
actionBias.reply += 0.25;
|
|
387
|
+
rationale.push("growth-hacker framework favors visible output + replies");
|
|
388
|
+
break;
|
|
389
|
+
case "truthseeker":
|
|
390
|
+
actionBias.reply += 0.25;
|
|
391
|
+
actionBias.post += 0.2;
|
|
392
|
+
sourceBias.topic_search += 0.3;
|
|
393
|
+
rationale.push("truthseeker framework favors research-grounded conversation");
|
|
394
|
+
break;
|
|
395
|
+
case "philosopher":
|
|
396
|
+
actionBias.post += 0.35;
|
|
397
|
+
actionBias.reply += 0.1;
|
|
398
|
+
sourceBias.synthesis += 0.25;
|
|
399
|
+
rationale.push("philosopher framework leans toward original perspective posts");
|
|
400
|
+
break;
|
|
401
|
+
case "provocateur":
|
|
402
|
+
actionBias.reply += 0.55;
|
|
403
|
+
actionBias.post += 0.35;
|
|
404
|
+
actionBias.like -= 0.15;
|
|
405
|
+
sourceBias.mention += 0.25;
|
|
406
|
+
sourceBias.timeline += 0.15;
|
|
407
|
+
rationale.push("provocateur framework favors sharp, conversational confrontation");
|
|
408
|
+
break;
|
|
409
|
+
case "shitposter":
|
|
410
|
+
actionBias.post += 0.45;
|
|
411
|
+
actionBias.reply += 0.25;
|
|
412
|
+
sourceBias.timeline += 0.2;
|
|
413
|
+
rationale.push("shitposter framework favors high-frequency social expression");
|
|
414
|
+
break;
|
|
415
|
+
default:
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
applyGoalBias(actionBias, sourceBias, identity.goals ?? [], rationale);
|
|
419
|
+
if ((strategy.currentFocus ?? []).length > 0 || (strategy.shortTermGoals ?? []).length > 0) {
|
|
420
|
+
sourceBias.topic_search += 0.2;
|
|
421
|
+
sourceBias.people_watch += 0.15;
|
|
422
|
+
rationale.push("active strategy focus boosts targeted discovery sources");
|
|
423
|
+
}
|
|
424
|
+
if (constraints.noOriginalPosts) {
|
|
425
|
+
actionBias.post -= 2;
|
|
426
|
+
rationale.push("hard constraint suppresses original posts");
|
|
427
|
+
}
|
|
428
|
+
if (constraints.replyOnlyMode) {
|
|
429
|
+
actionBias.reply += 1.5;
|
|
430
|
+
actionBias.like -= 1.2;
|
|
431
|
+
actionBias.retweet -= 1.2;
|
|
432
|
+
actionBias.follow -= 1.2;
|
|
433
|
+
actionBias.post -= 2;
|
|
434
|
+
rationale.push("reply-only hard constraint dominates action policy");
|
|
435
|
+
}
|
|
436
|
+
const clampedActionBias = {
|
|
437
|
+
reply: clamp(actionBias.reply, -2.5, 2.5),
|
|
438
|
+
like: clamp(actionBias.like, -2.5, 2.5),
|
|
439
|
+
retweet: clamp(actionBias.retweet, -2.5, 2.5),
|
|
440
|
+
follow: clamp(actionBias.follow, -2.5, 2.5),
|
|
441
|
+
post: clamp(actionBias.post, -2.5, 2.5)
|
|
442
|
+
};
|
|
443
|
+
const clampedSourceBias = {
|
|
444
|
+
mention: clamp(sourceBias.mention, -1.5, 1.5),
|
|
445
|
+
timeline: clamp(sourceBias.timeline, -1.5, 1.5),
|
|
446
|
+
topic_search: clamp(sourceBias.topic_search, -1.5, 1.5),
|
|
447
|
+
people_watch: clamp(sourceBias.people_watch, -1.5, 1.5),
|
|
448
|
+
synthesis: clamp(sourceBias.synthesis, -1.5, 1.5)
|
|
449
|
+
};
|
|
450
|
+
const prioritizedActions = Object.entries(clampedActionBias).sort((a, b) => b[1] - a[1]).map(([action]) => action);
|
|
451
|
+
const priorityTopics = unique2(
|
|
452
|
+
[
|
|
453
|
+
...identity.topics ?? [],
|
|
454
|
+
...strategy.currentFocus ?? [],
|
|
455
|
+
...strategy.shortTermGoals ?? []
|
|
456
|
+
].map((topic) => String(topic).trim()).filter(Boolean).slice(0, 12)
|
|
457
|
+
);
|
|
458
|
+
return {
|
|
459
|
+
actionBias: clampedActionBias,
|
|
460
|
+
sourceBias: clampedSourceBias,
|
|
461
|
+
prioritizedActions,
|
|
462
|
+
priorityTopics,
|
|
463
|
+
rationale: unique2(rationale).slice(0, 12)
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
|
|
136
467
|
// src/runtime/prompt-builder.ts
|
|
137
468
|
var PROMPT_TOKEN_STOPWORDS = /* @__PURE__ */ new Set([
|
|
138
469
|
"about",
|
|
@@ -562,6 +893,7 @@ function buildOpportunityPortfolioMessage(input) {
|
|
|
562
893
|
const identity = loadIdentity();
|
|
563
894
|
const constraints = getPersonaConstraints(identity);
|
|
564
895
|
const strategy = loadStrategy();
|
|
896
|
+
const personaProfile = compilePersonaActionProfile({ identity, strategy, constraints });
|
|
565
897
|
const recentWritten = recentWrittenTextsForPrompt(12);
|
|
566
898
|
const overusedOpenings = findOverusedOpenings(recentWritten);
|
|
567
899
|
const overusedTokens = findOverusedTokens(recentWritten);
|
|
@@ -593,6 +925,14 @@ function buildOpportunityPortfolioMessage(input) {
|
|
|
593
925
|
parts.push(line);
|
|
594
926
|
}
|
|
595
927
|
}
|
|
928
|
+
parts.push("Persona action priors (soft):");
|
|
929
|
+
parts.push(`- Preferred actions this heartbeat: ${personaProfile.prioritizedActions.slice(0, 4).join(", ")}`);
|
|
930
|
+
parts.push(
|
|
931
|
+
`- Preferred sources: ${Object.entries(personaProfile.sourceBias).sort((a, b) => b[1] - a[1]).map(([source]) => source).slice(0, 3).join(", ")}`
|
|
932
|
+
);
|
|
933
|
+
if (personaProfile.priorityTopics.length > 0) {
|
|
934
|
+
parts.push(`- Priority topics: ${personaProfile.priorityTopics.slice(0, 6).join(", ")}`);
|
|
935
|
+
}
|
|
596
936
|
parts.push("");
|
|
597
937
|
parts.push("Human style rotation:");
|
|
598
938
|
parts.push("- For each `reply`/`post`, pick one lane: quick reaction, curious question, friendly pushback, playful line, plain observation.");
|
|
@@ -872,4 +1212,4 @@ export {
|
|
|
872
1212
|
buildTrainingChatPrompt,
|
|
873
1213
|
buildReflectionPrompt
|
|
874
1214
|
};
|
|
875
|
-
//# sourceMappingURL=chunk-
|
|
1215
|
+
//# sourceMappingURL=chunk-73CWOI44.js.map
|