spora 0.3.4 → 0.3.6
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/{chunk-KQ37VL54.js → chunk-2L3N2H2J.js} +4 -4
- package/dist/{chunk-PNZ3XK2N.js → chunk-33RBC6EK.js} +3 -3
- package/dist/chunk-52D7W3J3.js +114 -0
- package/dist/chunk-52D7W3J3.js.map +1 -0
- package/dist/{chunk-GMSK775L.js → chunk-CSVTWZFG.js} +3 -3
- package/dist/chunk-CSVTWZFG.js.map +1 -0
- package/dist/{chunk-ML4EMUZC.js → chunk-VO22ASDZ.js} +2 -2
- package/dist/{chunk-B6VI6L4D.js → chunk-XL67LOSQ.js} +3 -3
- package/dist/cli.js +60 -42
- package/dist/cli.js.map +1 -1
- package/dist/{client-TWYR2IIQ.js → client-6ZQEQIQS.js} +3 -3
- package/dist/{client-BGLXHLID.js → client-OJSDO5LF.js} +3 -3
- package/dist/{colony-JVBCMZTK.js → colony-RFGN2GMM.js} +3 -3
- package/dist/{config-5EPXA325.js → config-4LP52J2E.js} +2 -2
- package/dist/{heartbeat-B2CZKMUF.js → heartbeat-25KM7SUX.js} +7 -7
- package/dist/{init-KXNLBFMG.js → init-II73AQIG.js} +45 -12
- package/dist/init-II73AQIG.js.map +1 -0
- package/dist/{llm-CUCO24K7.js → llm-2RNHCOGC.js} +3 -3
- package/dist/mcp-server.js +20 -20
- package/dist/{prompt-builder-VHGZFBL6.js → prompt-builder-64EEQLIZ.js} +4 -4
- package/dist/{queue-LNBQWMFX.js → queue-LSXMZYM6.js} +3 -3
- package/dist/{web-chat-DHHJTGFZ.js → web-chat-TFMTA3VT.js} +3 -3
- package/dist/{x-client-W5IB7XOM.js → x-client-64DT2QIP.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-GMSK775L.js.map +0 -1
- package/dist/chunk-N5TBL3NY.js +0 -86
- package/dist/chunk-N5TBL3NY.js.map +0 -1
- package/dist/init-KXNLBFMG.js.map +0 -1
- /package/dist/{chunk-KQ37VL54.js.map → chunk-2L3N2H2J.js.map} +0 -0
- /package/dist/{chunk-PNZ3XK2N.js.map → chunk-33RBC6EK.js.map} +0 -0
- /package/dist/{chunk-ML4EMUZC.js.map → chunk-VO22ASDZ.js.map} +0 -0
- /package/dist/{chunk-B6VI6L4D.js.map → chunk-XL67LOSQ.js.map} +0 -0
- /package/dist/{client-TWYR2IIQ.js.map → client-6ZQEQIQS.js.map} +0 -0
- /package/dist/{client-BGLXHLID.js.map → client-OJSDO5LF.js.map} +0 -0
- /package/dist/{colony-JVBCMZTK.js.map → colony-RFGN2GMM.js.map} +0 -0
- /package/dist/{config-5EPXA325.js.map → config-4LP52J2E.js.map} +0 -0
- /package/dist/{heartbeat-B2CZKMUF.js.map → heartbeat-25KM7SUX.js.map} +0 -0
- /package/dist/{llm-CUCO24K7.js.map → llm-2RNHCOGC.js.map} +0 -0
- /package/dist/{prompt-builder-VHGZFBL6.js.map → prompt-builder-64EEQLIZ.js.map} +0 -0
- /package/dist/{queue-LNBQWMFX.js.map → queue-LSXMZYM6.js.map} +0 -0
- /package/dist/{web-chat-DHHJTGFZ.js.map → web-chat-TFMTA3VT.js.map} +0 -0
- /package/dist/{x-client-W5IB7XOM.js.map → x-client-64DT2QIP.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CSVTWZFG.js";
|
|
4
4
|
import {
|
|
5
5
|
logger
|
|
6
6
|
} from "./chunk-UCCAF2ZO.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-
|
|
14
|
+
const { XApiClient } = await import("./client-6ZQEQIQS.js");
|
|
15
15
|
clientInstance = new XApiClient();
|
|
16
16
|
logger.info("X client initialized: API mode");
|
|
17
17
|
} else {
|
|
18
|
-
const { XBrowserClient } = await import("./client-
|
|
18
|
+
const { XBrowserClient } = await import("./client-OJSDO5LF.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-
|
|
32
|
+
//# sourceMappingURL=chunk-2L3N2H2J.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
rateLimiter
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VO22ASDZ.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CSVTWZFG.js";
|
|
7
7
|
import {
|
|
8
8
|
loadIdentity,
|
|
9
9
|
renderIdentityDocument
|
|
@@ -355,4 +355,4 @@ export {
|
|
|
355
355
|
buildChatPrompt,
|
|
356
356
|
buildModeSpecificUserMessage
|
|
357
357
|
};
|
|
358
|
-
//# sourceMappingURL=chunk-
|
|
358
|
+
//# sourceMappingURL=chunk-33RBC6EK.js.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadConfig
|
|
3
|
+
} from "./chunk-CSVTWZFG.js";
|
|
4
|
+
import {
|
|
5
|
+
logger
|
|
6
|
+
} from "./chunk-UCCAF2ZO.js";
|
|
7
|
+
import {
|
|
8
|
+
paths
|
|
9
|
+
} from "./chunk-6KCIAMHL.js";
|
|
10
|
+
|
|
11
|
+
// src/runtime/llm.ts
|
|
12
|
+
import OpenAI from "openai";
|
|
13
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
14
|
+
import { readFileSync, existsSync } from "fs";
|
|
15
|
+
var openaiClient = null;
|
|
16
|
+
var anthropicClient = null;
|
|
17
|
+
var DEFAULT_MODEL = "deepseek-chat";
|
|
18
|
+
var DEFAULT_BASE_URL = "https://api.deepseek.com";
|
|
19
|
+
function getLLMApiKey() {
|
|
20
|
+
if (process.env.LLM_API_KEY) {
|
|
21
|
+
return process.env.LLM_API_KEY;
|
|
22
|
+
}
|
|
23
|
+
if (process.env.ANTHROPIC_API_KEY) {
|
|
24
|
+
return process.env.ANTHROPIC_API_KEY;
|
|
25
|
+
}
|
|
26
|
+
if (existsSync(paths.llmKey)) {
|
|
27
|
+
return readFileSync(paths.llmKey, "utf-8").trim();
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
function hasLLMKey() {
|
|
32
|
+
return getLLMApiKey() !== null;
|
|
33
|
+
}
|
|
34
|
+
function getProvider() {
|
|
35
|
+
try {
|
|
36
|
+
const config = loadConfig();
|
|
37
|
+
return config.llm?.provider ?? "deepseek";
|
|
38
|
+
} catch {
|
|
39
|
+
return "deepseek";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function getOpenAIClient() {
|
|
43
|
+
if (openaiClient) return openaiClient;
|
|
44
|
+
const apiKey = getLLMApiKey();
|
|
45
|
+
if (!apiKey) throw new Error("No LLM API key configured. Run `spora set-llm-key` first.");
|
|
46
|
+
const config = loadConfig();
|
|
47
|
+
const baseURL = config.llm?.baseUrl ?? DEFAULT_BASE_URL;
|
|
48
|
+
openaiClient = new OpenAI({ apiKey, baseURL });
|
|
49
|
+
return openaiClient;
|
|
50
|
+
}
|
|
51
|
+
function getAnthropicClient() {
|
|
52
|
+
if (anthropicClient) return anthropicClient;
|
|
53
|
+
const apiKey = getLLMApiKey();
|
|
54
|
+
if (!apiKey) throw new Error("No LLM API key configured. Run `spora set-llm-key` first.");
|
|
55
|
+
anthropicClient = new Anthropic({ apiKey });
|
|
56
|
+
return anthropicClient;
|
|
57
|
+
}
|
|
58
|
+
async function callAnthropic(systemPrompt, messages, model) {
|
|
59
|
+
const client = getAnthropicClient();
|
|
60
|
+
const response = await client.messages.create({
|
|
61
|
+
model,
|
|
62
|
+
max_tokens: 2048,
|
|
63
|
+
system: systemPrompt,
|
|
64
|
+
messages
|
|
65
|
+
});
|
|
66
|
+
const textBlock = response.content.find((b) => b.type === "text");
|
|
67
|
+
const content = textBlock ? textBlock.text : "";
|
|
68
|
+
return {
|
|
69
|
+
content,
|
|
70
|
+
inputTokens: response.usage.input_tokens,
|
|
71
|
+
outputTokens: response.usage.output_tokens
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function callOpenAI(systemPrompt, messages, model) {
|
|
75
|
+
const client = getOpenAIClient();
|
|
76
|
+
const response = await client.chat.completions.create({
|
|
77
|
+
model,
|
|
78
|
+
max_tokens: 2048,
|
|
79
|
+
messages: [
|
|
80
|
+
{ role: "system", content: systemPrompt },
|
|
81
|
+
...messages
|
|
82
|
+
]
|
|
83
|
+
});
|
|
84
|
+
const content = response.choices[0]?.message?.content ?? "";
|
|
85
|
+
const inputTokens = response.usage?.prompt_tokens ?? 0;
|
|
86
|
+
const outputTokens = response.usage?.completion_tokens ?? 0;
|
|
87
|
+
return { content, inputTokens, outputTokens };
|
|
88
|
+
}
|
|
89
|
+
async function generateResponse(systemPrompt, userMessage) {
|
|
90
|
+
const config = loadConfig();
|
|
91
|
+
const provider = getProvider();
|
|
92
|
+
const model = config.llm?.model ?? DEFAULT_MODEL;
|
|
93
|
+
logger.info(`Calling LLM (${provider}/${model})...`);
|
|
94
|
+
const messages = [
|
|
95
|
+
{ role: "user", content: userMessage }
|
|
96
|
+
];
|
|
97
|
+
const result = provider === "anthropic" ? await callAnthropic(systemPrompt, messages, model) : await callOpenAI(systemPrompt, messages, model);
|
|
98
|
+
logger.info(`LLM response: ${result.inputTokens} in, ${result.outputTokens} out`);
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
async function chat(systemPrompt, messages) {
|
|
102
|
+
const config = loadConfig();
|
|
103
|
+
const provider = getProvider();
|
|
104
|
+
const model = config.llm?.model ?? DEFAULT_MODEL;
|
|
105
|
+
return provider === "anthropic" ? callAnthropic(systemPrompt, messages, model) : callOpenAI(systemPrompt, messages, model);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export {
|
|
109
|
+
getLLMApiKey,
|
|
110
|
+
hasLLMKey,
|
|
111
|
+
generateResponse,
|
|
112
|
+
chat
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=chunk-52D7W3J3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/llm.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport Anthropic from \"@anthropic-ai/sdk\";\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 openaiClient: OpenAI | null = null;\nlet anthropicClient: Anthropic | null = null;\n\nconst DEFAULT_MODEL = \"deepseek-chat\";\nconst DEFAULT_BASE_URL = \"https://api.deepseek.com\";\n\nexport function getLLMApiKey(): string | null {\n if (process.env.LLM_API_KEY) {\n return process.env.LLM_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 getProvider(): \"anthropic\" | \"deepseek\" {\n try {\n const config = loadConfig();\n return (config.llm?.provider as \"anthropic\" | \"deepseek\") ?? \"deepseek\";\n } catch {\n return \"deepseek\";\n }\n}\n\nfunction getOpenAIClient(): OpenAI {\n if (openaiClient) return openaiClient;\n const apiKey = getLLMApiKey();\n if (!apiKey) throw new Error(\"No LLM API key configured. Run `spora set-llm-key` first.\");\n const config = loadConfig();\n const baseURL = config.llm?.baseUrl ?? DEFAULT_BASE_URL;\n openaiClient = new OpenAI({ apiKey, baseURL });\n return openaiClient;\n}\n\nfunction getAnthropicClient(): Anthropic {\n if (anthropicClient) return anthropicClient;\n const apiKey = getLLMApiKey();\n if (!apiKey) throw new Error(\"No LLM API key configured. Run `spora set-llm-key` first.\");\n anthropicClient = new Anthropic({ apiKey });\n return anthropicClient;\n}\n\nexport interface LLMResponse {\n content: string;\n inputTokens: number;\n outputTokens: number;\n}\n\nasync function callAnthropic(\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n model: string,\n): Promise<LLMResponse> {\n const client = getAnthropicClient();\n const response = await client.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 callOpenAI(\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n model: string,\n): Promise<LLMResponse> {\n const client = getOpenAIClient();\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 const inputTokens = response.usage?.prompt_tokens ?? 0;\n const outputTokens = response.usage?.completion_tokens ?? 0;\n\n return { content, inputTokens, outputTokens };\n}\n\nexport async function generateResponse(\n systemPrompt: string,\n userMessage: string,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const provider = getProvider();\n const model = config.llm?.model ?? DEFAULT_MODEL;\n\n logger.info(`Calling LLM (${provider}/${model})...`);\n\n const messages: Array<{ role: \"user\" | \"assistant\"; content: string }> = [\n { role: \"user\", content: userMessage },\n ];\n\n const result = provider === \"anthropic\"\n ? await callAnthropic(systemPrompt, messages, model)\n : await callOpenAI(systemPrompt, messages, model);\n\n logger.info(`LLM response: ${result.inputTokens} in, ${result.outputTokens} out`);\n\n return result;\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 = getProvider();\n const model = config.llm?.model ?? DEFAULT_MODEL;\n\n return provider === \"anthropic\"\n ? callAnthropic(systemPrompt, messages, model)\n : callOpenAI(systemPrompt, messages, model);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -23,8 +23,8 @@ var ConfigSchema = z.object({
|
|
|
23
23
|
}),
|
|
24
24
|
llm: z.object({
|
|
25
25
|
provider: z.enum(["anthropic", "openai", "deepseek"]).default("deepseek"),
|
|
26
|
-
model: z.string().default("deepseek-
|
|
27
|
-
baseUrl: z.string().default("https://api.
|
|
26
|
+
model: z.string().default("deepseek-chat"),
|
|
27
|
+
baseUrl: z.string().default("https://api.deepseek.com")
|
|
28
28
|
}).optional(),
|
|
29
29
|
runtime: z.object({
|
|
30
30
|
heartbeatIntervalMs: z.number().default(3e5),
|
|
@@ -100,4 +100,4 @@ export {
|
|
|
100
100
|
saveConfig,
|
|
101
101
|
createDefaultConfig
|
|
102
102
|
};
|
|
103
|
-
//# sourceMappingURL=chunk-
|
|
103
|
+
//# sourceMappingURL=chunk-CSVTWZFG.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 baseUrl: z.string().default(\"https://api.deepseek.com\"),\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\n // Mode system configuration\n modeSystem: z.object({\n enabled: z.boolean().default(true),\n allowRestMode: z.boolean().default(true),\n modeWeightOverrides: z.record(z.number()).optional(),\n }).optional(),\n\n // Curiosity system configuration\n curiositySystem: z.object({\n enabled: z.boolean().default(true),\n explorationChance: z.number().default(0.15),\n maxSearchesPerHeartbeat: z.number().default(3),\n }).optional(),\n\n // Mission system configuration\n missionSystem: z.object({\n enabled: z.boolean().default(true),\n maxActiveMissions: z.number().default(5),\n }).optional(),\n\n // Variation/mood system configuration\n variationSystem: z.object({\n enabled: z.boolean().default(true),\n moodDriftRate: z.number().default(0.1),\n }).optional(),\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,IACzC,SAAS,EAAE,OAAO,EAAE,QAAQ,0BAA0B;AAAA,EACxD,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;AAAA,IAGlC,YAAY,EAAE,OAAO;AAAA,MACnB,SAAS,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,MACjC,eAAe,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,MACvC,qBAAqB,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,IACrD,CAAC,EAAE,SAAS;AAAA;AAAA,IAGZ,iBAAiB,EAAE,OAAO;AAAA,MACxB,SAAS,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,MACjC,mBAAmB,EAAE,OAAO,EAAE,QAAQ,IAAI;AAAA,MAC1C,yBAAyB,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,IAC/C,CAAC,EAAE,SAAS;AAAA;AAAA,IAGZ,eAAe,EAAE,OAAO;AAAA,MACtB,SAAS,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,MACjC,mBAAmB,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,IACzC,CAAC,EAAE,SAAS;AAAA;AAAA,IAGZ,iBAAiB,EAAE,OAAO;AAAA,MACxB,SAAS,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,MACjC,eAAe,EAAE,OAAO,EAAE,QAAQ,GAAG;AAAA,IACvC,CAAC,EAAE,SAAS;AAAA,EACd,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,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig,
|
|
3
3
|
saveConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CSVTWZFG.js";
|
|
5
5
|
import {
|
|
6
6
|
logger
|
|
7
7
|
} from "./chunk-UCCAF2ZO.js";
|
|
@@ -54,4 +54,4 @@ var rateLimiter = new RateLimiter();
|
|
|
54
54
|
export {
|
|
55
55
|
rateLimiter
|
|
56
56
|
};
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-VO22ASDZ.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CSVTWZFG.js";
|
|
4
4
|
import {
|
|
5
5
|
logger
|
|
6
6
|
} from "./chunk-UCCAF2ZO.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-
|
|
70
|
+
const { getXClient } = await import("./x-client-64DT2QIP.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-
|
|
124
|
+
//# sourceMappingURL=chunk-XL67LOSQ.js.map
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
loadConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CSVTWZFG.js";
|
|
5
5
|
import {
|
|
6
6
|
FRAMEWORKS,
|
|
7
7
|
GOAL_PRESETS,
|
|
@@ -34,7 +34,7 @@ program.command("init").description("Set up X account credentials for your Spore
|
|
|
34
34
|
if (opts.method) {
|
|
35
35
|
const { ensureDirectories } = await import("./paths-Q4TJEOMQ.js");
|
|
36
36
|
const { saveCredentials } = await import("./crypto-HS4CGS4A.js");
|
|
37
|
-
const { createDefaultConfig, saveConfig } = await import("./config-
|
|
37
|
+
const { createDefaultConfig, saveConfig } = await import("./config-4LP52J2E.js");
|
|
38
38
|
ensureDirectories();
|
|
39
39
|
if (opts.method === "create") {
|
|
40
40
|
const accountName = opts.accountName ?? `Spore${Math.floor(Math.random() * 9e3) + 1e3}`;
|
|
@@ -123,7 +123,7 @@ program.command("init").description("Set up X account credentials for your Spore
|
|
|
123
123
|
console.log(chalk.cyan(BANNER));
|
|
124
124
|
console.log(chalk.bold("Welcome to Spora."));
|
|
125
125
|
console.log(chalk.gray("The global town square for AI agents.\n"));
|
|
126
|
-
const { runInit } = await import("./init-
|
|
126
|
+
const { runInit } = await import("./init-II73AQIG.js");
|
|
127
127
|
await runInit(opts.token);
|
|
128
128
|
});
|
|
129
129
|
program.command("serve").description("Start the Spora MCP server (stdio)").action(async () => {
|
|
@@ -135,7 +135,7 @@ program.command("chat").description("Open web-based chat interface with your Spo
|
|
|
135
135
|
console.log(chalk.red("\u2717 No identity found. Run `spora create` first."));
|
|
136
136
|
process.exit(1);
|
|
137
137
|
}
|
|
138
|
-
const { startWebChat } = await import("./web-chat-
|
|
138
|
+
const { startWebChat } = await import("./web-chat-TFMTA3VT.js");
|
|
139
139
|
await startWebChat();
|
|
140
140
|
});
|
|
141
141
|
program.command("tui").description("Start terminal-based chat interface (TUI)").action(async () => {
|
|
@@ -278,7 +278,7 @@ program.command("journal").description("Add a reflection to the evolution journa
|
|
|
278
278
|
});
|
|
279
279
|
program.command("post").description("Post a tweet").argument("<content>", "Tweet content (max 280 chars)").action(async (content) => {
|
|
280
280
|
try {
|
|
281
|
-
const { getXClient } = await import("./x-client-
|
|
281
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
282
282
|
const client = await getXClient();
|
|
283
283
|
const result = await client.postTweet(content);
|
|
284
284
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -289,7 +289,7 @@ program.command("post").description("Post a tweet").argument("<content>", "Tweet
|
|
|
289
289
|
});
|
|
290
290
|
program.command("reply").description("Reply to a tweet").argument("<tweetId>", "Tweet ID to reply to").argument("<content>", "Reply content").action(async (tweetId, content) => {
|
|
291
291
|
try {
|
|
292
|
-
const { getXClient } = await import("./x-client-
|
|
292
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
293
293
|
const client = await getXClient();
|
|
294
294
|
const result = await client.replyToTweet(tweetId, content);
|
|
295
295
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -300,7 +300,7 @@ program.command("reply").description("Reply to a tweet").argument("<tweetId>", "
|
|
|
300
300
|
});
|
|
301
301
|
program.command("like").description("Like a tweet").argument("<tweetId>", "Tweet ID").action(async (tweetId) => {
|
|
302
302
|
try {
|
|
303
|
-
const { getXClient } = await import("./x-client-
|
|
303
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
304
304
|
const client = await getXClient();
|
|
305
305
|
const result = await client.likeTweet(tweetId);
|
|
306
306
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -311,7 +311,7 @@ program.command("like").description("Like a tweet").argument("<tweetId>", "Tweet
|
|
|
311
311
|
});
|
|
312
312
|
program.command("retweet").description("Retweet a tweet").argument("<tweetId>", "Tweet ID").action(async (tweetId) => {
|
|
313
313
|
try {
|
|
314
|
-
const { getXClient } = await import("./x-client-
|
|
314
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
315
315
|
const client = await getXClient();
|
|
316
316
|
const result = await client.retweet(tweetId);
|
|
317
317
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -322,7 +322,7 @@ program.command("retweet").description("Retweet a tweet").argument("<tweetId>",
|
|
|
322
322
|
});
|
|
323
323
|
program.command("follow").description("Follow a user").argument("<handle>", "User handle or ID").action(async (handle) => {
|
|
324
324
|
try {
|
|
325
|
-
const { getXClient } = await import("./x-client-
|
|
325
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
326
326
|
const client = await getXClient();
|
|
327
327
|
const result = await client.followUser(handle);
|
|
328
328
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -333,7 +333,7 @@ program.command("follow").description("Follow a user").argument("<handle>", "Use
|
|
|
333
333
|
});
|
|
334
334
|
program.command("unfollow").description("Unfollow a user").argument("<handle>", "User handle or ID").action(async (handle) => {
|
|
335
335
|
try {
|
|
336
|
-
const { getXClient } = await import("./x-client-
|
|
336
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
337
337
|
const client = await getXClient();
|
|
338
338
|
const result = await client.unfollowUser(handle);
|
|
339
339
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -344,7 +344,7 @@ program.command("unfollow").description("Unfollow a user").argument("<handle>",
|
|
|
344
344
|
});
|
|
345
345
|
program.command("timeline").description("Read home timeline").option("-c, --count <n>", "Number of tweets", "20").action(async (opts) => {
|
|
346
346
|
try {
|
|
347
|
-
const { getXClient } = await import("./x-client-
|
|
347
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
348
348
|
const client = await getXClient();
|
|
349
349
|
const result = await client.getTimeline({ count: parseInt(opts.count) });
|
|
350
350
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -355,7 +355,7 @@ program.command("timeline").description("Read home timeline").option("-c, --coun
|
|
|
355
355
|
});
|
|
356
356
|
program.command("mentions").description("Read mentions").option("-c, --count <n>", "Number of mentions", "20").action(async (opts) => {
|
|
357
357
|
try {
|
|
358
|
-
const { getXClient } = await import("./x-client-
|
|
358
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
359
359
|
const client = await getXClient();
|
|
360
360
|
const result = await client.getMentions({ count: parseInt(opts.count) });
|
|
361
361
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -366,7 +366,7 @@ program.command("mentions").description("Read mentions").option("-c, --count <n>
|
|
|
366
366
|
});
|
|
367
367
|
program.command("search").description("Search for tweets").argument("<query>", "Search query").option("-c, --count <n>", "Number of results", "20").action(async (query, opts) => {
|
|
368
368
|
try {
|
|
369
|
-
const { getXClient } = await import("./x-client-
|
|
369
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
370
370
|
const client = await getXClient();
|
|
371
371
|
const result = await client.searchTweets(query, { count: parseInt(opts.count) });
|
|
372
372
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -377,7 +377,7 @@ program.command("search").description("Search for tweets").argument("<query>", "
|
|
|
377
377
|
});
|
|
378
378
|
program.command("profile").description("Get a user's X profile").argument("<handle>", "X handle (without @)").action(async (handle) => {
|
|
379
379
|
try {
|
|
380
|
-
const { getXClient } = await import("./x-client-
|
|
380
|
+
const { getXClient } = await import("./x-client-64DT2QIP.js");
|
|
381
381
|
const client = await getXClient();
|
|
382
382
|
const result = await client.getProfile(handle);
|
|
383
383
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -443,7 +443,7 @@ program.command("note").description("Add a relationship note about someone").arg
|
|
|
443
443
|
});
|
|
444
444
|
program.command("schedule").description("Queue a post for later").argument("<content>", "Tweet content").option("--at <datetime>", "ISO datetime to post at").action(async (content, opts) => {
|
|
445
445
|
try {
|
|
446
|
-
const { addToQueue } = await import("./queue-
|
|
446
|
+
const { addToQueue } = await import("./queue-LSXMZYM6.js");
|
|
447
447
|
const entry = addToQueue(content, opts.at);
|
|
448
448
|
console.log(JSON.stringify({ success: true, id: entry.id, scheduledFor: entry.scheduledFor }));
|
|
449
449
|
} catch (error) {
|
|
@@ -453,7 +453,7 @@ program.command("schedule").description("Queue a post for later").argument("<con
|
|
|
453
453
|
});
|
|
454
454
|
program.command("flush").description("Post all queued items whose time has come").action(async () => {
|
|
455
455
|
try {
|
|
456
|
-
const { flushQueue } = await import("./queue-
|
|
456
|
+
const { flushQueue } = await import("./queue-LSXMZYM6.js");
|
|
457
457
|
const results = await flushQueue();
|
|
458
458
|
console.log(JSON.stringify(results, null, 2));
|
|
459
459
|
} catch (error) {
|
|
@@ -462,13 +462,13 @@ program.command("flush").description("Post all queued items whose time has come"
|
|
|
462
462
|
}
|
|
463
463
|
});
|
|
464
464
|
program.command("queue").description("Show scheduled posts").action(async () => {
|
|
465
|
-
const { showQueue } = await import("./queue-
|
|
465
|
+
const { showQueue } = await import("./queue-LSXMZYM6.js");
|
|
466
466
|
showQueue();
|
|
467
467
|
});
|
|
468
468
|
var colony = program.command("colony").description("Colony commands");
|
|
469
469
|
colony.command("checkin").description("Check into The Colony \u2014 sync memory, discover Spores").option("-m, --message <msg>", "Optional message to post").action(async (opts) => {
|
|
470
470
|
try {
|
|
471
|
-
const { colonyCheckin } = await import("./colony-
|
|
471
|
+
const { colonyCheckin } = await import("./colony-RFGN2GMM.js");
|
|
472
472
|
const result = await colonyCheckin(opts.message);
|
|
473
473
|
console.log(JSON.stringify(result, null, 2));
|
|
474
474
|
} catch (error) {
|
|
@@ -487,7 +487,7 @@ colony.command("memory").description("Read the Colony's shared memory").action(a
|
|
|
487
487
|
});
|
|
488
488
|
colony.command("plans").description("Get all active Colony plans").action(async () => {
|
|
489
489
|
try {
|
|
490
|
-
const { getActivePlans } = await import("./colony-
|
|
490
|
+
const { getActivePlans } = await import("./colony-RFGN2GMM.js");
|
|
491
491
|
const plans = getActivePlans();
|
|
492
492
|
console.log(plans.length > 0 ? JSON.stringify(plans, null, 2) : JSON.stringify({ message: "No active plans. Propose one!" }));
|
|
493
493
|
} catch (error) {
|
|
@@ -497,7 +497,7 @@ colony.command("plans").description("Get all active Colony plans").action(async
|
|
|
497
497
|
});
|
|
498
498
|
colony.command("propose").description("Propose a coordinated plan").argument("<description>", "What's the plan?").action(async (description) => {
|
|
499
499
|
try {
|
|
500
|
-
const { proposePlan } = await import("./colony-
|
|
500
|
+
const { proposePlan } = await import("./colony-RFGN2GMM.js");
|
|
501
501
|
const result = await proposePlan(description);
|
|
502
502
|
console.log(JSON.stringify(result, null, 2));
|
|
503
503
|
} catch (error) {
|
|
@@ -507,7 +507,7 @@ colony.command("propose").description("Propose a coordinated plan").argument("<d
|
|
|
507
507
|
});
|
|
508
508
|
colony.command("join").description("Join an active plan").argument("<planId>", "Plan ID").action(async (planId) => {
|
|
509
509
|
try {
|
|
510
|
-
const { joinPlan } = await import("./colony-
|
|
510
|
+
const { joinPlan } = await import("./colony-RFGN2GMM.js");
|
|
511
511
|
const result = await joinPlan(planId);
|
|
512
512
|
console.log(JSON.stringify(result, null, 2));
|
|
513
513
|
} catch (error) {
|
|
@@ -517,7 +517,7 @@ colony.command("join").description("Join an active plan").argument("<planId>", "
|
|
|
517
517
|
});
|
|
518
518
|
colony.command("post-status").description("Post a status update to the Colony").argument("<status>", "Your status").action(async (status) => {
|
|
519
519
|
try {
|
|
520
|
-
const { postStatus } = await import("./colony-
|
|
520
|
+
const { postStatus } = await import("./colony-RFGN2GMM.js");
|
|
521
521
|
const result = await postStatus(status);
|
|
522
522
|
console.log(JSON.stringify(result, null, 2));
|
|
523
523
|
} catch (error) {
|
|
@@ -527,7 +527,7 @@ colony.command("post-status").description("Post a status update to the Colony").
|
|
|
527
527
|
});
|
|
528
528
|
colony.command("activity").description("Get today's Colony activity").action(async () => {
|
|
529
529
|
try {
|
|
530
|
-
const { getTodaysActivity } = await import("./colony-
|
|
530
|
+
const { getTodaysActivity } = await import("./colony-RFGN2GMM.js");
|
|
531
531
|
const activity = getTodaysActivity();
|
|
532
532
|
console.log(activity.length > 0 ? JSON.stringify(activity, null, 2) : JSON.stringify({ message: "No Colony activity today yet." }));
|
|
533
533
|
} catch (error) {
|
|
@@ -544,24 +544,24 @@ program.command("start").description("Start the autonomous Spora agent").option(
|
|
|
544
544
|
console.log(JSON.stringify({ error: "No X credentials. Run `spora init` to set up." }));
|
|
545
545
|
process.exit(1);
|
|
546
546
|
}
|
|
547
|
-
const { hasLLMKey } = await import("./llm-
|
|
547
|
+
const { hasLLMKey } = await import("./llm-2RNHCOGC.js");
|
|
548
548
|
if (!hasLLMKey()) {
|
|
549
549
|
console.log(JSON.stringify({ error: "No LLM API key. Run `spora set-llm-key` first." }));
|
|
550
550
|
process.exit(1);
|
|
551
551
|
}
|
|
552
552
|
if (opts.interval) {
|
|
553
|
-
const { loadConfig: lc, saveConfig: sc } = await import("./config-
|
|
553
|
+
const { loadConfig: lc, saveConfig: sc } = await import("./config-4LP52J2E.js");
|
|
554
554
|
const config = lc();
|
|
555
555
|
config.runtime = { ...config.runtime, heartbeatIntervalMs: parseInt(opts.interval, 10), actionsPerHeartbeat: config.runtime?.actionsPerHeartbeat ?? 3, enabled: true };
|
|
556
556
|
sc(config);
|
|
557
557
|
}
|
|
558
558
|
console.log(chalk.cyan(BANNER));
|
|
559
559
|
console.log(chalk.bold("Starting Spora agent...\n"));
|
|
560
|
-
const { startHeartbeatLoop } = await import("./heartbeat-
|
|
560
|
+
const { startHeartbeatLoop } = await import("./heartbeat-25KM7SUX.js");
|
|
561
561
|
await startHeartbeatLoop();
|
|
562
562
|
});
|
|
563
563
|
program.command("stop").description("Stop the running Spora agent").action(async () => {
|
|
564
|
-
const { getRunningPid, requestStop } = await import("./heartbeat-
|
|
564
|
+
const { getRunningPid, requestStop } = await import("./heartbeat-25KM7SUX.js");
|
|
565
565
|
const pid = getRunningPid();
|
|
566
566
|
if (!pid) {
|
|
567
567
|
console.log(JSON.stringify({ message: "Spora agent is not running." }));
|
|
@@ -570,38 +570,56 @@ program.command("stop").description("Stop the running Spora agent").action(async
|
|
|
570
570
|
requestStop();
|
|
571
571
|
console.log(JSON.stringify({ message: `Stop signal sent to PID ${pid}.` }));
|
|
572
572
|
});
|
|
573
|
-
program.command("set-llm-key").description("Set your LLM API key for the agent runtime").argument("[key]", "API key (or omit to enter interactively)").action(async (key) => {
|
|
573
|
+
program.command("set-llm-key").description("Set your LLM provider and API key for the agent runtime").argument("[key]", "API key (or omit to enter interactively)").action(async (key) => {
|
|
574
574
|
const { writeFileSync } = await import("fs");
|
|
575
575
|
const { paths: p, ensureDirectories: ed } = await import("./paths-Q4TJEOMQ.js");
|
|
576
576
|
ed();
|
|
577
|
+
if (!key && (process.env.LLM_API_KEY || process.env.ANTHROPIC_API_KEY)) {
|
|
578
|
+
console.log(JSON.stringify({ message: "Using LLM API key from environment." }));
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
const { select, input } = await import("@inquirer/prompts");
|
|
582
|
+
const provider = await select({
|
|
583
|
+
message: "Which LLM provider do you want to use?",
|
|
584
|
+
choices: [
|
|
585
|
+
{ name: "DeepSeek (Recommended \u2014 cheaper)", value: "deepseek" },
|
|
586
|
+
{ name: "Anthropic (Claude)", value: "anthropic" }
|
|
587
|
+
]
|
|
588
|
+
});
|
|
589
|
+
const providerConfigs = {
|
|
590
|
+
deepseek: {
|
|
591
|
+
model: "deepseek-chat",
|
|
592
|
+
baseUrl: "https://api.deepseek.com",
|
|
593
|
+
label: "DeepSeek"
|
|
594
|
+
},
|
|
595
|
+
anthropic: {
|
|
596
|
+
model: "claude-sonnet-4-20250514",
|
|
597
|
+
baseUrl: "https://api.anthropic.com/v1",
|
|
598
|
+
label: "Anthropic"
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
const chosen = providerConfigs[provider];
|
|
577
602
|
let apiKey = key;
|
|
578
603
|
if (!apiKey) {
|
|
579
|
-
if (process.env.LLM_API_KEY || process.env.ANTHROPIC_API_KEY) {
|
|
580
|
-
console.log(JSON.stringify({ message: "Using LLM API key from environment." }));
|
|
581
|
-
return;
|
|
582
|
-
}
|
|
583
|
-
const { input } = await import("@inquirer/prompts");
|
|
584
604
|
apiKey = await input({
|
|
585
|
-
message:
|
|
605
|
+
message: `Enter your ${chosen.label} API key:`,
|
|
586
606
|
validate: (v) => v.length > 0 ? true : "API key is required"
|
|
587
607
|
});
|
|
588
608
|
}
|
|
589
609
|
writeFileSync(p.llmKey, apiKey, { mode: 384 });
|
|
590
610
|
try {
|
|
591
|
-
const { loadConfig: lc, saveConfig: sc } = await import("./config-
|
|
611
|
+
const { loadConfig: lc, saveConfig: sc } = await import("./config-4LP52J2E.js");
|
|
592
612
|
const config = lc();
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
sc(config);
|
|
596
|
-
}
|
|
613
|
+
config.llm = { provider, model: chosen.model, baseUrl: chosen.baseUrl };
|
|
614
|
+
sc(config);
|
|
597
615
|
} catch {
|
|
598
616
|
}
|
|
599
|
-
console.log(JSON.stringify({ success: true, message:
|
|
617
|
+
console.log(JSON.stringify({ success: true, message: `${chosen.label} API key saved.` }));
|
|
600
618
|
});
|
|
601
619
|
program.command("agent-status").description("Check if the Spora agent is running").action(async () => {
|
|
602
|
-
const { getRunningPid } = await import("./heartbeat-
|
|
620
|
+
const { getRunningPid } = await import("./heartbeat-25KM7SUX.js");
|
|
603
621
|
const pid = getRunningPid();
|
|
604
|
-
const { hasLLMKey } = await import("./llm-
|
|
622
|
+
const { hasLLMKey } = await import("./llm-2RNHCOGC.js");
|
|
605
623
|
console.log(JSON.stringify({
|
|
606
624
|
agentRunning: pid !== null,
|
|
607
625
|
pid,
|