spora 0.4.0 → 0.5.0

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.
Files changed (49) hide show
  1. package/dist/chunk-4F7KD5JT.js +124 -0
  2. package/dist/chunk-4F7KD5JT.js.map +1 -0
  3. package/dist/{chunk-MOCLA2KK.js → chunk-6M4HISFK.js} +2 -2
  4. package/dist/{chunk-YEKHNTQO.js → chunk-B6RPMDML.js} +3 -3
  5. package/dist/chunk-B6RPMDML.js.map +1 -0
  6. package/dist/{chunk-T3JHWIKX.js → chunk-RANLXKYR.js} +3 -3
  7. package/dist/{heartbeat-2GVBKQPO.js → chunk-VYT2DS5P.js} +9 -167
  8. package/dist/chunk-VYT2DS5P.js.map +1 -0
  9. package/dist/{chunk-IIQAE7OP.js → chunk-XGTGZ2KC.js} +4 -4
  10. package/dist/{chunk-BNFUXAQW.js → chunk-ZEV5VG2T.js} +3 -3
  11. package/dist/cli.js +35 -36
  12. package/dist/cli.js.map +1 -1
  13. package/dist/{client-2ZSXZE3D.js → client-K46O47ZE.js} +3 -3
  14. package/dist/{client-2CURS7J6.js → client-X7XCA2DK.js} +3 -3
  15. package/dist/{colony-EFGAMLOX.js → colony-B2HBFCAF.js} +3 -3
  16. package/dist/{config-NZAFARS6.js → config-TFAFYSIW.js} +2 -2
  17. package/dist/decision-engine-6WCHQU2A.js +19 -0
  18. package/dist/heartbeat-YOJVMZUL.js +178 -0
  19. package/dist/heartbeat-YOJVMZUL.js.map +1 -0
  20. package/dist/{init-TODR3WR2.js → init-WQDJLWMK.js} +12 -12
  21. package/dist/init-WQDJLWMK.js.map +1 -0
  22. package/dist/{llm-OH2Z4PSN.js → llm-2CDBHU2Q.js} +3 -3
  23. package/dist/mcp-server.js +20 -20
  24. package/dist/{prompt-builder-WYB5B67W.js → prompt-builder-6KC42BML.js} +4 -4
  25. package/dist/{queue-N64QLRAB.js → queue-DJZARE2U.js} +3 -3
  26. package/dist/web-chat/chat.html +134 -0
  27. package/dist/{web-chat-L5MVPVUR.js → web-chat-OH3YXPJO.js} +108 -3
  28. package/dist/web-chat-OH3YXPJO.js.map +1 -0
  29. package/dist/{x-client-SLAC2ON5.js → x-client-3MVINKNK.js} +3 -3
  30. package/dist/x-client-3MVINKNK.js.map +1 -0
  31. package/package.json +2 -1
  32. package/dist/chunk-3FBYOHQR.js +0 -81
  33. package/dist/chunk-3FBYOHQR.js.map +0 -1
  34. package/dist/chunk-YEKHNTQO.js.map +0 -1
  35. package/dist/heartbeat-2GVBKQPO.js.map +0 -1
  36. package/dist/init-TODR3WR2.js.map +0 -1
  37. package/dist/web-chat-L5MVPVUR.js.map +0 -1
  38. /package/dist/{chunk-MOCLA2KK.js.map → chunk-6M4HISFK.js.map} +0 -0
  39. /package/dist/{chunk-T3JHWIKX.js.map → chunk-RANLXKYR.js.map} +0 -0
  40. /package/dist/{chunk-IIQAE7OP.js.map → chunk-XGTGZ2KC.js.map} +0 -0
  41. /package/dist/{chunk-BNFUXAQW.js.map → chunk-ZEV5VG2T.js.map} +0 -0
  42. /package/dist/{client-2ZSXZE3D.js.map → client-K46O47ZE.js.map} +0 -0
  43. /package/dist/{client-2CURS7J6.js.map → client-X7XCA2DK.js.map} +0 -0
  44. /package/dist/{colony-EFGAMLOX.js.map → colony-B2HBFCAF.js.map} +0 -0
  45. /package/dist/{config-NZAFARS6.js.map → config-TFAFYSIW.js.map} +0 -0
  46. /package/dist/{llm-OH2Z4PSN.js.map → decision-engine-6WCHQU2A.js.map} +0 -0
  47. /package/dist/{prompt-builder-WYB5B67W.js.map → llm-2CDBHU2Q.js.map} +0 -0
  48. /package/dist/{queue-N64QLRAB.js.map → prompt-builder-6KC42BML.js.map} +0 -0
  49. /package/dist/{x-client-SLAC2ON5.js.map → queue-DJZARE2U.js.map} +0 -0
