balchemy 0.1.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.
- package/README.md +59 -0
- package/assets/bcrow.png +0 -0
- package/dist/agent-store.d.ts +40 -0
- package/dist/agent-store.d.ts.map +1 -0
- package/dist/agent-store.js +206 -0
- package/dist/agent-store.js.map +1 -0
- package/dist/config-loader.d.ts +8 -0
- package/dist/config-loader.d.ts.map +1 -0
- package/dist/config-loader.js +106 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/docker-gen.d.ts +6 -0
- package/dist/docker-gen.d.ts.map +1 -0
- package/dist/docker-gen.js +40 -0
- package/dist/docker-gen.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +143 -0
- package/dist/index.js.map +1 -0
- package/dist/openai-oauth.d.ts +28 -0
- package/dist/openai-oauth.d.ts.map +1 -0
- package/dist/openai-oauth.js +215 -0
- package/dist/openai-oauth.js.map +1 -0
- package/dist/runner.d.ts +6 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +63 -0
- package/dist/runner.js.map +1 -0
- package/dist/terminal-logo.d.ts +15 -0
- package/dist/terminal-logo.d.ts.map +1 -0
- package/dist/terminal-logo.js +121 -0
- package/dist/terminal-logo.js.map +1 -0
- package/dist/tui/AgentBridge.d.ts +35 -0
- package/dist/tui/AgentBridge.d.ts.map +1 -0
- package/dist/tui/AgentBridge.js +235 -0
- package/dist/tui/AgentBridge.js.map +1 -0
- package/dist/tui/App.d.ts +8 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +118 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/ChatAgent.d.ts +41 -0
- package/dist/tui/ChatAgent.d.ts.map +1 -0
- package/dist/tui/ChatAgent.js +312 -0
- package/dist/tui/ChatAgent.js.map +1 -0
- package/dist/tui/ChatPanel.d.ts +10 -0
- package/dist/tui/ChatPanel.d.ts.map +1 -0
- package/dist/tui/ChatPanel.js +43 -0
- package/dist/tui/ChatPanel.js.map +1 -0
- package/dist/tui/StatusPanel.d.ts +8 -0
- package/dist/tui/StatusPanel.d.ts.map +1 -0
- package/dist/tui/StatusPanel.js +25 -0
- package/dist/tui/StatusPanel.js.map +1 -0
- package/dist/tui/start.d.ts +3 -0
- package/dist/tui/start.d.ts.map +1 -0
- package/dist/tui/start.js +14 -0
- package/dist/tui/start.js.map +1 -0
- package/dist/tui/types.d.ts +61 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/tui/types.js +3 -0
- package/dist/tui/types.js.map +1 -0
- package/dist/wizard.d.ts +16 -0
- package/dist/wizard.d.ts.map +1 -0
- package/dist/wizard.js +716 -0
- package/dist/wizard.js.map +1 -0
- package/package.json +57 -0
- package/templates/.env.example +19 -0
- package/templates/Dockerfile +20 -0
- package/templates/agent.config.yaml +71 -0
- package/templates/docker-compose.yml +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# create-balchemy-agent
|
|
2
|
+
|
|
3
|
+
Deploy an autonomous AI trading agent on Solana and Base chains in 5 minutes.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx create-balchemy-agent
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The interactive wizard will:
|
|
12
|
+
|
|
13
|
+
1. Ask you to pick an LLM provider (Anthropic, OpenAI, Gemini, Grok, OpenRouter)
|
|
14
|
+
2. Set up your agent with trading wallets
|
|
15
|
+
3. Configure your trading strategy in natural language
|
|
16
|
+
4. Start an interactive TUI with live chat and status panel
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- **Bring Your Own LLM** — your agent, your model, your strategy
|
|
21
|
+
- **Interactive TUI** — split-panel chat + live status (balance, trades, events)
|
|
22
|
+
- **MCP Tool Calling** — your LLM calls Balchemy tools directly (trade, research, portfolio)
|
|
23
|
+
- **5 LLM Providers** — Anthropic, OpenAI, Gemini, Grok, OpenRouter
|
|
24
|
+
- **Encrypted Credentials** — AES-256-GCM at rest, PBKDF2 key derivation
|
|
25
|
+
- **Resume Anytime** — cached agent config, instant restart
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx create-balchemy-agent # Setup wizard or resume cached agent
|
|
31
|
+
npx create-balchemy-agent init # Force new setup wizard
|
|
32
|
+
npx create-balchemy-agent start # Start from agent.config.yaml
|
|
33
|
+
npx create-balchemy-agent docker # Generate Docker deployment files
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## How It Works
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
You (strategy) --> Your LLM (decisions) --> Balchemy MCP (execution) --> Solana/Base
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Your LLM is the brain. Balchemy provides the infrastructure — wallets, trading, risk checks, and 100+ tools via MCP protocol. You define the strategy in natural language; your LLM decides when and what to trade.
|
|
43
|
+
|
|
44
|
+
## Requirements
|
|
45
|
+
|
|
46
|
+
- Node.js 18+
|
|
47
|
+
- An LLM API key (from any supported provider)
|
|
48
|
+
|
|
49
|
+
## Configuration
|
|
50
|
+
|
|
51
|
+
After setup, `agent.config.yaml` and `.env` are generated in the current directory. Edit them to change settings without re-running the wizard.
|
|
52
|
+
|
|
53
|
+
## Hub Integration
|
|
54
|
+
|
|
55
|
+
When you bind your EVM wallet during setup, the agent appears in your [Balchemy Hub](https://balchemy.ai/hub) dashboard. Use Hub for monitoring, scope management, and key rotation.
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
MIT
|
package/assets/bcrow.png
ADDED
|
Binary file
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persists agent credentials to ~/.balchemy/agents.enc (AES-256-GCM encrypted).
|
|
3
|
+
*
|
|
4
|
+
* Key derivation: PBKDF2 from machine hostname + username + fixed salt,
|
|
5
|
+
* or from BALCHEMY_MASTER_KEY env var if set.
|
|
6
|
+
*
|
|
7
|
+
* Migration: automatically encrypts plaintext agents.json / agent.json on first read.
|
|
8
|
+
*/
|
|
9
|
+
export interface StoredAgent {
|
|
10
|
+
publicId: string;
|
|
11
|
+
mcpEndpoint: string;
|
|
12
|
+
apiKey: string;
|
|
13
|
+
masterKey?: string;
|
|
14
|
+
llmProvider: string;
|
|
15
|
+
llmApiKey: string;
|
|
16
|
+
llmModel?: string;
|
|
17
|
+
llmBaseUrl?: string;
|
|
18
|
+
maxDailyLlmCost?: number;
|
|
19
|
+
strategy: string;
|
|
20
|
+
shadowMode: boolean;
|
|
21
|
+
wallets?: {
|
|
22
|
+
solana?: string;
|
|
23
|
+
base?: string;
|
|
24
|
+
};
|
|
25
|
+
createdAt: string;
|
|
26
|
+
name?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function saveAgent(agent: StoredAgent): void;
|
|
29
|
+
/** Load the active agent, or null if none. */
|
|
30
|
+
export declare function loadAgent(): StoredAgent | null;
|
|
31
|
+
/** List all saved agents. */
|
|
32
|
+
export declare function listAgents(): StoredAgent[];
|
|
33
|
+
/** Clear the active agent (but keep the list). */
|
|
34
|
+
export declare function clearAgent(): void;
|
|
35
|
+
/** Delete a specific agent from the store. */
|
|
36
|
+
export declare function deleteAgent(publicId: string): void;
|
|
37
|
+
/** Set active agent by publicId. */
|
|
38
|
+
export declare function setActiveAgent(publicId: string): boolean;
|
|
39
|
+
export declare function getStorePath(): string;
|
|
40
|
+
//# sourceMappingURL=agent-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-store.d.ts","sourceRoot":"","sources":["../src/agent-store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAuJD,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAUlD;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,IAAI,WAAW,GAAG,IAAI,CAQ9C;AAED,6BAA6B;AAC7B,wBAAgB,UAAU,IAAI,WAAW,EAAE,CAE1C;AAED,kDAAkD;AAClD,wBAAgB,UAAU,IAAI,IAAI,CAIjC;AAED,8CAA8C;AAC9C,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAOlD;AAED,oCAAoC;AACpC,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOxD;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persists agent credentials to ~/.balchemy/agents.enc (AES-256-GCM encrypted).
|
|
3
|
+
*
|
|
4
|
+
* Key derivation: PBKDF2 from machine hostname + username + fixed salt,
|
|
5
|
+
* or from BALCHEMY_MASTER_KEY env var if set.
|
|
6
|
+
*
|
|
7
|
+
* Migration: automatically encrypts plaintext agents.json / agent.json on first read.
|
|
8
|
+
*/
|
|
9
|
+
import * as crypto from "crypto";
|
|
10
|
+
import * as fs from "fs";
|
|
11
|
+
import * as path from "path";
|
|
12
|
+
import * as os from "os";
|
|
13
|
+
const STORE_DIR = path.join(os.homedir(), ".balchemy");
|
|
14
|
+
const ENCRYPTED_STORE_PATH = path.join(STORE_DIR, "agents.enc");
|
|
15
|
+
const LEGACY_STORE_PATH = path.join(STORE_DIR, "agents.json");
|
|
16
|
+
const OLD_STORE_PATH = path.join(STORE_DIR, "agent.json"); // v0.1 single-agent format
|
|
17
|
+
const ALGORITHM = "aes-256-gcm";
|
|
18
|
+
const SALT = "balchemy-agent-store-v1";
|
|
19
|
+
const PBKDF2_ITERATIONS = 100_000;
|
|
20
|
+
// ── Encryption helpers ─────────────────────────────────────────────────────────
|
|
21
|
+
function deriveKey() {
|
|
22
|
+
const passphrase = process.env.BALCHEMY_MASTER_KEY ??
|
|
23
|
+
`${os.hostname()}:${os.userInfo().username}:balchemy`;
|
|
24
|
+
return crypto.pbkdf2Sync(passphrase, SALT, PBKDF2_ITERATIONS, 32, "sha256");
|
|
25
|
+
}
|
|
26
|
+
function encrypt(plaintext) {
|
|
27
|
+
const key = deriveKey();
|
|
28
|
+
const iv = crypto.randomBytes(12);
|
|
29
|
+
const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
|
|
30
|
+
const encrypted = Buffer.concat([
|
|
31
|
+
cipher.update(plaintext, "utf8"),
|
|
32
|
+
cipher.final(),
|
|
33
|
+
]);
|
|
34
|
+
const tag = cipher.getAuthTag();
|
|
35
|
+
// Format: base64(iv):base64(tag):base64(encrypted)
|
|
36
|
+
return `${iv.toString("base64")}:${tag.toString("base64")}:${encrypted.toString("base64")}`;
|
|
37
|
+
}
|
|
38
|
+
function decrypt(ciphertext) {
|
|
39
|
+
const key = deriveKey();
|
|
40
|
+
const parts = ciphertext.split(":");
|
|
41
|
+
if (parts.length !== 3) {
|
|
42
|
+
throw new Error("Invalid encrypted store format");
|
|
43
|
+
}
|
|
44
|
+
const [ivB64, tagB64, dataB64] = parts;
|
|
45
|
+
const iv = Buffer.from(ivB64, "base64");
|
|
46
|
+
const tag = Buffer.from(tagB64, "base64");
|
|
47
|
+
const data = Buffer.from(dataB64, "base64");
|
|
48
|
+
const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
|
|
49
|
+
decipher.setAuthTag(tag);
|
|
50
|
+
return decipher.update(data) + decipher.final("utf8");
|
|
51
|
+
}
|
|
52
|
+
// ── Legacy migration ───────────────────────────────────────────────────────────
|
|
53
|
+
/**
|
|
54
|
+
* Attempt to read a plaintext JSON file, parse it as StoreData or single agent.
|
|
55
|
+
* Returns null if the file doesn't exist or is unparseable.
|
|
56
|
+
*/
|
|
57
|
+
function readLegacyFile(filePath) {
|
|
58
|
+
try {
|
|
59
|
+
if (!fs.existsSync(filePath))
|
|
60
|
+
return null;
|
|
61
|
+
const raw = fs.readFileSync(filePath, "utf8");
|
|
62
|
+
const data = JSON.parse(raw);
|
|
63
|
+
// Multi-agent format
|
|
64
|
+
if ("agents" in data && Array.isArray(data.agents)) {
|
|
65
|
+
return data;
|
|
66
|
+
}
|
|
67
|
+
// Single-agent format
|
|
68
|
+
const agent = data;
|
|
69
|
+
if (agent.publicId) {
|
|
70
|
+
return { activeId: agent.publicId, agents: [agent] };
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Migrate plaintext stores to encrypted format.
|
|
80
|
+
* Reads agents.json and agent.json, merges them, writes agents.enc,
|
|
81
|
+
* then deletes the plaintext files.
|
|
82
|
+
*/
|
|
83
|
+
function migrateLegacyStores() {
|
|
84
|
+
const fromMulti = readLegacyFile(LEGACY_STORE_PATH);
|
|
85
|
+
const fromSingle = readLegacyFile(OLD_STORE_PATH);
|
|
86
|
+
if (!fromMulti && !fromSingle)
|
|
87
|
+
return null;
|
|
88
|
+
// Merge: multi-agent store takes precedence, single-agent merged in if not duplicate
|
|
89
|
+
const merged = fromMulti ?? { activeId: null, agents: [] };
|
|
90
|
+
if (fromSingle) {
|
|
91
|
+
for (const agent of fromSingle.agents) {
|
|
92
|
+
if (!merged.agents.some((a) => a.publicId === agent.publicId)) {
|
|
93
|
+
merged.agents.push(agent);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (!merged.activeId && fromSingle.activeId) {
|
|
97
|
+
merged.activeId = fromSingle.activeId;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Write encrypted
|
|
101
|
+
writeStore(merged);
|
|
102
|
+
// Remove plaintext files
|
|
103
|
+
try {
|
|
104
|
+
if (fs.existsSync(LEGACY_STORE_PATH))
|
|
105
|
+
fs.unlinkSync(LEGACY_STORE_PATH);
|
|
106
|
+
}
|
|
107
|
+
catch { /* best effort */ }
|
|
108
|
+
try {
|
|
109
|
+
if (fs.existsSync(OLD_STORE_PATH))
|
|
110
|
+
fs.unlinkSync(OLD_STORE_PATH);
|
|
111
|
+
}
|
|
112
|
+
catch { /* best effort */ }
|
|
113
|
+
return merged;
|
|
114
|
+
}
|
|
115
|
+
// ── Store read/write ───────────────────────────────────────────────────────────
|
|
116
|
+
function readStore() {
|
|
117
|
+
try {
|
|
118
|
+
// Try encrypted store first
|
|
119
|
+
if (fs.existsSync(ENCRYPTED_STORE_PATH)) {
|
|
120
|
+
const raw = fs.readFileSync(ENCRYPTED_STORE_PATH, "utf8");
|
|
121
|
+
const json = decrypt(raw);
|
|
122
|
+
const data = JSON.parse(json);
|
|
123
|
+
if (Array.isArray(data.agents))
|
|
124
|
+
return data;
|
|
125
|
+
}
|
|
126
|
+
// Attempt migration from plaintext
|
|
127
|
+
const migrated = migrateLegacyStores();
|
|
128
|
+
if (migrated)
|
|
129
|
+
return migrated;
|
|
130
|
+
return { activeId: null, agents: [] };
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Decryption failure (machine changed, key changed, etc.)
|
|
134
|
+
// Try legacy migration as fallback
|
|
135
|
+
try {
|
|
136
|
+
const migrated = migrateLegacyStores();
|
|
137
|
+
if (migrated)
|
|
138
|
+
return migrated;
|
|
139
|
+
}
|
|
140
|
+
catch { /* ignore */ }
|
|
141
|
+
return { activeId: null, agents: [] };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function writeStore(data) {
|
|
145
|
+
if (!fs.existsSync(STORE_DIR)) {
|
|
146
|
+
fs.mkdirSync(STORE_DIR, { recursive: true, mode: 0o700 });
|
|
147
|
+
}
|
|
148
|
+
const json = JSON.stringify(data, null, 2);
|
|
149
|
+
const encrypted = encrypt(json);
|
|
150
|
+
fs.writeFileSync(ENCRYPTED_STORE_PATH, encrypted, { mode: 0o600 });
|
|
151
|
+
}
|
|
152
|
+
// ── Public API ─────────────────────────────────────────────────────────────────
|
|
153
|
+
export function saveAgent(agent) {
|
|
154
|
+
const store = readStore();
|
|
155
|
+
const idx = store.agents.findIndex((a) => a.publicId === agent.publicId);
|
|
156
|
+
if (idx >= 0) {
|
|
157
|
+
store.agents[idx] = agent;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
store.agents.push(agent);
|
|
161
|
+
}
|
|
162
|
+
store.activeId = agent.publicId;
|
|
163
|
+
writeStore(store);
|
|
164
|
+
}
|
|
165
|
+
/** Load the active agent, or null if none. */
|
|
166
|
+
export function loadAgent() {
|
|
167
|
+
const store = readStore();
|
|
168
|
+
if (!store.activeId)
|
|
169
|
+
return store.agents[0] ?? null;
|
|
170
|
+
return (store.agents.find((a) => a.publicId === store.activeId) ??
|
|
171
|
+
store.agents[0] ??
|
|
172
|
+
null);
|
|
173
|
+
}
|
|
174
|
+
/** List all saved agents. */
|
|
175
|
+
export function listAgents() {
|
|
176
|
+
return readStore().agents;
|
|
177
|
+
}
|
|
178
|
+
/** Clear the active agent (but keep the list). */
|
|
179
|
+
export function clearAgent() {
|
|
180
|
+
const store = readStore();
|
|
181
|
+
store.activeId = null;
|
|
182
|
+
writeStore(store);
|
|
183
|
+
}
|
|
184
|
+
/** Delete a specific agent from the store. */
|
|
185
|
+
export function deleteAgent(publicId) {
|
|
186
|
+
const store = readStore();
|
|
187
|
+
store.agents = store.agents.filter((a) => a.publicId !== publicId);
|
|
188
|
+
if (store.activeId === publicId) {
|
|
189
|
+
store.activeId = store.agents[0]?.publicId ?? null;
|
|
190
|
+
}
|
|
191
|
+
writeStore(store);
|
|
192
|
+
}
|
|
193
|
+
/** Set active agent by publicId. */
|
|
194
|
+
export function setActiveAgent(publicId) {
|
|
195
|
+
const store = readStore();
|
|
196
|
+
const found = store.agents.find((a) => a.publicId === publicId);
|
|
197
|
+
if (!found)
|
|
198
|
+
return false;
|
|
199
|
+
store.activeId = publicId;
|
|
200
|
+
writeStore(store);
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
export function getStorePath() {
|
|
204
|
+
return ENCRYPTED_STORE_PATH;
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=agent-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-store.js","sourceRoot":"","sources":["../src/agent-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses agent.config.yaml into AgentLoopConfig.
|
|
3
|
+
* Resolves ${ENV_VAR} references in string values.
|
|
4
|
+
* Validates required fields and throws descriptive errors.
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentLoopConfig } from '@balchemyai/agent-sdk';
|
|
7
|
+
export declare function loadConfig(configPath: string): AgentLoopConfig;
|
|
8
|
+
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,uBAAuB,CAAC;AAsE1E,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAkE9D"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses agent.config.yaml into AgentLoopConfig.
|
|
3
|
+
* Resolves ${ENV_VAR} references in string values.
|
|
4
|
+
* Validates required fields and throws descriptive errors.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as yaml from 'js-yaml';
|
|
8
|
+
function resolveEnv(value) {
|
|
9
|
+
return value.replace(/\$\{([^}]+)\}/g, (_, varName) => {
|
|
10
|
+
const envVal = process.env[varName];
|
|
11
|
+
if (envVal === undefined) {
|
|
12
|
+
throw new Error(`Environment variable '${varName}' referenced in config is not set`);
|
|
13
|
+
}
|
|
14
|
+
return envVal;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function requireString(obj, fieldPath) {
|
|
18
|
+
if (typeof obj !== 'string' || !obj) {
|
|
19
|
+
throw new Error(`Config field '${fieldPath}' is required and must be a non-empty string`);
|
|
20
|
+
}
|
|
21
|
+
return resolveEnv(obj);
|
|
22
|
+
}
|
|
23
|
+
function optionalString(obj) {
|
|
24
|
+
if (typeof obj !== 'string' || !obj)
|
|
25
|
+
return undefined;
|
|
26
|
+
return resolveEnv(obj);
|
|
27
|
+
}
|
|
28
|
+
function optionalNumber(obj, defaultVal) {
|
|
29
|
+
if (obj === undefined || obj === null)
|
|
30
|
+
return defaultVal;
|
|
31
|
+
if (typeof obj === 'number')
|
|
32
|
+
return obj;
|
|
33
|
+
if (typeof obj === 'string') {
|
|
34
|
+
const n = parseFloat(obj);
|
|
35
|
+
if (!isNaN(n))
|
|
36
|
+
return n;
|
|
37
|
+
}
|
|
38
|
+
return defaultVal;
|
|
39
|
+
}
|
|
40
|
+
const VALID_SDK_PROVIDERS = ['anthropic', 'openai', 'custom'];
|
|
41
|
+
function parseLlmProvider(raw) {
|
|
42
|
+
const rawStr = String(raw);
|
|
43
|
+
// Map external provider names to SDK providers
|
|
44
|
+
if (rawStr === 'anthropic')
|
|
45
|
+
return 'anthropic';
|
|
46
|
+
if (['openai', 'gemini', 'grok', 'openrouter'].includes(rawStr))
|
|
47
|
+
return 'openai';
|
|
48
|
+
if (VALID_SDK_PROVIDERS.includes(rawStr))
|
|
49
|
+
return rawStr;
|
|
50
|
+
throw new Error(`Config field 'llm.provider' must be one of: anthropic, openai, gemini, grok, openrouter, custom`);
|
|
51
|
+
}
|
|
52
|
+
export function loadConfig(configPath) {
|
|
53
|
+
if (!fs.existsSync(configPath)) {
|
|
54
|
+
throw new Error(`Config file not found: ${configPath}`);
|
|
55
|
+
}
|
|
56
|
+
const raw = fs.readFileSync(configPath, 'utf8');
|
|
57
|
+
let parsed;
|
|
58
|
+
try {
|
|
59
|
+
parsed = yaml.load(raw);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
throw new Error(`Failed to parse YAML config: ${err instanceof Error ? err.message : String(err)}`);
|
|
63
|
+
}
|
|
64
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
65
|
+
throw new Error('Config file must be a YAML object');
|
|
66
|
+
}
|
|
67
|
+
const cfg = parsed;
|
|
68
|
+
const mcpEndpoint = requireString(cfg.mcp_endpoint, 'mcp_endpoint');
|
|
69
|
+
const apiKey = requireString(cfg.api_key, 'api_key');
|
|
70
|
+
if (!cfg.llm) {
|
|
71
|
+
throw new Error("Config field 'llm' is required");
|
|
72
|
+
}
|
|
73
|
+
const llmProvider = parseLlmProvider(cfg.llm.provider);
|
|
74
|
+
const llmApiKey = requireString(cfg.llm.api_key, 'llm.api_key');
|
|
75
|
+
const llmModel = optionalString(cfg.llm.model);
|
|
76
|
+
const llmBaseUrl = optionalString(cfg.llm.base_url);
|
|
77
|
+
const maxDailyLlmCost = optionalNumber(cfg.llm.max_daily_usd, 5);
|
|
78
|
+
const llmTimeoutMs = optionalNumber(cfg.llm.timeout_ms, 15_000);
|
|
79
|
+
const webhookPort = cfg.webhook
|
|
80
|
+
? optionalNumber(cfg.webhook.port, 0) ?? 0
|
|
81
|
+
: 0;
|
|
82
|
+
const webhookSecret = cfg.webhook
|
|
83
|
+
? optionalString(cfg.webhook.secret)
|
|
84
|
+
: undefined;
|
|
85
|
+
const behaviorRulesPath = typeof cfg.behavior_rules_path === 'string' && cfg.behavior_rules_path
|
|
86
|
+
? cfg.behavior_rules_path
|
|
87
|
+
: undefined;
|
|
88
|
+
const behaviorRules = typeof cfg.behavior_rules === 'object' && cfg.behavior_rules !== null
|
|
89
|
+
? cfg.behavior_rules
|
|
90
|
+
: undefined;
|
|
91
|
+
return {
|
|
92
|
+
mcpEndpoint,
|
|
93
|
+
apiKey,
|
|
94
|
+
llmProvider,
|
|
95
|
+
llmApiKey,
|
|
96
|
+
llmModel,
|
|
97
|
+
llmBaseUrl,
|
|
98
|
+
maxDailyLlmCost,
|
|
99
|
+
llmTimeoutMs,
|
|
100
|
+
webhookPort,
|
|
101
|
+
webhookSecret,
|
|
102
|
+
behaviorRulesPath,
|
|
103
|
+
behaviorRules,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=config-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-gen.d.ts","sourceRoot":"","sources":["../src/docker-gen.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBlE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates Dockerfile + docker-compose.yml for the agent.
|
|
3
|
+
* Copies static template files and does not mutate them.
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
const __filename_esm = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname_esm = path.dirname(__filename_esm);
|
|
10
|
+
const TEMPLATES_DIR = path.join(__dirname_esm, '..', 'templates');
|
|
11
|
+
function copyTemplate(filename, outDir) {
|
|
12
|
+
const src = path.join(TEMPLATES_DIR, filename);
|
|
13
|
+
const dest = path.join(outDir, filename);
|
|
14
|
+
if (!fs.existsSync(src)) {
|
|
15
|
+
throw new Error(`Template file not found: ${src}`);
|
|
16
|
+
}
|
|
17
|
+
fs.copyFileSync(src, dest);
|
|
18
|
+
process.stdout.write(` wrote ${dest}\n`);
|
|
19
|
+
}
|
|
20
|
+
export async function generateDocker(outDir) {
|
|
21
|
+
if (!fs.existsSync(outDir)) {
|
|
22
|
+
throw new Error(`Output directory does not exist: ${outDir}`);
|
|
23
|
+
}
|
|
24
|
+
process.stdout.write(`Generating Docker files in ${outDir}...\n`);
|
|
25
|
+
copyTemplate('Dockerfile', outDir);
|
|
26
|
+
copyTemplate('docker-compose.yml', outDir);
|
|
27
|
+
// Write .env.example only if not already present (don't overwrite real .env)
|
|
28
|
+
const envExampleDest = path.join(outDir, '.env.example');
|
|
29
|
+
if (!fs.existsSync(envExampleDest)) {
|
|
30
|
+
copyTemplate('.env.example', envExampleDest);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
process.stdout.write(` skipped .env.example (already exists)\n`);
|
|
34
|
+
}
|
|
35
|
+
process.stdout.write(`\nNext steps:\n` +
|
|
36
|
+
` 1. Copy .env.example to .env and fill in your credentials\n` +
|
|
37
|
+
` 2. Place your agent.config.yaml in the same directory\n` +
|
|
38
|
+
` 3. Run: docker compose up -d\n`);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=docker-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-gen.js","sourceRoot":"","sources":["../src/docker-gen.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;AACnD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AAElE,SAAS,YAAY,CAAC,QAAgB,EAAE,MAAc;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAc;IACjD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,MAAM,OAAO,CAAC,CAAC;IAElE,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;IAE3C,6EAA6E;IAC7E,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACnC,YAAY,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iBAAiB;QACjB,+DAA+D;QAC/D,2DAA2D;QAC3D,kCAAkC,CACnC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* create-balchemy-agent CLI entry point.
|
|
4
|
+
*
|
|
5
|
+
* On launch:
|
|
6
|
+
* - If ~/.balchemy/agent.json exists → offer to resume or start fresh
|
|
7
|
+
* - If no cached agent → run wizard
|
|
8
|
+
*
|
|
9
|
+
* Sub-commands:
|
|
10
|
+
* (no args) Resume cached agent or run wizard
|
|
11
|
+
* init / --init Force run wizard (ignore cache)
|
|
12
|
+
* start [config] Start from agent.config.yaml
|
|
13
|
+
* docker [outDir] Generate Docker files
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}
|