vaan-ai 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/LICENSE +216 -0
- package/README.md +390 -0
- package/dist/src/agent.js +151 -0
- package/dist/src/agent.js.map +1 -0
- package/dist/src/cli/args.js +38 -0
- package/dist/src/cli/args.js.map +1 -0
- package/dist/src/cli/doctor.js +98 -0
- package/dist/src/cli/doctor.js.map +1 -0
- package/dist/src/cli/dotenv.js +58 -0
- package/dist/src/cli/dotenv.js.map +1 -0
- package/dist/src/cli/main.js +138 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/memory-cmd.js +31 -0
- package/dist/src/cli/memory-cmd.js.map +1 -0
- package/dist/src/cli/repl.js +275 -0
- package/dist/src/cli/repl.js.map +1 -0
- package/dist/src/cli/schedule.js +184 -0
- package/dist/src/cli/schedule.js.map +1 -0
- package/dist/src/cli/suggested.js +26 -0
- package/dist/src/cli/suggested.js.map +1 -0
- package/dist/src/cli/trace-cmd.js +69 -0
- package/dist/src/cli/trace-cmd.js.map +1 -0
- package/dist/src/cli/wizard.js +346 -0
- package/dist/src/cli/wizard.js.map +1 -0
- package/dist/src/config.js +130 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/eval/graders.js +145 -0
- package/dist/src/eval/graders.js.map +1 -0
- package/dist/src/eval/report.js +20 -0
- package/dist/src/eval/report.js.map +1 -0
- package/dist/src/eval/runner.js +67 -0
- package/dist/src/eval/runner.js.map +1 -0
- package/dist/src/eval/suites.js +164 -0
- package/dist/src/eval/suites.js.map +1 -0
- package/dist/src/http.js +134 -0
- package/dist/src/http.js.map +1 -0
- package/dist/src/inbox.js +51 -0
- package/dist/src/inbox.js.map +1 -0
- package/dist/src/index.js +180 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/memory/context.js +63 -0
- package/dist/src/memory/context.js.map +1 -0
- package/dist/src/memory/index.js +28 -0
- package/dist/src/memory/index.js.map +1 -0
- package/dist/src/memory/search.js +32 -0
- package/dist/src/memory/search.js.map +1 -0
- package/dist/src/memory/store.js +171 -0
- package/dist/src/memory/store.js.map +1 -0
- package/dist/src/observability/events.js +109 -0
- package/dist/src/observability/events.js.map +1 -0
- package/dist/src/observability/request.js +20 -0
- package/dist/src/observability/request.js.map +1 -0
- package/dist/src/observability/trace.js +149 -0
- package/dist/src/observability/trace.js.map +1 -0
- package/dist/src/paths.js +24 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/permissions/approval.js +80 -0
- package/dist/src/permissions/approval.js.map +1 -0
- package/dist/src/permissions/policy.js +75 -0
- package/dist/src/permissions/policy.js.map +1 -0
- package/dist/src/permissions/rules.js +200 -0
- package/dist/src/permissions/rules.js.map +1 -0
- package/dist/src/prompt.js +114 -0
- package/dist/src/prompt.js.map +1 -0
- package/dist/src/providers/anthropic.js +233 -0
- package/dist/src/providers/anthropic.js.map +1 -0
- package/dist/src/providers/custom.js +46 -0
- package/dist/src/providers/custom.js.map +1 -0
- package/dist/src/providers/google.js +197 -0
- package/dist/src/providers/google.js.map +1 -0
- package/dist/src/providers/index.js +122 -0
- package/dist/src/providers/index.js.map +1 -0
- package/dist/src/providers/ollama.js +44 -0
- package/dist/src/providers/ollama.js.map +1 -0
- package/dist/src/providers/openai.js +193 -0
- package/dist/src/providers/openai.js.map +1 -0
- package/dist/src/providers/shared.js +32 -0
- package/dist/src/providers/shared.js.map +1 -0
- package/dist/src/sandbox/filesystem.js +193 -0
- package/dist/src/sandbox/filesystem.js.map +1 -0
- package/dist/src/sandbox/network.js +119 -0
- package/dist/src/sandbox/network.js.map +1 -0
- package/dist/src/sandbox/process.js +198 -0
- package/dist/src/sandbox/process.js.map +1 -0
- package/dist/src/skills.js +80 -0
- package/dist/src/skills.js.map +1 -0
- package/dist/src/tools/basics.js +41 -0
- package/dist/src/tools/basics.js.map +1 -0
- package/dist/src/tools/code.js +114 -0
- package/dist/src/tools/code.js.map +1 -0
- package/dist/src/tools/files.js +162 -0
- package/dist/src/tools/files.js.map +1 -0
- package/dist/src/tools/git.js +91 -0
- package/dist/src/tools/git.js.map +1 -0
- package/dist/src/tools/grep.js +92 -0
- package/dist/src/tools/grep.js.map +1 -0
- package/dist/src/tools/index.js +66 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/shared.js +11 -0
- package/dist/src/tools/shared.js.map +1 -0
- package/dist/src/tools/web.js +217 -0
- package/dist/src/tools/web.js.map +1 -0
- package/dist/src/types.js +14 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +59 -0
- package/scripts/postinstall.js +47 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// The loop. Read this first.
|
|
2
|
+
//
|
|
3
|
+
// A language model can't do anything. It only produces text. When it "reads a
|
|
4
|
+
// file" it emits a request saying *please run read_file on agent.ts*. This
|
|
5
|
+
// function runs the read, hands the result back, and asks again.
|
|
6
|
+
//
|
|
7
|
+
// Five things it guards, marked GUARD below. Each one is a bug you only find in
|
|
8
|
+
// production: reasoning must round-trip, tool calls arrive in parallel, tool
|
|
9
|
+
// errors are data, not every stop is a stop, and a refused permission is an
|
|
10
|
+
// answer rather than a crash.
|
|
11
|
+
//
|
|
12
|
+
// What the loop does *not* do is decide anything about safety. It doesn't know
|
|
13
|
+
// what a workspace is, whether a path is allowed, or who approves a command.
|
|
14
|
+
// Tools ask the gate; the gate asks a human. Keeping that out of here is why
|
|
15
|
+
// this file stays readable.
|
|
16
|
+
import { PermissionDenied } from "./permissions/approval.js";
|
|
17
|
+
const DEFAULT_MAX_STEPS = 12;
|
|
18
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
19
|
+
/** Answer one prompt. */
|
|
20
|
+
export function runAgent(prompt, opts) {
|
|
21
|
+
const first = { role: "user", parts: [{ type: "text", text: prompt }] };
|
|
22
|
+
return continueAgent([first], opts);
|
|
23
|
+
}
|
|
24
|
+
/** The same loop, resuming a transcript. The REPL uses this from turn two on. */
|
|
25
|
+
export async function continueAgent(messages, opts) {
|
|
26
|
+
const { model, system, tools, ctx, signal, trace } = opts;
|
|
27
|
+
const usedTools = [];
|
|
28
|
+
const maxSteps = opts.maxSteps ?? DEFAULT_MAX_STEPS;
|
|
29
|
+
let maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
30
|
+
let raisedCap = false;
|
|
31
|
+
let usage;
|
|
32
|
+
let steps = 0;
|
|
33
|
+
for (let step = 0; step < maxSteps; step++) {
|
|
34
|
+
steps = step + 1;
|
|
35
|
+
const request = { model, system, tools, messages, maxTokens, ...(signal ? { signal } : {}) };
|
|
36
|
+
const reply = opts.stream
|
|
37
|
+
? await consume(opts.provider.stream(request), opts.onEvent)
|
|
38
|
+
: await opts.provider.generate(request);
|
|
39
|
+
if (reply.usage) {
|
|
40
|
+
usage = {
|
|
41
|
+
input: (usage?.input ?? 0) + reply.usage.input,
|
|
42
|
+
output: (usage?.output ?? 0) + reply.usage.output,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
trace?.record({
|
|
46
|
+
kind: "model_call",
|
|
47
|
+
provider: opts.provider.name,
|
|
48
|
+
model,
|
|
49
|
+
...(reply.usage ? { tokensIn: reply.usage.input, tokensOut: reply.usage.output } : {}),
|
|
50
|
+
});
|
|
51
|
+
// GUARD 4a. Truncated mid-turn. Whatever we got is half-written — a tool
|
|
52
|
+
// call with an unparseable input, a sentence that stops dead — so throw it
|
|
53
|
+
// away rather than append it, raise the cap, and ask again unchanged.
|
|
54
|
+
if (reply.stop === "max_tokens" && !raisedCap) {
|
|
55
|
+
raisedCap = true;
|
|
56
|
+
maxTokens *= 2;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// GUARD 1. Push the provider's own message object, never one we rebuilt
|
|
60
|
+
// from `parts`. `raw` rides along inside it, so signed reasoning blocks go
|
|
61
|
+
// back byte-for-byte on the next request instead of being dropped.
|
|
62
|
+
messages.push(reply.message);
|
|
63
|
+
// GUARD 4b. `pause_turn` is neither an answer nor an error. The provider
|
|
64
|
+
// is asking for the same history back so it can pick up where it stopped.
|
|
65
|
+
if (reply.stop === "pause")
|
|
66
|
+
continue;
|
|
67
|
+
const text = textOf(reply.message);
|
|
68
|
+
if (text && !opts.stream)
|
|
69
|
+
opts.onEvent?.({ type: "text", text });
|
|
70
|
+
const calls = reply.message.parts.filter(isToolCall);
|
|
71
|
+
if (calls.length === 0)
|
|
72
|
+
return { text, messages, usedTools, steps, ...(usage ? { usage } : {}) };
|
|
73
|
+
// GUARD 2. One turn can carry several calls. Run them together, then put
|
|
74
|
+
// every result in the *single* next message, each keyed by its call id.
|
|
75
|
+
// Split them across two messages and the provider rejects the turn.
|
|
76
|
+
const results = await Promise.all(calls.map(async (call) => {
|
|
77
|
+
// Recorded before it runs: the trajectory grader asks what the model
|
|
78
|
+
// reached for, and a tool that failed was still a tool it reached for.
|
|
79
|
+
usedTools.push(call.name);
|
|
80
|
+
opts.onEvent?.({ type: "tool_call", name: call.name, input: call.input });
|
|
81
|
+
trace?.record({ kind: "tool_call", tool: call.name, input: call.input });
|
|
82
|
+
const part = await runTool(call, tools, ctx);
|
|
83
|
+
const { output, isError } = part;
|
|
84
|
+
opts.onEvent?.({ type: "tool_result", name: call.name, output, isError });
|
|
85
|
+
trace?.record({
|
|
86
|
+
kind: "tool_result",
|
|
87
|
+
tool: call.name,
|
|
88
|
+
ok: !isError,
|
|
89
|
+
summary: output.split("\n")[0] ?? "",
|
|
90
|
+
});
|
|
91
|
+
return part;
|
|
92
|
+
}));
|
|
93
|
+
messages.push({ role: "user", parts: results });
|
|
94
|
+
}
|
|
95
|
+
const text = `Stopped after ${maxSteps} steps without reaching an answer.`;
|
|
96
|
+
trace?.record({ kind: "error", where: "agent", message: text });
|
|
97
|
+
return { text, messages, usedTools, steps, ...(usage ? { usage } : {}) };
|
|
98
|
+
}
|
|
99
|
+
/** Drain a streamed turn, forwarding deltas, and hand back the assembled reply. */
|
|
100
|
+
async function consume(events, onEvent) {
|
|
101
|
+
let reply;
|
|
102
|
+
for await (const event of events) {
|
|
103
|
+
if (event.type === "text")
|
|
104
|
+
onEvent?.({ type: "delta", text: event.text });
|
|
105
|
+
else if (event.type === "done")
|
|
106
|
+
reply = event.reply;
|
|
107
|
+
}
|
|
108
|
+
if (!reply)
|
|
109
|
+
throw new Error("The provider's stream ended without finishing the turn.");
|
|
110
|
+
return reply;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* GUARD 3. A tool that throws is information, not a crash. The failure goes
|
|
114
|
+
* back to the model flagged as an error so it can recover — a missing file
|
|
115
|
+
* usually means it should try a different path, not that the run is over.
|
|
116
|
+
*
|
|
117
|
+
* GUARD 5. A refused permission is the same kind of information, and the
|
|
118
|
+
* wording matters: the model has to understand that the answer was no and that
|
|
119
|
+
* asking again the same way will get the same no. It is not a transient error
|
|
120
|
+
* to retry, and it is not a reason to look for another route to the same place.
|
|
121
|
+
*/
|
|
122
|
+
async function runTool(call, tools, ctx) {
|
|
123
|
+
const tool = tools.find((candidate) => candidate.name === call.name);
|
|
124
|
+
if (!tool)
|
|
125
|
+
return toolResult(call.id, `No tool named "${call.name}".`, true);
|
|
126
|
+
try {
|
|
127
|
+
return toolResult(call.id, await tool.run(asRecord(call.input), ctx), false);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
if (err instanceof PermissionDenied) {
|
|
131
|
+
return toolResult(call.id, `${err.message}. The user was asked and the answer was no — don't retry this or ` +
|
|
132
|
+
`look for another way to do it. Tell them what you needed and why.`, true);
|
|
133
|
+
}
|
|
134
|
+
return toolResult(call.id, `${call.name} failed: ${describe(err)}`, true);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const toolResult = (id, output, isError) => ({
|
|
138
|
+
type: "tool_result",
|
|
139
|
+
id,
|
|
140
|
+
output,
|
|
141
|
+
isError,
|
|
142
|
+
});
|
|
143
|
+
const isToolCall = (part) => part.type === "tool_call";
|
|
144
|
+
const textOf = (message) => message.parts
|
|
145
|
+
.filter((part) => part.type === "text")
|
|
146
|
+
.map((part) => part.text)
|
|
147
|
+
.join("")
|
|
148
|
+
.trim();
|
|
149
|
+
const asRecord = (input) => input !== null && typeof input === "object" ? input : {};
|
|
150
|
+
const describe = (err) => (err instanceof Error ? err.message : String(err));
|
|
151
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Argument parsing, extracted so it can be tested.
|
|
2
|
+
//
|
|
3
|
+
// It lived inline in main.ts and had a bug that every unit test missed: with
|
|
4
|
+
// no `--model` flag, `indexOf` returns -1, so `argv[index + 1]` read argv[0]
|
|
5
|
+
// and swallowed the command. `vaan memory` silently became `vaan`. Hence this
|
|
6
|
+
// file, and test/cli.test.ts.
|
|
7
|
+
/** Flags that take a value, so the value is never mistaken for the command. */
|
|
8
|
+
const VALUED = ["--model", "--workspace"];
|
|
9
|
+
export function parseArgs(argv) {
|
|
10
|
+
const flags = new Set(argv.filter((arg) => arg.startsWith("-")));
|
|
11
|
+
// Track each valued flag's *position*, not just its value: -1 means the flag
|
|
12
|
+
// is absent, and index 0 is a perfectly good place for a command to be.
|
|
13
|
+
const consumed = new Set();
|
|
14
|
+
const values = {};
|
|
15
|
+
for (const flag of VALUED) {
|
|
16
|
+
const at = argv.indexOf(flag);
|
|
17
|
+
if (at === -1)
|
|
18
|
+
continue;
|
|
19
|
+
consumed.add(at + 1);
|
|
20
|
+
values[flag] = argv[at + 1];
|
|
21
|
+
}
|
|
22
|
+
const positionals = argv.filter((arg, index) => !arg.startsWith("-") && !consumed.has(index));
|
|
23
|
+
const [command = "repl", ...rest] = positionals;
|
|
24
|
+
const model = values["--model"];
|
|
25
|
+
const workspace = values["--workspace"];
|
|
26
|
+
return {
|
|
27
|
+
command,
|
|
28
|
+
rest,
|
|
29
|
+
...(model ? { model } : {}),
|
|
30
|
+
...(workspace ? { workspace } : {}),
|
|
31
|
+
yes: flags.has("--yes") || flags.has("-y"),
|
|
32
|
+
memory: !flags.has("--no-memory"),
|
|
33
|
+
trace: !flags.has("--no-trace"),
|
|
34
|
+
help: flags.has("--help") || flags.has("-h") || command === "help",
|
|
35
|
+
version: flags.has("--version") || flags.has("-v"),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../../src/cli/args.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,8BAA8B;AAE9B,+EAA+E;AAC/E,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,aAAa,CAAU,CAAC;AAgBnD,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAEjE,6EAA6E;IAC7E,wEAAwE;IACxE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,MAAM,GAAuC,EAAE,CAAC;IACtD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,SAAS;QACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAC7B,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAC7D,CAAC;IACF,MAAM,CAAC,OAAO,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC;IAEhD,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IAExC,OAAO;QACL,OAAO;QACP,IAAI;QACJ,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QAC1C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC;QACjC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC;QAC/B,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,MAAM;QAClE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;KACnD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// `vaan doctor` — is this install actually going to work.
|
|
2
|
+
//
|
|
3
|
+
// Every check answers a question a user would otherwise discover three turns
|
|
4
|
+
// into a conversation: is FTS5 there, is a key set, does the config parse, are
|
|
5
|
+
// the two groups that ship empty actually empty. It never calls a model: a
|
|
6
|
+
// diagnostic that costs money and needs the network is one people won't run.
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { defaultConfig, describeConfig, loadConfig } from "../config.js";
|
|
9
|
+
import { probeFts5 } from "../memory/store.js";
|
|
10
|
+
import { describeRules } from "../permissions/policy.js";
|
|
11
|
+
import { defaultRules } from "../permissions/rules.js";
|
|
12
|
+
import { configFile, databaseFile, home, skillsDir } from "../paths.js";
|
|
13
|
+
import { statuses } from "../providers/index.js";
|
|
14
|
+
import { loadSkills } from "../skills.js";
|
|
15
|
+
import { GROUPS } from "../tools/index.js";
|
|
16
|
+
import { listTraces } from "../observability/trace.js";
|
|
17
|
+
/** Returns the exit code: non-zero when something is actually broken. */
|
|
18
|
+
export function runDoctor(out, opts) {
|
|
19
|
+
const problems = [];
|
|
20
|
+
const line = (ok, text) => {
|
|
21
|
+
out.write(` ${ok === undefined ? " " : ok ? "✓" : "✗"} ${text}\n`);
|
|
22
|
+
};
|
|
23
|
+
out.write("\n environment\n\n");
|
|
24
|
+
line(true, `node ${process.version} on ${process.platform}`);
|
|
25
|
+
line(true, `workspace ${opts.workspace}`);
|
|
26
|
+
out.write("\n memory\n\n");
|
|
27
|
+
const fts = probeFts5();
|
|
28
|
+
if (fts) {
|
|
29
|
+
problems.push("SQLite has no FTS5");
|
|
30
|
+
line(false, `SQLite is missing FTS5 — ${fts}`);
|
|
31
|
+
line(undefined, "fix: npm install better-sqlite3 --build-from-source");
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
line(true, "SQLite with FTS5");
|
|
35
|
+
}
|
|
36
|
+
line(existsSync(databaseFile(opts.workspace)) || undefined, existsSync(databaseFile(opts.workspace))
|
|
37
|
+
? `database at ${databaseFile(opts.workspace)}`
|
|
38
|
+
: "no database yet — it's created on the first turn");
|
|
39
|
+
out.write("\n providers\n\n");
|
|
40
|
+
const ready = statuses(opts.env);
|
|
41
|
+
for (const spec of ready) {
|
|
42
|
+
const key = spec.envKey ? `${spec.envKey} ${spec.ready ? "set" : "missing"}` : "no key needed";
|
|
43
|
+
line(spec.ready, `${spec.name.padEnd(12)} ${key}`);
|
|
44
|
+
}
|
|
45
|
+
if (!ready.some((spec) => spec.ready)) {
|
|
46
|
+
problems.push("no provider is usable");
|
|
47
|
+
}
|
|
48
|
+
out.write("\n configuration\n\n");
|
|
49
|
+
const config = loadConfig(opts.workspace);
|
|
50
|
+
if (!config) {
|
|
51
|
+
line(false, `no config at ${configFile(opts.workspace)} — run \`vaan init\``);
|
|
52
|
+
problems.push("not configured");
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
line(true, "config parses");
|
|
56
|
+
for (const entry of describeConfig(config))
|
|
57
|
+
line(undefined, entry);
|
|
58
|
+
}
|
|
59
|
+
out.write("\n permissions\n\n");
|
|
60
|
+
for (const entry of describeRules(config ? defaultRules(config.approvals) : defaultRules())) {
|
|
61
|
+
line(undefined, entry);
|
|
62
|
+
}
|
|
63
|
+
line(undefined, "credentials and system changes are denied by fixed policy, always");
|
|
64
|
+
out.write("\n tools\n\n");
|
|
65
|
+
// With no config yet, report what would actually run rather than "off":
|
|
66
|
+
// an unconfigured install still has defaults, and saying otherwise sends
|
|
67
|
+
// people looking for a problem that isn't there.
|
|
68
|
+
const enabled = new Set(config?.tools ?? defaultConfig(opts.workspace).tools);
|
|
69
|
+
for (const group of GROUPS) {
|
|
70
|
+
const state = !group.available
|
|
71
|
+
? "not configured in this build"
|
|
72
|
+
: enabled.has(group.group)
|
|
73
|
+
? "on"
|
|
74
|
+
: "off";
|
|
75
|
+
line(group.available && enabled.has(group.group), `${group.label.padEnd(22)} ${state}`);
|
|
76
|
+
}
|
|
77
|
+
const { skills, warnings } = loadSkills(opts.workspace);
|
|
78
|
+
out.write("\n skills\n\n");
|
|
79
|
+
if (skills.length === 0) {
|
|
80
|
+
line(undefined, `none — drop a SKILL.md in ${skillsDir(opts.workspace)}`);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
for (const skill of skills)
|
|
84
|
+
line(true, `${skill.name.padEnd(22)} ${skill.path}`);
|
|
85
|
+
}
|
|
86
|
+
for (const warning of warnings)
|
|
87
|
+
line(false, warning);
|
|
88
|
+
out.write("\n traces\n\n");
|
|
89
|
+
const traces = listTraces(home(opts.workspace), 1);
|
|
90
|
+
line(undefined, traces.length === 0
|
|
91
|
+
? "none yet — written to .vaan/traces after each request"
|
|
92
|
+
: `most recent ${traces[0]?.at ?? ""}`);
|
|
93
|
+
out.write(problems.length === 0
|
|
94
|
+
? "\n all clear\n\n"
|
|
95
|
+
: `\n ${problems.length} problem${problems.length === 1 ? "" : "s"}: ${problems.join(", ")}\n\n`);
|
|
96
|
+
return problems.length === 0 ? 0 : 1;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// A very small .env reader. Node has --env-file, but that only helps if the
|
|
2
|
+
// user remembers to pass it, and `npx vaan` gives them nowhere to put it.
|
|
3
|
+
//
|
|
4
|
+
// Values already in the real environment win, so an exported key always beats
|
|
5
|
+
// a stale one in the file.
|
|
6
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
export function loadEnv(cwd, env = process.env) {
|
|
9
|
+
for (const [key, value] of Object.entries(parseEnv(read(join(cwd, ".env"))))) {
|
|
10
|
+
if (env[key] === undefined)
|
|
11
|
+
env[key] = value;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function parseEnv(text) {
|
|
15
|
+
const out = {};
|
|
16
|
+
for (const raw of text.split("\n")) {
|
|
17
|
+
const line = raw.trim();
|
|
18
|
+
if (!line || line.startsWith("#"))
|
|
19
|
+
continue;
|
|
20
|
+
const eq = line.indexOf("=");
|
|
21
|
+
if (eq <= 0)
|
|
22
|
+
continue;
|
|
23
|
+
const key = line.slice(0, eq).trim();
|
|
24
|
+
const value = line.slice(eq + 1).trim();
|
|
25
|
+
out[key] = /^(".*"|'.*')$/s.test(value) ? value.slice(1, -1) : value;
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
/** Add or replace keys in .env, leaving comments and unrelated keys alone. */
|
|
30
|
+
export function updateEnvFile(cwd, updates) {
|
|
31
|
+
const path = join(cwd, ".env");
|
|
32
|
+
const lines = read(path).split("\n");
|
|
33
|
+
const remaining = { ...updates };
|
|
34
|
+
const merged = lines.map((line) => {
|
|
35
|
+
const eq = line.indexOf("=");
|
|
36
|
+
if (line.trim().startsWith("#") || eq <= 0)
|
|
37
|
+
return line;
|
|
38
|
+
const key = line.slice(0, eq).trim();
|
|
39
|
+
if (!(key in remaining))
|
|
40
|
+
return line;
|
|
41
|
+
const value = remaining[key];
|
|
42
|
+
delete remaining[key];
|
|
43
|
+
return `${key}=${value}`;
|
|
44
|
+
});
|
|
45
|
+
const added = Object.entries(remaining).map(([key, value]) => `${key}=${value}`);
|
|
46
|
+
const body = [...merged, ...added].join("\n").replace(/\n{3,}/g, "\n\n").trimEnd();
|
|
47
|
+
writeFileSync(path, `${body}\n`, "utf8");
|
|
48
|
+
return path;
|
|
49
|
+
}
|
|
50
|
+
function read(path) {
|
|
51
|
+
try {
|
|
52
|
+
return readFileSync(path, "utf8");
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return "";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=dotenv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dotenv.js","sourceRoot":"","sources":["../../../src/cli/dotenv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Entry point. Seven commands, and the bare one is the REPL.
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { defaultConfig, loadConfig } from "../config.js";
|
|
5
|
+
import { printReport } from "../eval/report.js";
|
|
6
|
+
import { runEvals } from "../eval/runner.js";
|
|
7
|
+
import { openMemory } from "../memory/store.js";
|
|
8
|
+
import { parseArgs } from "./args.js";
|
|
9
|
+
import { runDoctor } from "./doctor.js";
|
|
10
|
+
import { loadEnv } from "./dotenv.js";
|
|
11
|
+
import { printMemory } from "./memory-cmd.js";
|
|
12
|
+
import { runRepl } from "./repl.js";
|
|
13
|
+
import { addSchedule, printSchedules, removeSchedule, runSchedule } from "./schedule.js";
|
|
14
|
+
import { printTrace, printTraceList } from "./trace-cmd.js";
|
|
15
|
+
import { runWizard, VERSION } from "./wizard.js";
|
|
16
|
+
const HELP = `
|
|
17
|
+
Vaan ${VERSION}
|
|
18
|
+
|
|
19
|
+
vaan start the REPL
|
|
20
|
+
vaan init run setup again
|
|
21
|
+
vaan memory print facts and recent turns
|
|
22
|
+
vaan trace [id] list requests, or show one in full
|
|
23
|
+
vaan doctor check this install
|
|
24
|
+
vaan eval run the suites, exit non-zero if they fail
|
|
25
|
+
vaan schedule list, add, remove or run a scheduled task
|
|
26
|
+
|
|
27
|
+
options
|
|
28
|
+
|
|
29
|
+
--model <spec> provider/model for this run, e.g. anthropic/claude-opus-5
|
|
30
|
+
--workspace <path> work somewhere other than the current directory
|
|
31
|
+
--no-memory don't read or write memory this session
|
|
32
|
+
--no-trace don't write a trace file this session
|
|
33
|
+
--yes grant every permission without asking
|
|
34
|
+
--help, --version
|
|
35
|
+
|
|
36
|
+
In the REPL: /model /new /memory /forget /inbox /status /trace /settings /exit
|
|
37
|
+
`;
|
|
38
|
+
async function main(argv) {
|
|
39
|
+
const out = process.stdout;
|
|
40
|
+
const args = parseArgs(argv);
|
|
41
|
+
const workspace = resolve(args.workspace ?? process.cwd());
|
|
42
|
+
loadEnv(workspace);
|
|
43
|
+
if (args.help) {
|
|
44
|
+
out.write(HELP);
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
if (args.version) {
|
|
48
|
+
out.write(`${VERSION}\n`);
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
const stored = loadConfig(workspace);
|
|
52
|
+
// Precedence: the flag, then the environment, then what setup decided.
|
|
53
|
+
const model = args.model ?? process.env.VAAN_MODEL ?? stored?.model;
|
|
54
|
+
switch (args.command) {
|
|
55
|
+
case "memory": {
|
|
56
|
+
const store = openMemory({ dir: workspace, turnLimit: 10 });
|
|
57
|
+
printMemory(out, await store.recall(workspace, ""));
|
|
58
|
+
store.close?.();
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
case "trace":
|
|
62
|
+
return args.rest[0]
|
|
63
|
+
? printTrace(out, workspace, args.rest[0])
|
|
64
|
+
: printTraceList(out, workspace);
|
|
65
|
+
case "doctor":
|
|
66
|
+
return runDoctor(out, {
|
|
67
|
+
workspace,
|
|
68
|
+
env: process.env,
|
|
69
|
+
...(model ? { model } : {}),
|
|
70
|
+
});
|
|
71
|
+
case "eval": {
|
|
72
|
+
if (!model)
|
|
73
|
+
return unconfigured(out);
|
|
74
|
+
const report = await runEvals({ workspace, model, env: process.env });
|
|
75
|
+
printReport(out, report);
|
|
76
|
+
return report.passed ? 0 : 1;
|
|
77
|
+
}
|
|
78
|
+
case "schedule": {
|
|
79
|
+
const [sub, id] = args.rest;
|
|
80
|
+
if (!sub)
|
|
81
|
+
return printSchedules(out, workspace);
|
|
82
|
+
if (sub === "add")
|
|
83
|
+
return addSchedule(out, workspace);
|
|
84
|
+
if (sub === "remove" && id)
|
|
85
|
+
return removeSchedule(out, workspace, id);
|
|
86
|
+
if (sub === "run" && id) {
|
|
87
|
+
if (!model)
|
|
88
|
+
return unconfigured(out);
|
|
89
|
+
return runSchedule(out, id, { workspace, env: process.env, model, yes: args.yes });
|
|
90
|
+
}
|
|
91
|
+
out.write("\n vaan schedule [add | run <id> | remove <id>]\n\n");
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
case "repl":
|
|
95
|
+
case "init":
|
|
96
|
+
break;
|
|
97
|
+
default:
|
|
98
|
+
out.write(`\n Unknown command "${args.command}".\n${HELP}`);
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
// Setup needs a person at the keyboard. Say so and leave, rather than
|
|
102
|
+
// blocking forever on a prompt that nothing is going to answer.
|
|
103
|
+
const needsSetup = args.command === "init" || !model;
|
|
104
|
+
if (!process.stdin.isTTY && (needsSetup ? !args.yes : true)) {
|
|
105
|
+
out.write(needsSetup
|
|
106
|
+
? "\n Vaan needs a terminal to set up. Run it interactively, or pass --yes with\n" +
|
|
107
|
+
" VAAN_MODEL and an API key already in the environment.\n\n"
|
|
108
|
+
: "\n Vaan is a REPL and needs a terminal. It doesn't read piped input.\n\n");
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
let config = stored ?? defaultConfig(workspace, model ?? "");
|
|
112
|
+
if (needsSetup) {
|
|
113
|
+
const result = await runWizard({ cwd: workspace, yes: args.yes, env: process.env });
|
|
114
|
+
if (!result)
|
|
115
|
+
return 1;
|
|
116
|
+
config = result.config;
|
|
117
|
+
if (args.command === "init")
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
return runRepl({
|
|
121
|
+
workspace: config.workspace,
|
|
122
|
+
model: args.model ?? config.model,
|
|
123
|
+
config,
|
|
124
|
+
memory: args.memory && config.memory,
|
|
125
|
+
yes: args.yes,
|
|
126
|
+
trace: args.trace,
|
|
127
|
+
env: process.env,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function unconfigured(out) {
|
|
131
|
+
out.write("\n No model configured. Run `vaan init` first.\n\n");
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
main(process.argv.slice(2)).then((code) => process.exit(code), (err) => {
|
|
135
|
+
process.stderr.write(`\n ${err instanceof Error ? err.message : String(err)}\n\n`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// `vaan memory`, and the /memory slash command. Both print the same thing:
|
|
2
|
+
// what's injected on every turn, then what's sitting in the searchable tier.
|
|
3
|
+
export function printMemory(out, recall) {
|
|
4
|
+
out.write("\n facts — sent with every message\n\n");
|
|
5
|
+
if (recall.facts.length === 0) {
|
|
6
|
+
out.write(" (none yet)\n");
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
for (const fact of recall.facts) {
|
|
10
|
+
out.write(` ${String(fact.id).padStart(3)} ${fact.text}\n`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
out.write("\n recent turns — searched, not injected\n\n");
|
|
14
|
+
if (recall.turns.length === 0) {
|
|
15
|
+
out.write(" (none yet)\n");
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
for (const turn of recall.turns) {
|
|
19
|
+
const tools = turn.tools.length > 0 ? ` [${turn.tools.join(", ")}]` : "";
|
|
20
|
+
out.write(` ${turn.ts.slice(0, 16).replace("T", " ")}${tools}\n`);
|
|
21
|
+
out.write(` ${clip(turn.userText)}\n`);
|
|
22
|
+
out.write(` ${clip(turn.replyText)}\n\n`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
out.write("\n");
|
|
26
|
+
}
|
|
27
|
+
const clip = (text) => {
|
|
28
|
+
const line = text.replace(/\s+/g, " ").trim();
|
|
29
|
+
return line.length <= 96 ? line : `${line.slice(0, 96)}…`;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=memory-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-cmd.js","sourceRoot":"","sources":["../../../src/cli/memory-cmd.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAI7E,MAAM,UAAU,WAAW,CAAC,GAAuB,EAAE,MAAc;IACjE,GAAG,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,GAAG,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,GAAG,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;YACrE,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC5C,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,OAAO,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;AAC5D,CAAC,CAAC"}
|