@@ -0,0 +1,124 @@
1
+ import {
2
+ loadConfig
3
+ } from "./chunk-B6RPMDML.js";
4
+ import {
5
+ logger
6
+ } from "./chunk-KELPENM3.js";
7
+ import {
8
+ paths
9
+ } from "./chunk-53YLFYJF.js";
10
+
11
+ // src/runtime/llm.ts
12
+ import Anthropic from "@anthropic-ai/sdk";
13
+ import OpenAI from "openai";
14
+ import { readFileSync, existsSync } from "fs";
15
+ var anthropicClient = null;
16
+ var deepseekClient = null;
17
+ function getLLMApiKey() {
18
+ if (process.env.DEEPSEEK_API_KEY) {
19
+ return process.env.DEEPSEEK_API_KEY;
20
+ }
21
+ if (process.env.ANTHROPIC_API_KEY) {
22
+ return process.env.ANTHROPIC_API_KEY;
23
+ }
24
+ if (existsSync(paths.llmKey)) {
25
+ return readFileSync(paths.llmKey, "utf-8").trim();
26
+ }
27
+ return null;
28
+ }
29
+ function hasLLMKey() {
30
+ return getLLMApiKey() !== null;
31
+ }
32
+ function getAnthropicClient() {
33
+ if (anthropicClient) return anthropicClient;
34
+ const apiKey = getLLMApiKey();
35
+ if (!apiKey) {
36
+ throw new Error("No LLM API key configured. Run `spora set-llm-key` first.");
37
+ }
38
+ anthropicClient = new Anthropic({ apiKey });
39
+ return anthropicClient;
40
+ }
41
+ function getDeepSeekClient() {
42
+ if (deepseekClient) return deepseekClient;
43
+ const apiKey = process.env.DEEPSEEK_API_KEY || getLLMApiKey();
44
+ if (!apiKey) {
45
+ throw new Error("No DeepSeek API key configured. Run `spora set-llm-key` first.");
46
+ }
47
+ deepseekClient = new OpenAI({ apiKey, baseURL: "https://api.deepseek.com" });
48
+ return deepseekClient;
49
+ }
50
+ async function generateResponse(systemPrompt, userMessage) {
51
+ const config = loadConfig();
52
+ const provider = config.llm?.provider ?? "deepseek";
53
+ if (provider === "deepseek") {
54
+ return callDeepSeek(systemPrompt, [{ role: "user", content: userMessage }]);
55
+ }
56
+ const model = config.llm?.model ?? "claude-sonnet-4-20250514";
57
+ logger.info(`Calling LLM (${model})...`);
58
+ const anthropic = getAnthropicClient();
59
+ const response = await anthropic.messages.create({
60
+ model,
61
+ max_tokens: 2048,
62
+ system: systemPrompt,
63
+ messages: [{ role: "user", content: userMessage }]
64
+ });
65
+ const textBlock = response.content.find((b) => b.type === "text");
66
+ const content = textBlock ? textBlock.text : "";
67
+ logger.info(`LLM response: ${response.usage.input_tokens} in, ${response.usage.output_tokens} out`);
68
+ return {
69
+ content,
70
+ inputTokens: response.usage.input_tokens,
71
+ outputTokens: response.usage.output_tokens
72
+ };
73
+ }
74
+ async function chat(systemPrompt, messages) {
75
+ const config = loadConfig();
76
+ const provider = config.llm?.provider ?? "deepseek";
77
+ if (provider === "deepseek") {
78
+ return callDeepSeek(systemPrompt, messages);
79
+ }
80
+ const model = config.llm?.model ?? "claude-sonnet-4-20250514";
81
+ const anthropic = getAnthropicClient();
82
+ const response = await anthropic.messages.create({
83
+ model,
84
+ max_tokens: 2048,
85
+ system: systemPrompt,
86
+ messages
87
+ });
88
+ const textBlock = response.content.find((b) => b.type === "text");
89
+ const content = textBlock ? textBlock.text : "";
90
+ return {
91
+ content,
92
+ inputTokens: response.usage.input_tokens,
93
+ outputTokens: response.usage.output_tokens
94
+ };
95
+ }
96
+ async function callDeepSeek(systemPrompt, messages) {
97
+ const config = loadConfig();
98
+ const model = config.llm?.model ?? "deepseek-chat";
99
+ logger.info(`Calling DeepSeek (${model})...`);
100
+ const client = getDeepSeekClient();
101
+ const response = await client.chat.completions.create({
102
+ model,
103
+ max_tokens: 2048,
104
+ messages: [
105
+ { role: "system", content: systemPrompt },
106
+ ...messages
107
+ ]
108
+ });
109
+ const content = response.choices[0]?.message?.content ?? "";
110
+ logger.info(`DeepSeek response: ${response.usage?.prompt_tokens ?? 0} in, ${response.usage?.completion_tokens ?? 0} out`);
111
+ return {
112
+ content,
113
+ inputTokens: response.usage?.prompt_tokens ?? 0,
114
+ outputTokens: response.usage?.completion_tokens ?? 0
115
+ };
116
+ }
117
+
118
+ export {
119
+ getLLMApiKey,
120
+ hasLLMKey,
121
+ generateResponse,
122
+ chat
123
+ };
124
+ //# sourceMappingURL=chunk-4F7KD5JT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/llm.ts"],"sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { paths } from \"../utils/paths.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\n\nlet anthropicClient: Anthropic | null = null;\nlet deepseekClient: OpenAI | null = null;\n\nexport function getLLMApiKey(): string | null {\n if (process.env.DEEPSEEK_API_KEY) {\n return process.env.DEEPSEEK_API_KEY;\n }\n if (process.env.ANTHROPIC_API_KEY) {\n return process.env.ANTHROPIC_API_KEY;\n }\n if (existsSync(paths.llmKey)) {\n return readFileSync(paths.llmKey, \"utf-8\").trim();\n }\n return null;\n}\n\nexport function hasLLMKey(): boolean {\n return getLLMApiKey() !== null;\n}\n\nfunction getAnthropicClient(): Anthropic {\n if (anthropicClient) return anthropicClient;\n const apiKey = getLLMApiKey();\n if (!apiKey) {\n throw new Error(\"No LLM API key configured. Run `spora set-llm-key` first.\");\n }\n anthropicClient = new Anthropic({ apiKey });\n return anthropicClient;\n}\n\nfunction getDeepSeekClient(): OpenAI {\n if (deepseekClient) return deepseekClient;\n const apiKey = process.env.DEEPSEEK_API_KEY || getLLMApiKey();\n if (!apiKey) {\n throw new Error(\"No DeepSeek API key configured. Run `spora set-llm-key` first.\");\n }\n deepseekClient = new OpenAI({ apiKey, baseURL: \"https://api.deepseek.com\" });\n return deepseekClient;\n}\n\nexport interface LLMResponse {\n content: string;\n inputTokens: number;\n outputTokens: number;\n}\n\nexport async function generateResponse(\n systemPrompt: string,\n userMessage: string,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const provider = config.llm?.provider ?? \"deepseek\";\n\n if (provider === \"deepseek\") {\n return callDeepSeek(systemPrompt, [{ role: \"user\", content: userMessage }]);\n }\n\n const model = config.llm?.model ?? \"claude-sonnet-4-20250514\";\n logger.info(`Calling LLM (${model})...`);\n\n const anthropic = getAnthropicClient();\n const response = await anthropic.messages.create({\n model,\n max_tokens: 2048,\n system: systemPrompt,\n messages: [{ role: \"user\", content: userMessage }],\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n const content = textBlock ? textBlock.text : \"\";\n\n logger.info(`LLM response: ${response.usage.input_tokens} in, ${response.usage.output_tokens} out`);\n\n return {\n content,\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n };\n}\n\nexport async function chat(\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const provider = config.llm?.provider ?? \"deepseek\";\n\n if (provider === \"deepseek\") {\n return callDeepSeek(systemPrompt, messages);\n }\n\n const model = config.llm?.model ?? \"claude-sonnet-4-20250514\";\n\n const anthropic = getAnthropicClient();\n const response = await anthropic.messages.create({\n model,\n max_tokens: 2048,\n system: systemPrompt,\n messages,\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n const content = textBlock ? textBlock.text : \"\";\n\n return {\n content,\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n };\n}\n\nasync function callDeepSeek(\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const model = config.llm?.model ?? \"deepseek-chat\";\n\n logger.info(`Calling DeepSeek (${model})...`);\n\n const client = getDeepSeekClient();\n const response = await client.chat.completions.create({\n model,\n max_tokens: 2048,\n messages: [\n { role: \"system\", content: systemPrompt },\n ...messages,\n ],\n });\n\n const content = response.choices[0]?.message?.content ?? \"\";\n\n logger.info(`DeepSeek response: ${response.usage?.prompt_tokens ?? 0} in, ${response.usage?.completion_tokens ?? 0} out`);\n\n return {\n content,\n inputTokens: response.usage?.prompt_tokens ?? 0,\n outputTokens: response.usage?.completion_tokens ?? 0,\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadConfig,
3
3
  saveConfig
