vole-agent 0.1.2 → 0.1.4
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/app.js +19 -9
- package/dist/{chunk-DZLI6PBD.js → chunk-ZGGSF3JK.js} +40 -26
- package/dist/index.js +1 -1
- package/dist/web/server.js +15637 -359
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -3,12 +3,14 @@ import {
|
|
|
3
3
|
CliChatSession,
|
|
4
4
|
loadConfig,
|
|
5
5
|
renderToolResult
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZGGSF3JK.js";
|
|
7
7
|
|
|
8
8
|
// src/app.tsx
|
|
9
9
|
import { useState, useEffect, useCallback, useMemo, useRef as useRef2 } from "react";
|
|
10
10
|
import { render, Box, Text as Text2, useInput, useApp, useAnimation, useStdout, Static } from "ink";
|
|
11
11
|
import TextInput from "ink-text-input";
|
|
12
|
+
import { readFile } from "fs/promises";
|
|
13
|
+
import { join } from "path";
|
|
12
14
|
|
|
13
15
|
// src/Markdown.tsx
|
|
14
16
|
import { marked as marked2 } from "marked";
|
|
@@ -452,6 +454,10 @@ function ChatApp({ config, cliOptions, sessionId }) {
|
|
|
452
454
|
async (message) => {
|
|
453
455
|
if (session === null || isSending || message.trim() === "") return;
|
|
454
456
|
const trimmed = message.trim();
|
|
457
|
+
if (config.secrets.apiKey === void 0) {
|
|
458
|
+
setMessages((prev) => [...prev, { role: "user", content: trimmed }, { role: "error", content: 'No API key configured. Add one to ~/.vole/config.json (e.g. {"apiKey": "sk-..."}) or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.' }]);
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
455
461
|
const controller = new AbortController();
|
|
456
462
|
abortControllerRef.current = controller;
|
|
457
463
|
setMessages((prev) => [...prev, { role: "user", content: trimmed }]);
|
|
@@ -660,10 +666,21 @@ function ChatApp({ config, cliOptions, sessionId }) {
|
|
|
660
666
|
] })
|
|
661
667
|
] });
|
|
662
668
|
}
|
|
669
|
+
async function readJsonFile(path) {
|
|
670
|
+
try {
|
|
671
|
+
return JSON.parse(await readFile(path, "utf8"));
|
|
672
|
+
} catch {
|
|
673
|
+
return void 0;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
663
676
|
async function runInkChat({ args, env, sessionsDirectory }) {
|
|
664
677
|
let config;
|
|
665
678
|
try {
|
|
666
|
-
|
|
679
|
+
const home = env.HOME ?? process.env.HOME;
|
|
680
|
+
const input = { env };
|
|
681
|
+
if (home !== void 0) input.userConfig = await readJsonFile(join(home, ".vole", "config.json"));
|
|
682
|
+
input.projectConfig = await readJsonFile("vole.config.json");
|
|
683
|
+
config = loadConfig(input);
|
|
667
684
|
} catch (err) {
|
|
668
685
|
process.stderr.write(
|
|
669
686
|
`Configuration error: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -672,13 +689,6 @@ async function runInkChat({ args, env, sessionsDirectory }) {
|
|
|
672
689
|
process.exitCode = 1;
|
|
673
690
|
return;
|
|
674
691
|
}
|
|
675
|
-
if (config.secrets.apiKey === void 0) {
|
|
676
|
-
process.stderr.write(
|
|
677
|
-
"Missing VOLE_API_KEY or OPENROUTER_API_KEY. Set one to start `vole chat`, or use `vole chat --fake-interactive` for local learning.\n"
|
|
678
|
-
);
|
|
679
|
-
process.exitCode = 1;
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
692
|
const sessionIndex = args.indexOf("--session");
|
|
683
693
|
const sessionId = sessionIndex !== -1 && args[sessionIndex + 1] !== void 0 ? args[sessionIndex + 1] : void 0;
|
|
684
694
|
const cliOptions = {
|
|
@@ -3301,6 +3301,23 @@ function isNodeError4(error) {
|
|
|
3301
3301
|
|
|
3302
3302
|
// src/index.ts
|
|
3303
3303
|
var cliPackageName = "@vole/cli";
|
|
3304
|
+
async function readJsonFile(path) {
|
|
3305
|
+
try {
|
|
3306
|
+
return JSON.parse(await readFile6(path, "utf8"));
|
|
3307
|
+
} catch {
|
|
3308
|
+
return void 0;
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
async function loadCliConfig(options = {}) {
|
|
3312
|
+
const env = options.env ?? process.env;
|
|
3313
|
+
const home = env.HOME ?? process.env.HOME;
|
|
3314
|
+
const input = { env };
|
|
3315
|
+
if (home !== void 0) {
|
|
3316
|
+
input.userConfig = await readJsonFile(join7(home, ".vole", "config.json"));
|
|
3317
|
+
}
|
|
3318
|
+
input.projectConfig = await readJsonFile(join7("vole.config.json"));
|
|
3319
|
+
return loadConfig(input);
|
|
3320
|
+
}
|
|
3304
3321
|
var AGENT_SYSTEM_INSTRUCTION = `You are Vole, a capable coding and general-purpose agent.
|
|
3305
3322
|
|
|
3306
3323
|
## Tool Call Style
|
|
@@ -3446,7 +3463,7 @@ async function runFakeChatTurn(input, options) {
|
|
|
3446
3463
|
stderr: "Missing message for `chat --fake`.\n"
|
|
3447
3464
|
};
|
|
3448
3465
|
}
|
|
3449
|
-
const session = CliChatSession.createFake(`Fake response to: ${message}`, options);
|
|
3466
|
+
const session = await CliChatSession.createFake(`Fake response to: ${message}`, options);
|
|
3450
3467
|
const turn = await session.sendMessage(message);
|
|
3451
3468
|
const commandOutput = await renderSlashCommands(session, slashCommands);
|
|
3452
3469
|
const assistantText = turn.assistantText;
|
|
@@ -3463,18 +3480,18 @@ ${commandOutput}`,
|
|
|
3463
3480
|
};
|
|
3464
3481
|
}
|
|
3465
3482
|
async function runInteractiveFakeChat(options, args) {
|
|
3466
|
-
const session = CliChatSession.createFake((message) => `Fake response to: ${message}`, options, {
|
|
3483
|
+
const session = await CliChatSession.createFake((message) => `Fake response to: ${message}`, options, {
|
|
3467
3484
|
...args.sessionId === void 0 ? {} : { sessionId: args.sessionId }
|
|
3468
3485
|
});
|
|
3469
3486
|
return runInteractiveLoop(session, "Vole chat (fake provider)", options);
|
|
3470
3487
|
}
|
|
3471
3488
|
async function runInteractiveConfiguredChat(options, args) {
|
|
3472
|
-
const config =
|
|
3489
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3473
3490
|
if (config.secrets.apiKey === void 0) {
|
|
3474
3491
|
return {
|
|
3475
3492
|
exitCode: 1,
|
|
3476
3493
|
stdout: "",
|
|
3477
|
-
stderr: "
|
|
3494
|
+
stderr: "No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.\n"
|
|
3478
3495
|
};
|
|
3479
3496
|
}
|
|
3480
3497
|
if (args.resume && args.sessionId !== void 0) {
|
|
@@ -3503,7 +3520,7 @@ Resumed session: ${resumedSessionId}`,
|
|
|
3503
3520
|
);
|
|
3504
3521
|
}
|
|
3505
3522
|
async function runListSessions(options) {
|
|
3506
|
-
const config =
|
|
3523
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3507
3524
|
const store = createConfiguredSessionStore(config, options, createSessionId());
|
|
3508
3525
|
const sessions = await store.listSessions();
|
|
3509
3526
|
if (sessions.length === 0) {
|
|
@@ -3520,12 +3537,12 @@ async function runListSessions(options) {
|
|
|
3520
3537
|
};
|
|
3521
3538
|
}
|
|
3522
3539
|
async function runMemoryDreaming(options) {
|
|
3523
|
-
const config =
|
|
3540
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3524
3541
|
if (config.secrets.apiKey === void 0) {
|
|
3525
3542
|
return {
|
|
3526
3543
|
exitCode: 1,
|
|
3527
3544
|
stdout: "",
|
|
3528
|
-
stderr: "
|
|
3545
|
+
stderr: "No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.\n"
|
|
3529
3546
|
};
|
|
3530
3547
|
}
|
|
3531
3548
|
if (config.memory.longTermFiles !== "write") {
|
|
@@ -3543,12 +3560,12 @@ Be concise and factual. Do not duplicate what is already in MEMORY.md.`;
|
|
|
3543
3560
|
return runBackgroundTask(dreamGoal, "auto", options);
|
|
3544
3561
|
}
|
|
3545
3562
|
async function runBackgroundTask(goal, mode, options) {
|
|
3546
|
-
const config =
|
|
3563
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3547
3564
|
if (config.secrets.apiKey === void 0) {
|
|
3548
3565
|
return {
|
|
3549
3566
|
exitCode: 1,
|
|
3550
3567
|
stdout: "",
|
|
3551
|
-
stderr: "
|
|
3568
|
+
stderr: "No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.\n"
|
|
3552
3569
|
};
|
|
3553
3570
|
}
|
|
3554
3571
|
const effectiveConfig = options.sessionsDirectory ? { ...config, sessions: { directory: options.sessionsDirectory } } : config;
|
|
@@ -3626,7 +3643,7 @@ ${resultLine}
|
|
|
3626
3643
|
};
|
|
3627
3644
|
}
|
|
3628
3645
|
async function runListTasks(options, limit) {
|
|
3629
|
-
const config =
|
|
3646
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3630
3647
|
const effectiveConfig = options.sessionsDirectory ? { ...config, sessions: { directory: options.sessionsDirectory } } : config;
|
|
3631
3648
|
const sessionsDir = resolveSessionsDirectory(effectiveConfig, options.env);
|
|
3632
3649
|
const taskStore = new JsonlTaskStore(join7(sessionsDir, "task-runs.jsonl"));
|
|
@@ -3733,12 +3750,12 @@ async function runDaemonTask(task, config, options, taskStore) {
|
|
|
3733
3750
|
await writeHeartbeat(heartbeatPath, endHeartbeat);
|
|
3734
3751
|
}
|
|
3735
3752
|
async function runDaemon(options, once) {
|
|
3736
|
-
const config =
|
|
3753
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3737
3754
|
if (config.secrets.apiKey === void 0) {
|
|
3738
3755
|
return {
|
|
3739
3756
|
exitCode: 1,
|
|
3740
3757
|
stdout: "",
|
|
3741
|
-
stderr: "
|
|
3758
|
+
stderr: "No API key configured. Add one to ~/.vole/config.json or set VOLE_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY in your shell.\n"
|
|
3742
3759
|
};
|
|
3743
3760
|
}
|
|
3744
3761
|
const effectiveConfig = options.sessionsDirectory ? { ...config, sessions: { directory: options.sessionsDirectory } } : config;
|
|
@@ -3787,14 +3804,14 @@ async function runDaemon(options, once) {
|
|
|
3787
3804
|
process.once("SIGINT", shutdown);
|
|
3788
3805
|
});
|
|
3789
3806
|
}
|
|
3790
|
-
function resolveTaskflowFilePath(options) {
|
|
3791
|
-
const config =
|
|
3807
|
+
async function resolveTaskflowFilePath(options) {
|
|
3808
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3792
3809
|
const effectiveConfig = options.sessionsDirectory ? { ...config, sessions: { directory: options.sessionsDirectory } } : config;
|
|
3793
3810
|
const sessionsDir = resolveSessionsDirectory(effectiveConfig, options.env);
|
|
3794
3811
|
return join7(dirname4(sessionsDir), "taskflow.jsonl");
|
|
3795
3812
|
}
|
|
3796
3813
|
async function runTaskflowList(options, limit) {
|
|
3797
|
-
const filePath = resolveTaskflowFilePath(options);
|
|
3814
|
+
const filePath = await resolveTaskflowFilePath(options);
|
|
3798
3815
|
const store = new JsonlTaskFlowStore(filePath);
|
|
3799
3816
|
const records = await store.list(limit !== void 0 ? { limit } : {});
|
|
3800
3817
|
if (records.length === 0) {
|
|
@@ -3815,7 +3832,7 @@ async function runTaskflowList(options, limit) {
|
|
|
3815
3832
|
};
|
|
3816
3833
|
}
|
|
3817
3834
|
async function runTaskflowShow(id, options) {
|
|
3818
|
-
const filePath = resolveTaskflowFilePath(options);
|
|
3835
|
+
const filePath = await resolveTaskflowFilePath(options);
|
|
3819
3836
|
const store = new JsonlTaskFlowStore(filePath);
|
|
3820
3837
|
const record = await store.get(id);
|
|
3821
3838
|
if (record === void 0) {
|
|
@@ -3845,7 +3862,7 @@ async function runTaskflowShow(id, options) {
|
|
|
3845
3862
|
};
|
|
3846
3863
|
}
|
|
3847
3864
|
async function runTaskflowCancel(id, options) {
|
|
3848
|
-
const filePath = resolveTaskflowFilePath(options);
|
|
3865
|
+
const filePath = await resolveTaskflowFilePath(options);
|
|
3849
3866
|
const store = new JsonlTaskFlowStore(filePath);
|
|
3850
3867
|
const updated = await store.update(id, { status: "cancelled" });
|
|
3851
3868
|
if (updated === void 0) {
|
|
@@ -3869,7 +3886,7 @@ function resolveSkillsDirectory(config, options) {
|
|
|
3869
3886
|
return join7(dirname4(sessionsDir), "skills");
|
|
3870
3887
|
}
|
|
3871
3888
|
async function runSkillsList(options) {
|
|
3872
|
-
const config =
|
|
3889
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3873
3890
|
const skillsDir = resolveSkillsDirectory(config, options);
|
|
3874
3891
|
const loader = new SkillLoader();
|
|
3875
3892
|
const skills = await loader.load({
|
|
@@ -3884,7 +3901,7 @@ async function runSkillsList(options) {
|
|
|
3884
3901
|
};
|
|
3885
3902
|
}
|
|
3886
3903
|
async function runSkillsInstall(sourcePath, options) {
|
|
3887
|
-
const config =
|
|
3904
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3888
3905
|
const skillsDir = resolveSkillsDirectory(config, options);
|
|
3889
3906
|
const manager = new SkillManager(skillsDir);
|
|
3890
3907
|
try {
|
|
@@ -3905,7 +3922,7 @@ async function runSkillsInstall(sourcePath, options) {
|
|
|
3905
3922
|
}
|
|
3906
3923
|
}
|
|
3907
3924
|
async function runSkillsLifecycle(action, name, options) {
|
|
3908
|
-
const config =
|
|
3925
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3909
3926
|
const skillsDir = resolveSkillsDirectory(config, options);
|
|
3910
3927
|
const manager = new SkillManager(skillsDir);
|
|
3911
3928
|
try {
|
|
@@ -3932,7 +3949,7 @@ async function runSkillsLifecycle(action, name, options) {
|
|
|
3932
3949
|
}
|
|
3933
3950
|
}
|
|
3934
3951
|
async function runSkillsReview(name, options) {
|
|
3935
|
-
const config =
|
|
3952
|
+
const config = await loadCliConfig(options.env ? { env: options.env } : {});
|
|
3936
3953
|
const skillsDir = resolveSkillsDirectory(config, options);
|
|
3937
3954
|
const manager = new SkillManager(skillsDir);
|
|
3938
3955
|
const def = await manager.review(name);
|
|
@@ -4090,8 +4107,8 @@ var CliChatSession = class _CliChatSession {
|
|
|
4090
4107
|
close() {
|
|
4091
4108
|
this.#gateway?.unregister(this.#sessionId);
|
|
4092
4109
|
}
|
|
4093
|
-
static createFake(responseContent = "Fake response to: Hello trace", options = {}, sessionOptions = {}) {
|
|
4094
|
-
const config = redactedConfig(
|
|
4110
|
+
static async createFake(responseContent = "Fake response to: Hello trace", options = {}, sessionOptions = {}) {
|
|
4111
|
+
const config = redactedConfig(await loadCliConfig(options.env ? { env: options.env } : {}));
|
|
4095
4112
|
const approvalPromptLog = [];
|
|
4096
4113
|
const provider = options.fakeModelOutputs ? new FakeModelProvider(options.fakeModelOutputs) : typeof responseContent === "function" ? new MessageMappedFakeModelProvider(responseContent) : new FakeModelProvider([
|
|
4097
4114
|
{
|
|
@@ -4123,9 +4140,6 @@ var CliChatSession = class _CliChatSession {
|
|
|
4123
4140
|
);
|
|
4124
4141
|
}
|
|
4125
4142
|
static async createConfigured(config, options = {}, sessionOptions = {}) {
|
|
4126
|
-
if (config.secrets.apiKey === void 0) {
|
|
4127
|
-
throw new Error("Configured chat requires an API key.");
|
|
4128
|
-
}
|
|
4129
4143
|
const sessionId = sessionOptions.sessionId ?? createSessionId();
|
|
4130
4144
|
const currentDate = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4131
4145
|
const approvalPromptLog = [];
|