electric-ax 0.1.13 → 0.1.14
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/index.cjs +90 -1
- package/dist/index.js +91 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8,7 +8,95 @@ const node_os = require_chunk.__toESM(require("node:os"));
|
|
|
8
8
|
const node_path = require_chunk.__toESM(require("node:path"));
|
|
9
9
|
const node_url = require_chunk.__toESM(require("node:url"));
|
|
10
10
|
const commander = require_chunk.__toESM(require("commander"));
|
|
11
|
+
const node_readline_promises = require_chunk.__toESM(require("node:readline/promises"));
|
|
11
12
|
|
|
13
|
+
//#region src/prompt-api-key.ts
|
|
14
|
+
const FRIENDLY_INTRO = [
|
|
15
|
+
``,
|
|
16
|
+
`The Electric Agents quickstart requires setting an API key to connect to an LLM provider.`,
|
|
17
|
+
``,
|
|
18
|
+
`Currently (in this initial developer preview release) the key must be an ANTHROPIC_API_KEY.`,
|
|
19
|
+
`Support for other LLM providers is coming very soon.`,
|
|
20
|
+
``,
|
|
21
|
+
`Note that your API key never leaves your local computer. It's used by the agent entities`,
|
|
22
|
+
`installed by default in the Electric Agents runtime and by the example agents included`,
|
|
23
|
+
`in the quickstart template.`,
|
|
24
|
+
``,
|
|
25
|
+
`Would you like to:`,
|
|
26
|
+
``,
|
|
27
|
+
` 1. manually setup a .env file with ANTHROPIC_API_KEY=...`,
|
|
28
|
+
` 2. paste your api key into a prompt and we'll set it up for you`,
|
|
29
|
+
``
|
|
30
|
+
].join(`\n`);
|
|
31
|
+
const MANUAL_SETUP_INSTRUCTIONS = [
|
|
32
|
+
``,
|
|
33
|
+
`No problem. To finish setup:`,
|
|
34
|
+
``,
|
|
35
|
+
` 1. Get a key from https://console.anthropic.com/settings/keys`,
|
|
36
|
+
` 2. Add a line to your .env file:`,
|
|
37
|
+
` ANTHROPIC_API_KEY=sk-ant-...`,
|
|
38
|
+
` 3. Re-run the command.`,
|
|
39
|
+
``
|
|
40
|
+
].join(`\n`);
|
|
41
|
+
function defaultPromptIO() {
|
|
42
|
+
return {
|
|
43
|
+
input: process.stdin,
|
|
44
|
+
output: process.stdout,
|
|
45
|
+
isTTY: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
46
|
+
cwd: process.cwd(),
|
|
47
|
+
exit: process.exit.bind(process)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async function ensureAnthropicApiKey(options, io = defaultPromptIO()) {
|
|
51
|
+
try {
|
|
52
|
+
return require_env.resolveAnthropicApiKey(options);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
if (!io.isTTY) throw error;
|
|
55
|
+
}
|
|
56
|
+
io.output.write(FRIENDLY_INTRO);
|
|
57
|
+
const rl = (0, node_readline_promises.createInterface)({
|
|
58
|
+
input: io.input,
|
|
59
|
+
output: io.output
|
|
60
|
+
});
|
|
61
|
+
try {
|
|
62
|
+
const choice = (await rl.question(`Enter 1/2: `)).trim();
|
|
63
|
+
if (choice === `1`) {
|
|
64
|
+
io.output.write(MANUAL_SETUP_INSTRUCTIONS);
|
|
65
|
+
io.exit(0);
|
|
66
|
+
throw new Error(`unreachable`);
|
|
67
|
+
}
|
|
68
|
+
if (choice === `2`) {
|
|
69
|
+
const key = (await rl.question(`Paste your ANTHROPIC_API_KEY: `)).trim();
|
|
70
|
+
if (!key) throw new Error(`No API key provided. Re-run the command and try again.`);
|
|
71
|
+
const envPath = writeApiKeyToDotEnv(key, io.cwd);
|
|
72
|
+
process.env.ANTHROPIC_API_KEY = key;
|
|
73
|
+
io.output.write(`\nSaved ANTHROPIC_API_KEY to ${envPath}\n\n`);
|
|
74
|
+
return key;
|
|
75
|
+
}
|
|
76
|
+
throw new Error(`Unrecognized choice ${JSON.stringify(choice)}. Please re-run the command and enter 1 or 2.`);
|
|
77
|
+
} finally {
|
|
78
|
+
rl.close();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function writeApiKeyToDotEnv(key, cwd) {
|
|
82
|
+
const envPath = (0, node_path.resolve)(cwd, `.env`);
|
|
83
|
+
const newLine = `ANTHROPIC_API_KEY=${key}`;
|
|
84
|
+
if (!(0, node_fs.existsSync)(envPath)) {
|
|
85
|
+
(0, node_fs.writeFileSync)(envPath, `${newLine}\n`, `utf8`);
|
|
86
|
+
return envPath;
|
|
87
|
+
}
|
|
88
|
+
const existing = (0, node_fs.readFileSync)(envPath, `utf8`);
|
|
89
|
+
const replaced = existing.replace(/^ANTHROPIC_API_KEY=.*$/m, newLine);
|
|
90
|
+
if (replaced !== existing) {
|
|
91
|
+
(0, node_fs.writeFileSync)(envPath, replaced, `utf8`);
|
|
92
|
+
return envPath;
|
|
93
|
+
}
|
|
94
|
+
const separator = existing.length === 0 || existing.endsWith(`\n`) ? `` : `\n`;
|
|
95
|
+
(0, node_fs.writeFileSync)(envPath, `${existing}${separator}${newLine}\n`, `utf8`);
|
|
96
|
+
return envPath;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
//#endregion
|
|
12
100
|
//#region src/index.ts
|
|
13
101
|
const DEFAULT_ELECTRIC_AGENTS_URL = `http://localhost:4437`;
|
|
14
102
|
var CliError = class extends Error {};
|
|
@@ -257,6 +345,7 @@ function createElectricCliHandlers(env, commandPrefix = commandExample(`electric
|
|
|
257
345
|
return started;
|
|
258
346
|
},
|
|
259
347
|
startBuiltin: async (options) => {
|
|
348
|
+
options.anthropicApiKey = await ensureAnthropicApiKey(options);
|
|
260
349
|
const { startBuiltinAgentsServer } = await loadStartModule();
|
|
261
350
|
return startBuiltinAgentsServer(options, { agentServerUrl: env.electricAgentsUrl });
|
|
262
351
|
},
|
|
@@ -267,7 +356,7 @@ function createElectricCliHandlers(env, commandPrefix = commandExample(`electric
|
|
|
267
356
|
return stopped;
|
|
268
357
|
},
|
|
269
358
|
quickstart: async (options) => {
|
|
270
|
-
|
|
359
|
+
options.anthropicApiKey = await ensureAnthropicApiKey(options);
|
|
271
360
|
const { startBuiltinAgentsServer, startElectricAgentsDevEnvironment } = await loadStartModule();
|
|
272
361
|
const started = await startElectricAgentsDevEnvironment();
|
|
273
362
|
printStartedEnvironment(started);
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,100 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { installCompletions, setupCompletions } from "./completions-B-Lf28Wy.js";
|
|
3
3
|
import { resolveAnthropicApiKey$1 as resolveAnthropicApiKey } from "./env-LZtIfFz1.js";
|
|
4
|
-
import { realpathSync } from "node:fs";
|
|
4
|
+
import { existsSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { hostname, userInfo } from "node:os";
|
|
6
6
|
import { basename, resolve } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { Command } from "commander";
|
|
9
|
+
import { createInterface } from "node:readline/promises";
|
|
9
10
|
|
|
11
|
+
//#region src/prompt-api-key.ts
|
|
12
|
+
const FRIENDLY_INTRO = [
|
|
13
|
+
``,
|
|
14
|
+
`The Electric Agents quickstart requires setting an API key to connect to an LLM provider.`,
|
|
15
|
+
``,
|
|
16
|
+
`Currently (in this initial developer preview release) the key must be an ANTHROPIC_API_KEY.`,
|
|
17
|
+
`Support for other LLM providers is coming very soon.`,
|
|
18
|
+
``,
|
|
19
|
+
`Note that your API key never leaves your local computer. It's used by the agent entities`,
|
|
20
|
+
`installed by default in the Electric Agents runtime and by the example agents included`,
|
|
21
|
+
`in the quickstart template.`,
|
|
22
|
+
``,
|
|
23
|
+
`Would you like to:`,
|
|
24
|
+
``,
|
|
25
|
+
` 1. manually setup a .env file with ANTHROPIC_API_KEY=...`,
|
|
26
|
+
` 2. paste your api key into a prompt and we'll set it up for you`,
|
|
27
|
+
``
|
|
28
|
+
].join(`\n`);
|
|
29
|
+
const MANUAL_SETUP_INSTRUCTIONS = [
|
|
30
|
+
``,
|
|
31
|
+
`No problem. To finish setup:`,
|
|
32
|
+
``,
|
|
33
|
+
` 1. Get a key from https://console.anthropic.com/settings/keys`,
|
|
34
|
+
` 2. Add a line to your .env file:`,
|
|
35
|
+
` ANTHROPIC_API_KEY=sk-ant-...`,
|
|
36
|
+
` 3. Re-run the command.`,
|
|
37
|
+
``
|
|
38
|
+
].join(`\n`);
|
|
39
|
+
function defaultPromptIO() {
|
|
40
|
+
return {
|
|
41
|
+
input: process.stdin,
|
|
42
|
+
output: process.stdout,
|
|
43
|
+
isTTY: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
44
|
+
cwd: process.cwd(),
|
|
45
|
+
exit: process.exit.bind(process)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function ensureAnthropicApiKey(options, io = defaultPromptIO()) {
|
|
49
|
+
try {
|
|
50
|
+
return resolveAnthropicApiKey(options);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (!io.isTTY) throw error;
|
|
53
|
+
}
|
|
54
|
+
io.output.write(FRIENDLY_INTRO);
|
|
55
|
+
const rl = createInterface({
|
|
56
|
+
input: io.input,
|
|
57
|
+
output: io.output
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
const choice = (await rl.question(`Enter 1/2: `)).trim();
|
|
61
|
+
if (choice === `1`) {
|
|
62
|
+
io.output.write(MANUAL_SETUP_INSTRUCTIONS);
|
|
63
|
+
io.exit(0);
|
|
64
|
+
throw new Error(`unreachable`);
|
|
65
|
+
}
|
|
66
|
+
if (choice === `2`) {
|
|
67
|
+
const key = (await rl.question(`Paste your ANTHROPIC_API_KEY: `)).trim();
|
|
68
|
+
if (!key) throw new Error(`No API key provided. Re-run the command and try again.`);
|
|
69
|
+
const envPath = writeApiKeyToDotEnv(key, io.cwd);
|
|
70
|
+
process.env.ANTHROPIC_API_KEY = key;
|
|
71
|
+
io.output.write(`\nSaved ANTHROPIC_API_KEY to ${envPath}\n\n`);
|
|
72
|
+
return key;
|
|
73
|
+
}
|
|
74
|
+
throw new Error(`Unrecognized choice ${JSON.stringify(choice)}. Please re-run the command and enter 1 or 2.`);
|
|
75
|
+
} finally {
|
|
76
|
+
rl.close();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function writeApiKeyToDotEnv(key, cwd) {
|
|
80
|
+
const envPath = resolve(cwd, `.env`);
|
|
81
|
+
const newLine = `ANTHROPIC_API_KEY=${key}`;
|
|
82
|
+
if (!existsSync(envPath)) {
|
|
83
|
+
writeFileSync(envPath, `${newLine}\n`, `utf8`);
|
|
84
|
+
return envPath;
|
|
85
|
+
}
|
|
86
|
+
const existing = readFileSync(envPath, `utf8`);
|
|
87
|
+
const replaced = existing.replace(/^ANTHROPIC_API_KEY=.*$/m, newLine);
|
|
88
|
+
if (replaced !== existing) {
|
|
89
|
+
writeFileSync(envPath, replaced, `utf8`);
|
|
90
|
+
return envPath;
|
|
91
|
+
}
|
|
92
|
+
const separator = existing.length === 0 || existing.endsWith(`\n`) ? `` : `\n`;
|
|
93
|
+
writeFileSync(envPath, `${existing}${separator}${newLine}\n`, `utf8`);
|
|
94
|
+
return envPath;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//#endregion
|
|
10
98
|
//#region src/index.ts
|
|
11
99
|
const DEFAULT_ELECTRIC_AGENTS_URL = `http://localhost:4437`;
|
|
12
100
|
var CliError = class extends Error {};
|
|
@@ -255,6 +343,7 @@ function createElectricCliHandlers(env, commandPrefix = commandExample(`electric
|
|
|
255
343
|
return started;
|
|
256
344
|
},
|
|
257
345
|
startBuiltin: async (options) => {
|
|
346
|
+
options.anthropicApiKey = await ensureAnthropicApiKey(options);
|
|
258
347
|
const { startBuiltinAgentsServer } = await loadStartModule();
|
|
259
348
|
return startBuiltinAgentsServer(options, { agentServerUrl: env.electricAgentsUrl });
|
|
260
349
|
},
|
|
@@ -265,7 +354,7 @@ function createElectricCliHandlers(env, commandPrefix = commandExample(`electric
|
|
|
265
354
|
return stopped;
|
|
266
355
|
},
|
|
267
356
|
quickstart: async (options) => {
|
|
268
|
-
|
|
357
|
+
options.anthropicApiKey = await ensureAnthropicApiKey(options);
|
|
269
358
|
const { startBuiltinAgentsServer, startElectricAgentsDevEnvironment } = await loadStartModule();
|
|
270
359
|
const started = await startElectricAgentsDevEnvironment();
|
|
271
360
|
printStartedEnvironment(started);
|