4
- } from "./chunk-YEKHNTQO.js";
4
+ } from "./chunk-B6RPMDML.js";
5
5
  import {
6
6
  logger
7
7
  } from "./chunk-KELPENM3.js";
@@ -54,4 +54,4 @@ var rateLimiter = new RateLimiter();
54
54
  export {
55
55
  rateLimiter
56
56
  };
57
- //# sourceMappingURL=chunk-MOCLA2KK.js.map
57
+ //# sourceMappingURL=chunk-6M4HISFK.js.map
@@ -22,8 +22,8 @@ var ConfigSchema = z.object({
22
22
  timezone: z.string()
23
23
  }),
24
24
  llm: z.object({
25
- provider: z.enum(["anthropic", "openai"]).default("anthropic"),
26
- model: z.string().default("claude-sonnet-4-20250514")
25
+ provider: z.enum(["anthropic", "openai", "deepseek"]).default("deepseek"),
26
+ model: z.string().default("deepseek-chat")
27
27
  }).optional(),
28
28
  runtime: z.object({
29
29
  heartbeatIntervalMs: z.number().default(3e5),
@@ -77,4 +77,4 @@ export {
77
77
  saveConfig,
78
78
  createDefaultConfig
79
79
  };
80
- //# sourceMappingURL=chunk-YEKHNTQO.js.map
80
+ //# sourceMappingURL=chunk-B6RPMDML.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/config.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { z } from \"zod\";\nimport { paths, ensureDirectories } from \"./paths.js\";\n\nexport const ConfigSchema = z.object({\n version: z.literal(1),\n xMethod: z.enum([\"api\", \"browser\"]),\n xApiTier: z.enum([\"free\", \"basic\"]).optional(),\n\n credits: z.object({\n monthlyPostLimit: z.number(),\n postsUsedThisMonth: z.number(),\n resetDate: z.string(),\n }),\n\n schedule: z.object({\n postsPerDay: z.number(),\n activeHoursStart: z.number().min(0).max(23),\n activeHoursEnd: z.number().min(0).max(23),\n timezone: z.string(),\n }),\n\n llm: z.object({\n provider: z.enum([\"anthropic\", \"openai\", \"deepseek\"]).default(\"deepseek\"),\n model: z.string().default(\"deepseek-chat\"),\n }).optional(),\n\n runtime: z.object({\n heartbeatIntervalMs: z.number().default(300_000),\n actionsPerHeartbeat: z.number().default(3),\n enabled: z.boolean().default(false),\n }).optional(),\n\n connection: z.object({\n token: z.string().optional(),\n apiEndpoint: z.string().default(\"https://spora.dev/api/v1\"),\n lastSync: z.string().optional(),\n configVersion: z.number().default(0),\n }).optional(),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nexport function loadConfig(): Config {\n if (!existsSync(paths.config)) {\n throw new Error(\"Spora not initialized. Run `spora init` first.\");\n }\n const raw = readFileSync(paths.config, \"utf-8\");\n return ConfigSchema.parse(JSON.parse(raw));\n}\n\nexport function saveConfig(config: Config): void {\n ensureDirectories();\n ConfigSchema.parse(config);\n writeFileSync(paths.config, JSON.stringify(config, null, 2));\n}\n\nexport function createDefaultConfig(overrides: {\n xMethod: \"api\" | \"browser\";\n xApiTier?: \"free\" | \"basic\";\n timezone?: string;\n}): Config {\n const monthlyLimit = overrides.xApiTier === \"basic\" ? 10000 : 500;\n const now = new Date();\n const resetDate = new Date(now.getFullYear(), now.getMonth() + 1, 1).toISOString();\n\n return {\n version: 1,\n xMethod: overrides.xMethod,\n xApiTier: overrides.xApiTier,\n credits: {\n monthlyPostLimit: monthlyLimit,\n postsUsedThisMonth: 0,\n resetDate,\n },\n schedule: {\n postsPerDay: Math.floor(monthlyLimit / 30),\n activeHoursStart: 8,\n activeHoursEnd: 22,\n timezone: overrides.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone,\n },\n };\n}\n"],"mappings":";;;;;;AAAA,SAAS,cAAc,eAAe,kBAAkB;AACxD,SAAS,SAAS;AAGX,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,SAAS,EAAE,QAAQ,CAAC;AAAA,EACpB,SAAS,EAAE,KAAK,CAAC,OAAO,SAAS,CAAC;AAAA,EAClC,UAAU,EAAE,KAAK,CAAC,QAAQ,OAAO,CAAC,EAAE,SAAS;AAAA,EAE7C,SAAS,EAAE,OAAO;AAAA,IAChB,kBAAkB,EAAE,OAAO;AAAA,IAC3B,oBAAoB,EAAE,OAAO;AAAA,IAC7B,WAAW,EAAE,OAAO;AAAA,EACtB,CAAC;AAAA,EAED,UAAU,EAAE,OAAO;AAAA,IACjB,aAAa,EAAE,OAAO;AAAA,IACtB,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,IAC1C,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,IACxC,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EAED,KAAK,EAAE,OAAO;AAAA,IACZ,UAAU,EAAE,KAAK,CAAC,aAAa,UAAU,UAAU,CAAC,EAAE,QAAQ,UAAU;AAAA,IACxE,OAAO,EAAE,OAAO,EAAE,QAAQ,eAAe;AAAA,EAC3C,CAAC,EAAE,SAAS;AAAA,EAEZ,SAAS,EAAE,OAAO;AAAA,IAChB,qBAAqB,EAAE,OAAO,EAAE,QAAQ,GAAO;AAAA,IAC/C,qBAAqB,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,IACzC,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACpC,CAAC,EAAE,SAAS;AAAA,EAEZ,YAAY,EAAE,OAAO;AAAA,IACnB,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,aAAa,EAAE,OAAO,EAAE,QAAQ,0BAA0B;AAAA,IAC1D,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,EACrC,CAAC,EAAE,SAAS;AACd,CAAC;AAIM,SAAS,aAAqB;AACnC,MAAI,CAAC,WAAW,MAAM,MAAM,GAAG;AAC7B,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,QAAM,MAAM,aAAa,MAAM,QAAQ,OAAO;AAC9C,SAAO,aAAa,MAAM,KAAK,MAAM,GAAG,CAAC;AAC3C;AAEO,SAAS,WAAW,QAAsB;AAC/C,oBAAkB;AAClB,eAAa,MAAM,MAAM;AACzB,gBAAc,MAAM,QAAQ,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7D;AAEO,SAAS,oBAAoB,WAIzB;AACT,QAAM,eAAe,UAAU,aAAa,UAAU,MAAQ;AAC9D,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,YAAY,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,IAAI,GAAG,CAAC,EAAE,YAAY;AAEjF,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,UAAU;AAAA,IACnB,UAAU,UAAU;AAAA,IACpB,SAAS;AAAA,MACP,kBAAkB;AAAA,MAClB,oBAAoB;AAAA,MACpB;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,aAAa,KAAK,MAAM,eAAe,EAAE;AAAA,MACzC,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,UAAU,UAAU,YAAY,KAAK,eAAe,EAAE,gBAAgB,EAAE;AAAA,IAC1E;AAAA,EACF;AACF;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-YEKHNTQO.js";
3
+ } from "./chunk-B6RPMDML.js";
4
4
  import {
5
5
  logger
6
6
  } from "./chunk-KELPENM3.js";
@@ -67,7 +67,7 @@ async function flushQueue() {
67
67
  const now = /* @__PURE__ */ new Date();
68
68
  let posted = 0;
69
69
  let failed = 0;
70
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
70
+ const { getXClient } = await import("./x-client-3MVINKNK.js");
71
71
  const client = await getXClient();
72
72
  for (const entry of queue.entries) {
73
73
  if (entry.status !== "pending") continue;
@@ -121,4 +121,4 @@ export {
121
121
  flushQueue,
122
122
  showQueue
123
123
  };
124
- //# sourceMappingURL=chunk-T3JHWIKX.js.map
124
+ //# sourceMappingURL=chunk-RANLXKYR.js.map
@@ -1,23 +1,12 @@
1
- import {
2
- buildHeartbeatUserMessage,
3
- buildSystemPrompt
4
- } from "./chunk-BNFUXAQW.js";
5
- import {
6
- generateResponse
7
- } from "./chunk-3FBYOHQR.js";
8
- import {
9
- rateLimiter
10
- } from "./chunk-MOCLA2KK.js";
11
1
  import {
12
2
  getXClient
13
- } from "./chunk-IIQAE7OP.js";
3
+ } from "./chunk-XGTGZ2KC.js";
14
4
  import {
15
- addToQueue,
16
- flushQueue
17
- } from "./chunk-T3JHWIKX.js";
5
+ addToQueue
6
+ } from "./chunk-RANLXKYR.js";
18
7
  import {
19
- loadConfig
20
- } from "./chunk-YEKHNTQO.js";
8
+ rateLimiter
9
+ } from "./chunk-6M4HISFK.js";
21
10
  import {
22
11
  loadIdentity,
23
12
  saveIdentity
@@ -29,12 +18,6 @@ import {
29
18
  addLearning,
30
19
  logInteraction
31
20
  } from "./chunk-EBO4F5NU.js";
32
- import {
33
- paths
34
- } from "./chunk-53YLFYJF.js";
35
-
36
- // src/runtime/heartbeat.ts
37
- import { existsSync, unlinkSync, writeFileSync, readFileSync } from "fs";
38
21
 
39
22
  // src/runtime/decision-engine.ts
40
23
  function parseActions(llmResponse) {
@@ -209,150 +192,9 @@ async function executeActions(actions) {
209
192
  return results;
210
193
  }
211
194
 
212
- // src/runtime/heartbeat.ts
213
- var running = false;
214
- function isRunning() {
215
- return running;
216
- }
217
- function requestStop() {
218
- writeFileSync(paths.stopSignal, "stop");
219
- logger.info("Stop signal sent.");
220
- }
221
- function shouldStop() {
222
- if (existsSync(paths.stopSignal)) {
223
- unlinkSync(paths.stopSignal);
224
- return true;
225
- }
226
- return false;
227
- }
228
- function writePid() {
229
- writeFileSync(paths.runtimePid, String(process.pid));
230
- }
231
- function clearPid() {
232
- if (existsSync(paths.runtimePid)) {
233
- unlinkSync(paths.runtimePid);
234
- }
235
- }
236
- function getRunningPid() {
237
- if (!existsSync(paths.runtimePid)) return null;
238
- const pid = parseInt(readFileSync(paths.runtimePid, "utf-8").trim(), 10);
239
- if (isNaN(pid)) return null;
240
- try {
241
- process.kill(pid, 0);
242
- return pid;
243
- } catch {
244
- clearPid();
245
- return null;
246
- }
247
- }
248
- async function startHeartbeatLoop() {
249
- const existingPid = getRunningPid();
250
- if (existingPid) {
251
- throw new Error(`Spora is already running (PID ${existingPid}). Run \`spora stop\` first.`);
252
- }
253
- running = true;
254
- writePid();
255
- const config = loadConfig();
256
- const intervalMs = config.runtime?.heartbeatIntervalMs ?? 3e5;
257
- const maxActions = config.runtime?.actionsPerHeartbeat ?? 3;
258
- logger.info(`Spora agent starting. Heartbeat interval: ${intervalMs / 1e3}s, max actions: ${maxActions}`);
259
- console.log(`
260
- Spora agent is running (PID ${process.pid})`);
261
- console.log(`Heartbeat every ${Math.round(intervalMs / 6e4)} minutes`);
262
- console.log(`Press Ctrl+C or run \`spora stop\` to stop.
263
- `);
264
- const shutdown = () => {
265
- logger.info("Shutting down...");
266
- running = false;
267
- clearPid();
268
- process.exit(0);
269
- };
270
- process.on("SIGINT", shutdown);
271
- process.on("SIGTERM", shutdown);
272
- if (existsSync(paths.stopSignal)) {
273
- unlinkSync(paths.stopSignal);
274
- }
275
- let heartbeatCount = 0;
276
- while (running) {
277
- heartbeatCount++;
278
- logger.info(`=== Heartbeat #${heartbeatCount} ===`);
279
- try {
280
- await runHeartbeat(maxActions);
281
- } catch (error) {
282
- logger.error("Heartbeat error", error);
283
- console.error(`Heartbeat #${heartbeatCount} failed: ${error.message}`);
284
- }
285
- if (shouldStop()) {
286
- logger.info("Stop signal received.");
287
- break;
288
- }
289
- const jitter = Math.floor(Math.random() * intervalMs * 0.3);
290
- const sleepMs = intervalMs + jitter;
291
- logger.info(`Sleeping ${Math.round(sleepMs / 1e3)}s until next heartbeat...`);
292
- const chunkMs = 1e4;
293
- let slept = 0;
294
- while (slept < sleepMs && running) {
295
- await new Promise((r) => setTimeout(r, Math.min(chunkMs, sleepMs - slept)));
296
- slept += chunkMs;
297
- if (shouldStop()) {
298
- running = false;
299
- break;
300
- }
301
- }
302
- }
303
- clearPid();
304
- logger.info("Spora agent stopped.");
305
- console.log("\nSpora agent stopped.");
306
- }
307
- async function runHeartbeat(maxActions) {
308
- logger.info("Checking queue...");
309
- try {
310
- const flushed = await flushQueue();
311
- if (flushed.posted > 0) {
312
- logger.info(`Flushed ${flushed.posted} queued posts.`);
313
- }
314
- } catch (error) {
315
- logger.warn(`Queue flush failed: ${error.message}`);
316
- }
317
- logger.info("Reading timeline and mentions...");
318
- const client = await getXClient();
319
- let timeline = [];
320
- let mentions = [];
321
- try {
322
- timeline = await client.getTimeline({ count: 20 });
323
- } catch (error) {
324
- logger.warn(`Timeline read failed: ${error.message}`);
325
- }
326
- try {
327
- mentions = await client.getMentions({ count: 10 });
328
- } catch (error) {
329
- logger.warn(`Mentions read failed: ${error.message}`);
330
- }
331
- const systemPrompt = buildSystemPrompt();
332
- const userMessage = buildHeartbeatUserMessage(timeline, mentions);
333
- logger.info("Asking LLM for decisions...");
334
- const response = await generateResponse(systemPrompt, userMessage);
335
- const actions = parseActions(response.content);
336
- if (actions.length === 0) {
337
- logger.info("LLM returned no actions.");
338
- return;
339
- }
340
- const limitedActions = actions.slice(0, maxActions);
341
- logger.info(`Executing ${limitedActions.length} action(s)...`);
342
- const results = await executeActions(limitedActions);
343
- for (const result of results) {
344
- if (result.success) {
345
- logger.info(` [OK] ${result.action}${result.detail ? `: ${result.detail}` : ""}`);
346
- } else {
347
- logger.warn(` [FAIL] ${result.action}: ${result.error}`);
348
- }
349
- }
350
- logger.info(`Heartbeat complete. ${results.filter((r) => r.success).length}/${results.length} actions succeeded.`);
351
- }
352
195
  export {
353
- getRunningPid,
354
- isRunning,
355
- requestStop,
356
- startHeartbeatLoop
196
+ parseActions,
197
+ executeAction,
198
+ executeActions
357
199
  };
358
- //# sourceMappingURL=heartbeat-2GVBKQPO.js.map
200
+ //# sourceMappingURL=chunk-VYT2DS5P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/decision-engine.ts"],"sourcesContent":["import { logger } from \"../utils/logger.js\";\nimport { getXClient } from \"../x-client/index.js\";\nimport { logInteraction, addLearning } from \"../memory/index.js\";\nimport { loadIdentity, saveIdentity } from \"../identity/index.js\";\nimport { addToQueue } from \"../scheduler/queue.js\";\nimport { rateLimiter } from \"../x-client/rate-limiter.js\";\n\nexport interface AgentAction {\n action: string;\n content?: string;\n tweetId?: string;\n handle?: string;\n tags?: string[];\n reason?: string;\n reasoning?: string;\n}\n\nexport interface ActionResult {\n action: string;\n success: boolean;\n detail?: string;\n error?: string;\n}\n\nexport function parseActions(llmResponse: string): AgentAction[] {\n // Extract JSON array from the response (may be wrapped in markdown code blocks)\n const jsonMatch = llmResponse.match(/\\[[\\s\\S]*?\\]/);\n if (!jsonMatch) {\n // Try to parse as a single action object\n const objMatch = llmResponse.match(/\\{[\\s\\S]*?\\}/);\n if (objMatch) {\n try {\n return [JSON.parse(objMatch[0]) as AgentAction];\n } catch {\n logger.warn(\"Could not parse LLM response as action object\");\n return [];\n }\n }\n logger.warn(\"No JSON found in LLM response\");\n return [];\n }\n\n try {\n const actions = JSON.parse(jsonMatch[0]) as AgentAction[];\n return Array.isArray(actions) ? actions : [actions];\n } catch {\n logger.warn(\"Failed to parse actions JSON from LLM response\");\n return [];\n }\n}\n\nexport async function executeAction(action: AgentAction): Promise<ActionResult> {\n const { action: type } = action;\n\n try {\n switch (type) {\n case \"post\": {\n if (!action.content) return { action: type, success: false, error: \"No content provided\" };\n if (action.content.length > 280) {\n return { action: type, success: false, error: `Tweet too long: ${action.content.length} chars (max 280)` };\n }\n if (!rateLimiter.canPost()) {\n return { action: type, success: false, error: \"No credits remaining this month\" };\n }\n\n const client = await getXClient();\n const result = await client.postTweet(action.content);\n if (result.success) {\n rateLimiter.consume(1);\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"post\",\n tweetId: result.tweetId,\n content: action.content,\n creditsUsed: 1,\n success: true,\n });\n logger.info(`Posted: \"${action.content.slice(0, 50)}...\"`);\n }\n return { action: type, success: result.success, detail: result.tweetId, error: result.error };\n }\n\n case \"reply\": {\n if (!action.tweetId || !action.content) {\n return { action: type, success: false, error: \"Missing tweetId or content\" };\n }\n if (!rateLimiter.canPost()) {\n return { action: type, success: false, error: \"No credits remaining\" };\n }\n\n const client = await getXClient();\n const result = await client.replyToTweet(action.tweetId, action.content);\n if (result.success) {\n rateLimiter.consume(1);\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"reply\",\n tweetId: result.tweetId,\n inReplyTo: action.tweetId,\n content: action.content,\n creditsUsed: 1,\n success: true,\n });\n logger.info(`Replied to ${action.tweetId}: \"${action.content.slice(0, 50)}...\"`);\n }\n return { action: type, success: result.success, detail: result.tweetId, error: result.error };\n }\n\n case \"like\": {\n if (!action.tweetId) return { action: type, success: false, error: \"Missing tweetId\" };\n const client = await getXClient();\n const result = await client.likeTweet(action.tweetId);\n if (result.success) {\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"like\",\n tweetId: action.tweetId,\n creditsUsed: 0,\n success: true,\n });\n }\n return { action: type, success: result.success, error: result.error };\n }\n\n case \"retweet\": {\n if (!action.tweetId) return { action: type, success: false, error: \"Missing tweetId\" };\n const client = await getXClient();\n const result = await client.retweet(action.tweetId);\n if (result.success) {\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"retweet\",\n tweetId: action.tweetId,\n creditsUsed: 0,\n success: true,\n });\n }\n return { action: type, success: result.success, error: result.error };\n }\n\n case \"follow\": {\n if (!action.handle) return { action: type, success: false, error: \"Missing handle\" };\n const client = await getXClient();\n const result = await client.followUser(action.handle);\n if (result.success) {\n logInteraction({\n id: `int-${Date.now()}`,\n timestamp: new Date().toISOString(),\n type: \"follow\",\n targetHandle: action.handle,\n creditsUsed: 0,\n success: true,\n });\n }\n return { action: type, success: result.success, error: result.error };\n }\n\n case \"schedule\": {\n if (!action.content) return { action: type, success: false, error: \"No content\" };\n const entry = addToQueue(action.content);\n logger.info(`Scheduled: \"${action.content.slice(0, 50)}...\" for ${entry.scheduledFor}`);\n return { action: type, success: true, detail: `Scheduled for ${entry.scheduledFor}` };\n }\n\n case \"learn\": {\n if (!action.content) return { action: type, success: false, error: \"No content\" };\n addLearning(action.content, \"agent\", action.tags ?? [\"heartbeat\"]);\n logger.info(`Learned: \"${action.content.slice(0, 50)}...\"`);\n return { action: type, success: true };\n }\n\n case \"reflect\": {\n if (!action.content) return { action: type, success: false, error: \"No content\" };\n const identity = loadIdentity();\n identity.evolutionJournal.push({\n date: new Date().toISOString(),\n reflection: action.content,\n });\n saveIdentity(identity);\n logger.info(`Reflected: \"${action.content.slice(0, 50)}...\"`);\n return { action: type, success: true };\n }\n\n case \"skip\": {\n logger.info(`Skipping: ${action.reason ?? action.reasoning ?? \"no reason given\"}`);\n return { action: type, success: true, detail: action.reason ?? action.reasoning };\n }\n\n default:\n logger.warn(`Unknown action: ${type}`);\n return { action: type, success: false, error: `Unknown action: ${type}` };\n }\n } catch (error) {\n const msg = (error as Error).message;\n logger.error(`Action ${type} failed: ${msg}`);\n return { action: type, success: false, error: msg };\n }\n}\n\nexport async function executeActions(actions: AgentAction[]): Promise<ActionResult[]> {\n const results: ActionResult[] = [];\n for (const action of actions) {\n const result = await executeAction(action);\n results.push(result);\n // Small delay between actions to be human-like\n await new Promise((r) => setTimeout(r, 2000 + Math.random() * 3000));\n }\n return results;\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-YEKHNTQO.js";
3
+ } from "./chunk-B6RPMDML.js";
4
4
  import {
5
5
  logger
6
6
  } from "./chunk-KELPENM3.js";
@@ -11,11 +11,11 @@ async function getXClient() {
11
11
  if (clientInstance) return clientInstance;
12
12
  const config = loadConfig();
13
13
  if (config.xMethod === "api") {
14
- const { XApiClient } = await import("./client-2ZSXZE3D.js");
14
+ const { XApiClient } = await import("./client-K46O47ZE.js");
15
15
  clientInstance = new XApiClient();
16
16
  logger.info("X client initialized: API mode");
17
17
  } else {
18
- const { XBrowserClient } = await import("./client-2CURS7J6.js");
18
+ const { XBrowserClient } = await import("./client-X7XCA2DK.js");
19
19
  clientInstance = new XBrowserClient();
20
20
  logger.info("X client initialized: Browser mode");
21
21
  }
@@ -29,4 +29,4 @@ export {
29
29
  getXClient,
30
30
  resetXClient
31
31
  };
32
- //# sourceMappingURL=chunk-IIQAE7OP.js.map
32
+ //# sourceMappingURL=chunk-XGTGZ2KC.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  rateLimiter
3
- } from "./chunk-MOCLA2KK.js";
3
+ } from "./chunk-6M4HISFK.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-YEKHNTQO.js";
6
+ } from "./chunk-B6RPMDML.js";
7
7
  import {
8
8
  loadIdentity,
9
9
  renderIdentityDocument
@@ -200,4 +200,4 @@ export {
200
200
  buildHeartbeatUserMessage,
201
201
  buildChatPrompt
202
202
  };
203
- //# sourceMappingURL=chunk-BNFUXAQW.js.map
203
+ //# sourceMappingURL=chunk-ZEV5VG2T.js.map