spora 0.7.4 → 0.7.5
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-DFPA3OK6.js +20 -0
- package/dist/{chunk-SUZUJGGW.js → chunk-342ZX72W.js} +4 -4
- package/dist/{chunk-PN5A6MCV.js → chunk-5R4AJZHN.js} +4 -4
- package/dist/{chunk-PN5A6MCV.js.map → chunk-5R4AJZHN.js.map} +1 -1
- package/dist/{chunk-Q3YXJ2C6.js → chunk-A2XTKC7B.js} +281 -65
- package/dist/chunk-A2XTKC7B.js.map +1 -0
- package/dist/{chunk-JBYZ7K56.js → chunk-BBXHECZ5.js} +2 -2
- package/dist/{chunk-WN35MRMF.js → chunk-CAWWG3MD.js} +2 -2
- package/dist/chunk-CP6JWCLY.js +171 -0
- package/dist/chunk-CP6JWCLY.js.map +1 -0
- package/dist/{chunk-T7L2L7ZL.js → chunk-D47OFTEK.js} +2 -2
- package/dist/chunk-HXI2EH5C.js +2338 -0
- package/dist/chunk-HXI2EH5C.js.map +1 -0
- package/dist/{chunk-M6YOQVSI.js → chunk-IULO3GRE.js} +4 -4
- package/dist/chunk-IULO3GRE.js.map +1 -0
- package/dist/chunk-OTZNHIXT.js +431 -0
- package/dist/chunk-OTZNHIXT.js.map +1 -0
- package/dist/{chunk-NO3NQN67.js → chunk-QYFNAGNI.js} +2 -2
- package/dist/{chunk-YMGJQRKG.js → chunk-RSNEVBEI.js} +2 -2
- package/dist/{chunk-QWEYVDLU.js → chunk-SXNZVKLJ.js} +2 -2
- package/dist/{chunk-MDOFAAZB.js → chunk-ZLSDFYBR.js} +17 -5
- package/dist/chunk-ZLSDFYBR.js.map +1 -0
- package/dist/{chunk-3RYCUGXE.js → chunk-ZWKTKWS6.js} +4 -1
- package/dist/chunk-ZWKTKWS6.js.map +1 -0
- package/dist/cli.js +49 -49
- package/dist/{client-Z5UQWPPI.js → client-AR5ZD6S4.js} +48 -16
- package/dist/client-AR5ZD6S4.js.map +1 -0
- package/dist/{colony-NNX45EAV.js → colony-UGVYALOS.js} +7 -7
- package/dist/{config-FL4VJVKZ.js → config-MU2ODEO3.js} +3 -3
- package/dist/{crypto-B65ZH7KN.js → crypto-GDG5K3ZH.js} +3 -3
- package/dist/{goals-RBKLMILE.js → goals-QWX3A47Y.js} +3 -3
- package/dist/{heartbeat-ZCCOIZGU.js → heartbeat-RAOEIKWC.js} +18 -21
- package/dist/heartbeat-RAOEIKWC.js.map +1 -0
- package/dist/{identity-VDUW4I2K.js → identity-ASHVWIN5.js} +3 -3
- package/dist/{init-SEJPTOOB.js → init-ETUTFHT6.js} +59 -13
- package/dist/init-ETUTFHT6.js.map +1 -0
- package/dist/{llm-OGOYCWBH.js → llm-IJBRQ7O2.js} +5 -5
- package/dist/mcp-server.js +24 -24
- package/dist/{memory-PNW7SX7A.js → memory-AWKIW2KW.js} +3 -3
- package/dist/{memory-OIAH33G2.js → memory-DTSLVSQG.js} +3 -3
- package/dist/{paths-BYR6MEPR.js → paths-4V5OCB5F.js} +2 -2
- package/dist/prompt-builder-XJHXZCSQ.js +27 -0
- package/dist/queue-QCGNDHH2.js +14 -0
- package/dist/strategy-R2BMRVJ3.js +19 -0
- package/dist/{web-chat-ZZ65DUID.js → web-chat-TB3ACPVF.js} +23 -28
- package/dist/web-chat-TB3ACPVF.js.map +1 -0
- package/dist/x-client-S2LUVEKV.js +12 -0
- package/package.json +1 -1
- package/dist/autonomy-XUKCAZM3.js +0 -19
- package/dist/chunk-3RYCUGXE.js.map +0 -1
- package/dist/chunk-4LNMA56H.js +0 -57
- package/dist/chunk-4LNMA56H.js.map +0 -1
- package/dist/chunk-EU4FMOKG.js +0 -377
- package/dist/chunk-EU4FMOKG.js.map +0 -1
- package/dist/chunk-M6YOQVSI.js.map +0 -1
- package/dist/chunk-MDOFAAZB.js.map +0 -1
- package/dist/chunk-P6KZIJYL.js +0 -79
- package/dist/chunk-P6KZIJYL.js.map +0 -1
- package/dist/chunk-Q3YXJ2C6.js.map +0 -1
- package/dist/client-Z5UQWPPI.js.map +0 -1
- package/dist/heartbeat-ZCCOIZGU.js.map +0 -1
- package/dist/init-SEJPTOOB.js.map +0 -1
- package/dist/prompt-builder-KJKFCGM7.js +0 -25
- package/dist/queue-2ZBKDFX3.js +0 -14
- package/dist/strategy-Z4JSFHSP.js +0 -12
- package/dist/web-chat-ZZ65DUID.js.map +0 -1
- package/dist/x-client-YG7UCCNI.js +0 -12
- /package/dist/{autonomy-XUKCAZM3.js.map → autonomy-DFPA3OK6.js.map} +0 -0
- /package/dist/{chunk-SUZUJGGW.js.map → chunk-342ZX72W.js.map} +0 -0
- /package/dist/{chunk-JBYZ7K56.js.map → chunk-BBXHECZ5.js.map} +0 -0
- /package/dist/{chunk-WN35MRMF.js.map → chunk-CAWWG3MD.js.map} +0 -0
- /package/dist/{chunk-T7L2L7ZL.js.map → chunk-D47OFTEK.js.map} +0 -0
- /package/dist/{chunk-NO3NQN67.js.map → chunk-QYFNAGNI.js.map} +0 -0
- /package/dist/{chunk-YMGJQRKG.js.map → chunk-RSNEVBEI.js.map} +0 -0
- /package/dist/{chunk-QWEYVDLU.js.map → chunk-SXNZVKLJ.js.map} +0 -0
- /package/dist/{colony-NNX45EAV.js.map → colony-UGVYALOS.js.map} +0 -0
- /package/dist/{config-FL4VJVKZ.js.map → config-MU2ODEO3.js.map} +0 -0
- /package/dist/{crypto-B65ZH7KN.js.map → crypto-GDG5K3ZH.js.map} +0 -0
- /package/dist/{goals-RBKLMILE.js.map → goals-QWX3A47Y.js.map} +0 -0
- /package/dist/{identity-VDUW4I2K.js.map → identity-ASHVWIN5.js.map} +0 -0
- /package/dist/{llm-OGOYCWBH.js.map → llm-IJBRQ7O2.js.map} +0 -0
- /package/dist/{memory-OIAH33G2.js.map → memory-AWKIW2KW.js.map} +0 -0
- /package/dist/{memory-PNW7SX7A.js.map → memory-DTSLVSQG.js.map} +0 -0
- /package/dist/{paths-BYR6MEPR.js.map → paths-4V5OCB5F.js.map} +0 -0
- /package/dist/{prompt-builder-KJKFCGM7.js.map → prompt-builder-XJHXZCSQ.js.map} +0 -0
- /package/dist/{queue-2ZBKDFX3.js.map → queue-QCGNDHH2.js.map} +0 -0
- /package/dist/{strategy-Z4JSFHSP.js.map → strategy-R2BMRVJ3.js.map} +0 -0
- /package/dist/{x-client-YG7UCCNI.js.map → x-client-S2LUVEKV.js.map} +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runAutonomyCycle
|
|
3
|
+
} from "./chunk-HXI2EH5C.js";
|
|
4
|
+
import "./chunk-5R4AJZHN.js";
|
|
5
|
+
import "./chunk-ZLSDFYBR.js";
|
|
6
|
+
import "./chunk-A2XTKC7B.js";
|
|
7
|
+
import "./chunk-OTZNHIXT.js";
|
|
8
|
+
import "./chunk-CAWWG3MD.js";
|
|
9
|
+
import "./chunk-CP6JWCLY.js";
|
|
10
|
+
import "./chunk-IULO3GRE.js";
|
|
11
|
+
import "./chunk-SXNZVKLJ.js";
|
|
12
|
+
import "./chunk-342ZX72W.js";
|
|
13
|
+
import "./chunk-RSNEVBEI.js";
|
|
14
|
+
import "./chunk-QYFNAGNI.js";
|
|
15
|
+
import "./chunk-BBXHECZ5.js";
|
|
16
|
+
import "./chunk-ZWKTKWS6.js";
|
|
17
|
+
export {
|
|
18
|
+
runAutonomyCycle
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=autonomy-DFPA3OK6.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
logger
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RSNEVBEI.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QYFNAGNI.js";
|
|
7
7
|
import {
|
|
8
8
|
paths
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZWKTKWS6.js";
|
|
10
10
|
|
|
11
11
|
// src/runtime/llm.ts
|
|
12
12
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -177,4 +177,4 @@ export {
|
|
|
177
177
|
generateResponse,
|
|
178
178
|
chat
|
|
179
179
|
};
|
|
180
|
-
//# sourceMappingURL=chunk-
|
|
180
|
+
//# sourceMappingURL=chunk-342ZX72W.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
logger
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RSNEVBEI.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QYFNAGNI.js";
|
|
7
7
|
|
|
8
8
|
// src/x-client/index.ts
|
|
9
9
|
var clientInstance = null;
|
|
@@ -13,7 +13,7 @@ async function getXClient() {
|
|
|
13
13
|
if (config.xMethod !== "api") {
|
|
14
14
|
throw new Error("Only X API mode is supported.");
|
|
15
15
|
}
|
|
16
|
-
const { XApiClient } = await import("./client-
|
|
16
|
+
const { XApiClient } = await import("./client-AR5ZD6S4.js");
|
|
17
17
|
clientInstance = new XApiClient();
|
|
18
18
|
logger.info("X client initialized: API mode");
|
|
19
19
|
return clientInstance;
|
|
@@ -26,4 +26,4 @@ export {
|
|
|
26
26
|
getXClient,
|
|
27
27
|
resetXClient
|
|
28
28
|
};
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
29
|
+
//# sourceMappingURL=chunk-5R4AJZHN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/x-client/index.ts"],"sourcesContent":["import { loadConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\nimport type { XClientInterface } from \"./types.js\";\n\nlet clientInstance: XClientInterface | null = null;\n\nexport async function getXClient(): Promise<XClientInterface> {\n if (clientInstance) return clientInstance;\n\n const config = loadConfig();\n if (config.xMethod !== \"api\") {\n throw new Error(\"Only X API mode is supported.\");\n }\n\n const { XApiClient } = await import(\"./api/client.js\");\n clientInstance = new XApiClient();\n logger.info(\"X client initialized: API mode\");\n\n return clientInstance;\n}\n\nexport function resetXClient(): void {\n clientInstance = null;\n}\n\nexport type { XClientInterface } from \"./types.js\";\nexport type { Tweet, UserProfile, PostResult, TimelineOptions, SearchOptions } from \"./types.js\";\n"],"mappings":";;;;;;;;AAIA,IAAI,iBAA0C;AAE9C,eAAsB,aAAwC;AAC5D,MAAI,eAAgB,QAAO;AAE3B,QAAM,SAAS,WAAW;AAC1B,MAAI,OAAO,YAAY,OAAO;AAC5B,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AAEA,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,sBAAiB;AACrD,mBAAiB,IAAI,WAAW;AAChC,SAAO,KAAK,gCAAgC;AAE5C,SAAO;AACT;AAEO,SAAS,eAAqB;AACnC,mBAAiB;AACnB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/x-client/index.ts"],"sourcesContent":["import { loadConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\nimport type { XClientInterface } from \"./types.js\";\n\nlet clientInstance: XClientInterface | null = null;\n\nexport async function getXClient(): Promise<XClientInterface> {\n if (clientInstance) return clientInstance;\n\n const config = loadConfig();\n if (config.xMethod !== \"api\") {\n throw new Error(\"Only X API mode is supported.\");\n }\n\n const { XApiClient } = await import(\"./api/client.js\");\n clientInstance = new XApiClient();\n logger.info(\"X client initialized: API mode\");\n\n return clientInstance;\n}\n\nexport function resetXClient(): void {\n clientInstance = null;\n}\n\nexport type { XClientInterface } from \"./types.js\";\nexport type { Tweet, UserProfile, PostResult, TimelineOptions, SearchOptions, TweetMetrics } from \"./types.js\";\n"],"mappings":";;;;;;;;AAIA,IAAI,iBAA0C;AAE9C,eAAsB,aAAwC;AAC5D,MAAI,eAAgB,QAAO;AAE3B,QAAM,SAAS,WAAW;AAC1B,MAAI,OAAO,YAAY,OAAO;AAC5B,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AAEA,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,sBAAiB;AACrD,mBAAiB,IAAI,WAAW;AAChC,SAAO,KAAK,gCAAgC;AAE5C,SAAO;AACT;AAEO,SAAS,eAAqB;AACnC,mBAAiB;AACnB;","names":[]}
|
|
@@ -1,90 +1,148 @@
|
|
|
1
1
|
import {
|
|
2
|
+
loadStrategy,
|
|
3
|
+
renderActiveIntentsForPrompt,
|
|
2
4
|
renderStrategyForPrompt
|
|
3
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OTZNHIXT.js";
|
|
4
6
|
import {
|
|
5
7
|
renderGoalsForPrompt
|
|
6
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CAWWG3MD.js";
|
|
7
9
|
import {
|
|
10
|
+
getPerformanceSummary,
|
|
8
11
|
rateLimiter
|
|
9
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-CP6JWCLY.js";
|
|
10
13
|
import {
|
|
11
14
|
loadIdentity,
|
|
12
15
|
renderIdentityDocument
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-IULO3GRE.js";
|
|
14
17
|
import {
|
|
15
18
|
loadConfig
|
|
16
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-QYFNAGNI.js";
|
|
17
20
|
import {
|
|
18
21
|
getRecentInteractions,
|
|
19
22
|
loadLearnings,
|
|
20
23
|
loadRelationships
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import {
|
|
23
|
-
paths
|
|
24
|
-
} from "./chunk-3RYCUGXE.js";
|
|
24
|
+
} from "./chunk-BBXHECZ5.js";
|
|
25
25
|
|
|
26
|
-
// src/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
// src/runtime/prompt-builder.ts
|
|
27
|
+
var PROMPT_TOKEN_STOPWORDS = /* @__PURE__ */ new Set([
|
|
28
|
+
"about",
|
|
29
|
+
"after",
|
|
30
|
+
"again",
|
|
31
|
+
"against",
|
|
32
|
+
"among",
|
|
33
|
+
"because",
|
|
34
|
+
"being",
|
|
35
|
+
"between",
|
|
36
|
+
"could",
|
|
37
|
+
"every",
|
|
38
|
+
"first",
|
|
39
|
+
"from",
|
|
40
|
+
"going",
|
|
41
|
+
"have",
|
|
42
|
+
"having",
|
|
43
|
+
"into",
|
|
44
|
+
"just",
|
|
45
|
+
"like",
|
|
46
|
+
"more",
|
|
47
|
+
"most",
|
|
48
|
+
"only",
|
|
49
|
+
"other",
|
|
50
|
+
"over",
|
|
51
|
+
"really",
|
|
52
|
+
"same",
|
|
53
|
+
"some",
|
|
54
|
+
"than",
|
|
55
|
+
"that",
|
|
56
|
+
"their",
|
|
57
|
+
"there",
|
|
58
|
+
"these",
|
|
59
|
+
"they",
|
|
60
|
+
"this",
|
|
61
|
+
"those",
|
|
62
|
+
"through",
|
|
63
|
+
"very",
|
|
64
|
+
"what",
|
|
65
|
+
"when",
|
|
66
|
+
"where",
|
|
67
|
+
"which",
|
|
68
|
+
"while",
|
|
69
|
+
"with",
|
|
70
|
+
"would",
|
|
71
|
+
"your",
|
|
72
|
+
"youre",
|
|
73
|
+
"dont",
|
|
74
|
+
"cant",
|
|
75
|
+
"will",
|
|
76
|
+
"also",
|
|
77
|
+
"tweet",
|
|
78
|
+
"tweets",
|
|
79
|
+
"thread",
|
|
80
|
+
"threads",
|
|
81
|
+
"future",
|
|
82
|
+
"human",
|
|
83
|
+
"humans",
|
|
84
|
+
"technology",
|
|
85
|
+
"tech",
|
|
86
|
+
"agent",
|
|
87
|
+
"agents",
|
|
88
|
+
"build",
|
|
89
|
+
"building"
|
|
90
|
+
]);
|
|
91
|
+
function normalizeForPrompt(text) {
|
|
92
|
+
return text.toLowerCase().replace(/https?:\/\/\S+/g, " ").replace(/[@#]\w+/g, " ").replace(/[^a-z0-9\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
93
|
+
}
|
|
94
|
+
function recentWrittenTextsForPrompt(limit = 12) {
|
|
95
|
+
return getRecentInteractions(60).filter((entry) => entry.type === "post" || entry.type === "reply").map((entry) => entry.content ?? "").filter((text) => text.trim().length > 0).slice(0, limit);
|
|
96
|
+
}
|
|
97
|
+
function findOverusedOpenings(texts) {
|
|
98
|
+
const counts = /* @__PURE__ */ new Map();
|
|
99
|
+
for (const text of texts) {
|
|
100
|
+
const opening = normalizeForPrompt(text).split(" ").filter(Boolean).slice(0, 4).join(" ");
|
|
101
|
+
if (!opening || opening.split(" ").length < 3) continue;
|
|
102
|
+
counts.set(opening, (counts.get(opening) ?? 0) + 1);
|
|
31
103
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
104
|
+
return [...counts.entries()].filter(([, count]) => count >= 2).sort((a, b) => b[1] - a[1]).slice(0, 4).map(([opening]) => opening);
|
|
105
|
+
}
|
|
106
|
+
function findOverusedTokens(texts) {
|
|
107
|
+
const counts = /* @__PURE__ */ new Map();
|
|
108
|
+
for (const text of texts) {
|
|
109
|
+
const tokens = new Set(
|
|
110
|
+
normalizeForPrompt(text).split(" ").filter((token) => token.length >= 5 && !PROMPT_TOKEN_STOPWORDS.has(token))
|
|
111
|
+
);
|
|
112
|
+
for (const token of tokens) {
|
|
113
|
+
counts.set(token, (counts.get(token) ?? 0) + 1);
|
|
114
|
+
}
|
|
36
115
|
}
|
|
116
|
+
return [...counts.entries()].filter(([, count]) => count >= 3).sort((a, b) => b[1] - a[1]).slice(0, 6).map(([token]) => token);
|
|
37
117
|
}
|
|
38
|
-
function
|
|
39
|
-
const data = loadPerformance();
|
|
118
|
+
function buildVoiceLockLines(identity) {
|
|
40
119
|
const lines = [];
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
};
|
|
55
|
-
});
|
|
56
|
-
const totalLikes = postStats.reduce((s, p) => s + p.likes, 0);
|
|
57
|
-
const totalRTs = postStats.reduce((s, p) => s + p.retweets, 0);
|
|
58
|
-
const avgLikes = Math.round(totalLikes / postStats.length);
|
|
59
|
-
lines.push(`- Last 24h: ${postStats.length} posts, avg ${avgLikes} likes, ${totalRTs} total retweets`);
|
|
60
|
-
const sorted = [...postStats].sort((a, b) => b.likes - a.likes);
|
|
61
|
-
if (sorted.length > 0 && sorted[0].likes > 0) {
|
|
62
|
-
lines.push(`- Best performing: "${sorted[0].content.slice(0, 60)}..." (${sorted[0].likes} likes, ${sorted[0].retweets} RTs)`);
|
|
63
|
-
}
|
|
64
|
-
if (sorted.length > 1) {
|
|
65
|
-
const worst = sorted[sorted.length - 1];
|
|
66
|
-
lines.push(`- Lowest performing: "${worst.content.slice(0, 60)}..." (${worst.likes} likes)`);
|
|
67
|
-
}
|
|
120
|
+
const { traits } = identity;
|
|
121
|
+
const assertive = traits.confidence >= 0.72 || traits.aggression >= 0.62 || identity.conflictStyle === "clap-back" || identity.conflictStyle === "debate";
|
|
122
|
+
lines.push(`- Tone anchor: ${identity.tone}`);
|
|
123
|
+
lines.push(`- Conflict style: ${identity.conflictStyle}`);
|
|
124
|
+
lines.push(`- Vocabulary: ${identity.vocabularyStyle}; tweet style: ${identity.tweetStyle}`);
|
|
125
|
+
if (assertive) {
|
|
126
|
+
lines.push("- Be stubborn and decisive. Take a side. Do not hedge or play both sides.");
|
|
127
|
+
}
|
|
128
|
+
if (traits.curiosity >= 0.72) {
|
|
129
|
+
lines.push("- Ask sharp questions when engaging. Curiosity should show up in replies.");
|
|
130
|
+
}
|
|
131
|
+
if (traits.verbosity <= 0.48) {
|
|
132
|
+
lines.push("- Keep replies punchy: 1-2 short sentences unless a longer reply is truly necessary.");
|
|
68
133
|
} else {
|
|
69
|
-
lines.push("-
|
|
134
|
+
lines.push("- Keep replies compact and human; avoid essay-like paragraphs.");
|
|
70
135
|
}
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
lines.push(`- Followers: ${latest.followers} | Following: ${latest.following} | Total tweets: ${latest.totalTweets}`);
|
|
74
|
-
const dayAgoMetric = data.selfMetrics.find(
|
|
75
|
-
(m) => Math.abs(new Date(m.checkedAt).getTime() - (Date.now() - 24 * 60 * 60 * 1e3)) < 12 * 60 * 60 * 1e3
|
|
76
|
-
);
|
|
77
|
-
if (dayAgoMetric) {
|
|
78
|
-
const diff = latest.followers - dayAgoMetric.followers;
|
|
79
|
-
if (diff !== 0) {
|
|
80
|
-
lines.push(`- Follower trend: ${diff > 0 ? "+" : ""}${diff} in the last ~24h`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
136
|
+
if (identity.catchphrases.length > 0) {
|
|
137
|
+
lines.push(`- Your signature phrases: ${identity.catchphrases.slice(0, 3).join(" | ")} (use occasionally, not every post).`);
|
|
83
138
|
}
|
|
84
|
-
|
|
139
|
+
if (identity.framework !== "philosopher") {
|
|
140
|
+
lines.push("- Do NOT use philosopher framing: avoid lines like 'the real question', 'the deeper question', or abstract manifesto language.");
|
|
141
|
+
lines.push("- Ground every post/reply in concrete context: a person, a claim, an event, or a direct observation.");
|
|
142
|
+
}
|
|
143
|
+
lines.push("- If the reply could be posted by any generic AI account, rewrite it.");
|
|
144
|
+
return lines;
|
|
85
145
|
}
|
|
86
|
-
|
|
87
|
-
// src/runtime/prompt-builder.ts
|
|
88
146
|
function buildSystemPrompt() {
|
|
89
147
|
const identity = loadIdentity();
|
|
90
148
|
const config = loadConfig();
|
|
@@ -92,6 +150,11 @@ function buildSystemPrompt() {
|
|
|
92
150
|
const sections = [];
|
|
93
151
|
sections.push(`You are ${identity.name} (@${identity.handle}), an autonomous AI agent on X/Twitter.`);
|
|
94
152
|
sections.push("");
|
|
153
|
+
sections.push("## Voice Lock (Non-Negotiable)");
|
|
154
|
+
for (const line of buildVoiceLockLines(identity)) {
|
|
155
|
+
sections.push(line);
|
|
156
|
+
}
|
|
157
|
+
sections.push("");
|
|
95
158
|
sections.push("## Your Identity");
|
|
96
159
|
sections.push(identityDoc);
|
|
97
160
|
sections.push("");
|
|
@@ -125,6 +188,15 @@ function buildSystemPrompt() {
|
|
|
125
188
|
}
|
|
126
189
|
sections.push("");
|
|
127
190
|
}
|
|
191
|
+
const intentsText = renderActiveIntentsForPrompt();
|
|
192
|
+
if (intentsText) {
|
|
193
|
+
sections.push("### Active Mission Intents");
|
|
194
|
+
for (const line of intentsText.split("\n")) {
|
|
195
|
+
if (!line || line.startsWith("**Active mission intents:**")) continue;
|
|
196
|
+
sections.push(line);
|
|
197
|
+
}
|
|
198
|
+
sections.push("");
|
|
199
|
+
}
|
|
128
200
|
const relationships = loadRelationships();
|
|
129
201
|
const topRelationships = Object.values(relationships.accounts).sort((a, b) => b.interactionCount - a.interactionCount).slice(0, 10);
|
|
130
202
|
if (topRelationships.length > 0) {
|
|
@@ -229,6 +301,8 @@ function buildHeartbeatUserMessage(research) {
|
|
|
229
301
|
parts.push("**DON'T:**");
|
|
230
302
|
parts.push(`- Write explanatory or educational posts ("Here's why X matters...")`);
|
|
231
303
|
parts.push('- Start tweets with "I think" or "This is interesting because"');
|
|
304
|
+
parts.push('- Use philosopher opener templates like "The real question is..." or "The deeper question is..."');
|
|
305
|
+
parts.push("- Use colon/semicolon/em-dash manifesto framing in normal tweets");
|
|
232
306
|
parts.push("- Write like a blog post or article \u2014 this is Twitter, keep it punchy");
|
|
233
307
|
parts.push("- Post generic observations nobody would engage with");
|
|
234
308
|
parts.push("- Ignore your timeline and just post into the void");
|
|
@@ -256,7 +330,20 @@ function buildHeartbeatUserMessage(research) {
|
|
|
256
330
|
return parts.join("\n");
|
|
257
331
|
}
|
|
258
332
|
function buildToolDecisionMessage(input) {
|
|
259
|
-
const
|
|
333
|
+
const identity = loadIdentity();
|
|
334
|
+
const strategy = loadStrategy();
|
|
335
|
+
const {
|
|
336
|
+
step,
|
|
337
|
+
maxActions,
|
|
338
|
+
timeline,
|
|
339
|
+
mentions,
|
|
340
|
+
topicSearchResults = [],
|
|
341
|
+
peopleActivity = [],
|
|
342
|
+
executedActions,
|
|
343
|
+
policyFeedback,
|
|
344
|
+
blockedTweetIds = [],
|
|
345
|
+
disallowedActions = []
|
|
346
|
+
} = input;
|
|
260
347
|
const parts = [];
|
|
261
348
|
parts.push(`Heartbeat step ${step + 1} of ${maxActions}.`);
|
|
262
349
|
parts.push("");
|
|
@@ -267,6 +354,18 @@ function buildToolDecisionMessage(input) {
|
|
|
267
354
|
parts.push("3. Avoid repetitive templates, slogans, and lecture-like formats.");
|
|
268
355
|
parts.push("4. Ask questions sometimes. Curiosity beats certainty.");
|
|
269
356
|
parts.push("5. Never reuse the same wording across replies; tailor each reply to the specific tweet.");
|
|
357
|
+
parts.push("6. Never interact with your own tweets. No self-replies, self-likes, or self-retweets.");
|
|
358
|
+
parts.push("");
|
|
359
|
+
const priorityTargets = strategy.peopleToEngage.filter((person) => person.priority === "high").map((person) => `@${person.handle.replace(/^@/, "")}`);
|
|
360
|
+
if (priorityTargets.length > 0) {
|
|
361
|
+
parts.push(`Priority targets: ${priorityTargets.slice(0, 5).join(", ")}`);
|
|
362
|
+
parts.push("If any priority target appears in current context, prefer engaging them.");
|
|
363
|
+
parts.push("");
|
|
364
|
+
}
|
|
365
|
+
parts.push("Voice lock:");
|
|
366
|
+
for (const line of buildVoiceLockLines(identity)) {
|
|
367
|
+
parts.push(line);
|
|
368
|
+
}
|
|
270
369
|
parts.push("");
|
|
271
370
|
if (policyFeedback.length > 0) {
|
|
272
371
|
parts.push("Policy feedback from previous attempts:");
|
|
@@ -282,6 +381,15 @@ function buildToolDecisionMessage(input) {
|
|
|
282
381
|
}
|
|
283
382
|
parts.push("");
|
|
284
383
|
}
|
|
384
|
+
if (blockedTweetIds.length > 0) {
|
|
385
|
+
parts.push("Tweet IDs you must NOT use this heartbeat:");
|
|
386
|
+
parts.push(`- ${blockedTweetIds.slice(0, 20).join(", ")}`);
|
|
387
|
+
parts.push("");
|
|
388
|
+
}
|
|
389
|
+
if (disallowedActions.length > 0) {
|
|
390
|
+
parts.push(`Temporarily disallowed actions this heartbeat: ${disallowedActions.join(", ")}`);
|
|
391
|
+
parts.push("");
|
|
392
|
+
}
|
|
285
393
|
if (mentions.length > 0) {
|
|
286
394
|
parts.push("Mentions:");
|
|
287
395
|
for (const t of mentions.slice(0, 10)) {
|
|
@@ -296,6 +404,26 @@ function buildToolDecisionMessage(input) {
|
|
|
296
404
|
}
|
|
297
405
|
parts.push("");
|
|
298
406
|
}
|
|
407
|
+
if (topicSearchResults.length > 0) {
|
|
408
|
+
parts.push("Topic Search (fresh conversations beyond your home timeline):");
|
|
409
|
+
for (const result of topicSearchResults.slice(0, 2)) {
|
|
410
|
+
parts.push(`- Query: "${result.query}"`);
|
|
411
|
+
for (const t of result.tweets.slice(0, 4)) {
|
|
412
|
+
parts.push(` - @${t.authorHandle}: "${t.text}" [tweet:${t.id}]`);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
parts.push("");
|
|
416
|
+
}
|
|
417
|
+
if (peopleActivity.length > 0) {
|
|
418
|
+
parts.push("People Monitoring (accounts you track):");
|
|
419
|
+
for (const person of peopleActivity.slice(0, 3)) {
|
|
420
|
+
parts.push(`- @${person.handle} (${person.reason})`);
|
|
421
|
+
for (const t of person.tweets.slice(0, 2)) {
|
|
422
|
+
parts.push(` - "${t.text}" [tweet:${t.id}]`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
parts.push("");
|
|
426
|
+
}
|
|
299
427
|
parts.push("Available tools (choose one):");
|
|
300
428
|
parts.push("- post { content, reasoning }");
|
|
301
429
|
parts.push("- reply { tweetId, content, reasoning }");
|
|
@@ -312,6 +440,93 @@ function buildToolDecisionMessage(input) {
|
|
|
312
440
|
parts.push('{"action":"reply","tweetId":"123","content":"Great point. Curious: what changed your mind?","reasoning":"Directly engages a relevant mention."}');
|
|
313
441
|
return parts.join("\n");
|
|
314
442
|
}
|
|
443
|
+
function buildOpportunityPortfolioMessage(input) {
|
|
444
|
+
const identity = loadIdentity();
|
|
445
|
+
const strategy = loadStrategy();
|
|
446
|
+
const recentWritten = recentWrittenTextsForPrompt(12);
|
|
447
|
+
const overusedOpenings = findOverusedOpenings(recentWritten);
|
|
448
|
+
const overusedTokens = findOverusedTokens(recentWritten);
|
|
449
|
+
const { opportunities, maxActions, policyFeedback, executedActions } = input;
|
|
450
|
+
const parts = [];
|
|
451
|
+
parts.push(`Select a portfolio of up to ${maxActions} actions from ranked opportunities.`);
|
|
452
|
+
parts.push("");
|
|
453
|
+
parts.push("Portfolio goals:");
|
|
454
|
+
parts.push("1. Be socially immersed and grounded in real tweets.");
|
|
455
|
+
parts.push("2. Diversify actions and targets, avoid repetitive reply chains.");
|
|
456
|
+
parts.push("3. Prefer quality over quantity; skip weak opportunities.");
|
|
457
|
+
parts.push("4. Advance current strategy targets and focus areas from memory.");
|
|
458
|
+
parts.push("5. Use only listed candidate IDs.");
|
|
459
|
+
parts.push("");
|
|
460
|
+
const priorityTargets = strategy.peopleToEngage.filter((person) => person.priority === "high").map((person) => `@${person.handle.replace(/^@/, "")}`);
|
|
461
|
+
if (priorityTargets.length > 0) {
|
|
462
|
+
parts.push(`Priority targets: ${priorityTargets.slice(0, 5).join(", ")}`);
|
|
463
|
+
parts.push("When opportunities include these targets, prioritize them.");
|
|
464
|
+
parts.push("");
|
|
465
|
+
}
|
|
466
|
+
parts.push("Voice lock:");
|
|
467
|
+
for (const line of buildVoiceLockLines(identity)) {
|
|
468
|
+
parts.push(line);
|
|
469
|
+
}
|
|
470
|
+
parts.push("");
|
|
471
|
+
parts.push("Human style rotation:");
|
|
472
|
+
parts.push("- For each `reply`/`post`, pick one lane: quick reaction, curious question, friendly pushback, playful line, plain observation.");
|
|
473
|
+
parts.push("- Do not reuse the same lane for multiple content actions in this portfolio.");
|
|
474
|
+
parts.push("- Keep phrasing short and spoken; contractions and fragments are allowed.");
|
|
475
|
+
if (overusedOpenings.length > 0) {
|
|
476
|
+
parts.push(`- Avoid these repeated opening patterns: ${overusedOpenings.join(" | ")}`);
|
|
477
|
+
}
|
|
478
|
+
if (overusedTokens.length > 0) {
|
|
479
|
+
parts.push(`- Avoid overused anchor words this round: ${overusedTokens.join(", ")}`);
|
|
480
|
+
}
|
|
481
|
+
parts.push("");
|
|
482
|
+
if (policyFeedback.length > 0) {
|
|
483
|
+
parts.push("Latest policy feedback:");
|
|
484
|
+
for (const feedback of policyFeedback.slice(-6)) {
|
|
485
|
+
parts.push(`- ${feedback}`);
|
|
486
|
+
}
|
|
487
|
+
parts.push("");
|
|
488
|
+
}
|
|
489
|
+
if (executedActions.length > 0) {
|
|
490
|
+
parts.push("Actions already executed:");
|
|
491
|
+
for (const action of executedActions) {
|
|
492
|
+
parts.push(`- ${JSON.stringify(action)}`);
|
|
493
|
+
}
|
|
494
|
+
parts.push("");
|
|
495
|
+
}
|
|
496
|
+
parts.push("Opportunities (higher score = better):");
|
|
497
|
+
for (const opportunity of opportunities) {
|
|
498
|
+
parts.push(
|
|
499
|
+
`- ${opportunity.id} | action=${opportunity.actionType} | score=${opportunity.score.toFixed(2)} | source=${opportunity.source}${opportunity.authorHandle ? ` | author=@${opportunity.authorHandle}` : ""}${opportunity.tweetId ? ` | tweet=${opportunity.tweetId}` : ""}`
|
|
500
|
+
);
|
|
501
|
+
parts.push(` summary: ${opportunity.summary}`);
|
|
502
|
+
parts.push(` context: ${opportunity.context}`);
|
|
503
|
+
if (opportunity.requiresContent) {
|
|
504
|
+
parts.push(" content_required: true");
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
parts.push("");
|
|
508
|
+
parts.push("Return JSON only in this shape:");
|
|
509
|
+
parts.push("```json");
|
|
510
|
+
parts.push("{");
|
|
511
|
+
parts.push(' "selections": [');
|
|
512
|
+
parts.push(' { "candidateId": "opp-3", "content": "optional for reply/post", "reasoning": "short reason" }');
|
|
513
|
+
parts.push(" ]");
|
|
514
|
+
parts.push("}");
|
|
515
|
+
parts.push("```");
|
|
516
|
+
parts.push("Rules:");
|
|
517
|
+
parts.push("- For `reply` and `post`, include `content`.");
|
|
518
|
+
parts.push("- Keep content concise, natural, and non-repetitive.");
|
|
519
|
+
parts.push("- Avoid explanatory/essay voice. No lecture framing.");
|
|
520
|
+
parts.push("- Do NOT use abstract philosopher framing unless the identity framework is explicitly philosopher.");
|
|
521
|
+
parts.push("- Prefer short, human syntax: plain sentence fragments are fine.");
|
|
522
|
+
parts.push("- Avoid colon/semicolon/em-dash for non-philosopher personas.");
|
|
523
|
+
parts.push("- Prefer short conversational language: plain words, occasional question, and direct reaction.");
|
|
524
|
+
parts.push("- Reply content target: usually 8-24 words, max 2 short sentences.");
|
|
525
|
+
parts.push("- Prefer at least one non-reply action when viable.");
|
|
526
|
+
parts.push("- Do not target the same author repeatedly in one portfolio.");
|
|
527
|
+
parts.push("- Avoid consensus phrasing like 'you're both right' if your persona is assertive.");
|
|
528
|
+
return parts.join("\n");
|
|
529
|
+
}
|
|
315
530
|
function buildChatPrompt() {
|
|
316
531
|
const identity = loadIdentity();
|
|
317
532
|
const identityDoc = renderIdentityDocument(identity);
|
|
@@ -523,8 +738,9 @@ export {
|
|
|
523
738
|
buildSystemPrompt,
|
|
524
739
|
buildHeartbeatUserMessage,
|
|
525
740
|
buildToolDecisionMessage,
|
|
741
|
+
buildOpportunityPortfolioMessage,
|
|
526
742
|
buildChatPrompt,
|
|
527
743
|
buildTrainingChatPrompt,
|
|
528
744
|
buildReflectionPrompt
|
|
529
745
|
};
|
|
530
|
-
//# sourceMappingURL=chunk-
|
|
746
|
+
//# sourceMappingURL=chunk-A2XTKC7B.js.map
|