volute 0.4.0 → 0.5.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 +22 -22
- package/dist/agent-Z2B6EFEQ.js +75 -0
- package/dist/{agent-manager-AUCKMGPR.js → agent-manager-PXBKA2GK.js} +4 -4
- package/dist/channel-MK5OK2SI.js +113 -0
- package/dist/chunk-5X7HGB6L.js +107 -0
- package/dist/{chunk-YGFIWIOF.js → chunk-7L4AN5D4.js} +1 -1
- package/dist/{chunk-VRVVQIYY.js → chunk-AZEL2IEK.js} +1 -1
- package/dist/chunk-B3R6L2GW.js +24 -0
- package/dist/{chunk-DNOXHLE5.js → chunk-HE67X4T6.js} +1 -1
- package/dist/{chunk-I6OHXCMV.js → chunk-MW2KFO3B.js} +47 -9
- package/dist/{chunk-5OCWMTVS.js → chunk-SMISE4SV.js} +77 -3
- package/dist/{chunk-SOZA2TLP.js → chunk-UAVD2AHX.js} +1 -1
- package/dist/{chunk-3C2XR4IY.js → chunk-UX25Z2ND.js} +113 -107
- package/dist/{chunk-GSPKUPKU.js → chunk-XUA3JUFK.js} +2 -1
- package/dist/chunk-ZYGKG6VC.js +22 -0
- package/dist/cli.js +86 -74
- package/dist/{connector-DKDJTLYZ.js → connector-LYEMXQEV.js} +11 -6
- package/dist/connectors/discord.js +3 -1
- package/dist/connectors/slack.js +14 -5
- package/dist/connectors/telegram.js +21 -2
- package/dist/conversation-ERXEQZTY.js +163 -0
- package/dist/create-RVCZN6HE.js +91 -0
- package/dist/{daemon-client-XR24PUJF.js → daemon-client-ZY6UUN2M.js} +2 -2
- package/dist/daemon.js +629 -177
- package/dist/{delete-55MXCEY5.js → delete-3QH7VYIN.js} +7 -8
- package/dist/{down-3OB6UVAJ.js → down-O7IFZLVJ.js} +1 -1
- package/dist/{env-JB27UAC3.js → env-4D4REPJF.js} +8 -5
- package/dist/{history-BKG74I43.js → history-OEONB53Z.js} +3 -3
- package/dist/{import-4CI2ZUTJ.js → import-MXJB2EII.js} +8 -8
- package/dist/{logs-NXFFGUKY.js → logs-DF342W4M.js} +2 -2
- package/dist/message-ADHWFHSI.js +32 -0
- package/dist/{package-Z2SFO2SV.js → package-VQOE7JNH.js} +1 -1
- package/dist/{schedule-A35SH4HT.js → schedule-NAG6F463.js} +10 -5
- package/dist/send-66QMKRUH.js +75 -0
- package/dist/{setup-2FDVN7OF.js → setup-RPRRGG2F.js} +5 -5
- package/dist/{start-LDPMCMYT.js → start-TUOXDSFL.js} +3 -3
- package/dist/{status-MVSQG54T.js → status-A36EHRO4.js} +3 -3
- package/dist/{stop-5PZTZCLL.js → stop-AOJZLQ5X.js} +6 -7
- package/dist/{up-F7TMTLRE.js → up-7ILD7GU7.js} +2 -2
- package/dist/update-LPSIAWQ2.js +140 -0
- package/dist/update-check-Y33QDCFL.js +17 -0
- package/dist/{upgrade-6ZW2RD64.js → upgrade-FX2TKJ2S.js} +16 -15
- package/dist/{variant-T64BKARF.js → variant-LAB67OC2.js} +15 -10
- package/dist/web-assets/assets/index-BbRmoxoA.js +308 -0
- package/dist/web-assets/index.html +2 -2
- package/drizzle/0003_clean_ego.sql +12 -0
- package/drizzle/meta/0003_snapshot.json +417 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/templates/_base/.init/.config/hooks/startup-context.sh +19 -1
- package/templates/_base/_skills/volute-agent/SKILL.md +110 -14
- package/templates/_base/home/.config/routes.json +10 -0
- package/templates/_base/home/VOLUTE.md +14 -35
- package/templates/_base/src/lib/format-prefix.ts +1 -1
- package/templates/_base/src/lib/router.ts +163 -16
- package/templates/_base/src/lib/routing.ts +55 -18
- package/templates/_base/src/lib/types.ts +3 -1
- package/templates/agent-sdk/.init/.config/routes.json +5 -0
- package/templates/agent-sdk/.init/CLAUDE.md +2 -2
- package/templates/agent-sdk/src/agent.ts +2 -1
- package/templates/agent-sdk/src/server.ts +8 -2
- package/templates/agent-sdk/volute-template.json +1 -1
- package/templates/pi/.init/.config/routes.json +5 -0
- package/templates/pi/.init/AGENTS.md +1 -1
- package/templates/pi/src/agent.ts +5 -3
- package/templates/pi/src/server.ts +1 -1
- package/templates/pi/volute-template.json +1 -1
- package/dist/channel-DQ6UY7QB.js +0 -67
- package/dist/chunk-ZHCE4DPY.js +0 -110
- package/dist/create-ILVOG75A.js +0 -79
- package/dist/send-3U6OTKG7.js +0 -57
- package/dist/web-assets/assets/index-NS621maO.js +0 -296
- package/templates/agent-sdk/.init/.config/sessions.json +0 -4
- package/templates/pi/.init/.config/sessions.json +0 -1
- package/dist/{service-SA4TTMDU.js → service-HZNIDNJF.js} +3 -3
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
readStdin
|
|
4
|
+
} from "./chunk-ZYGKG6VC.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveAgentName
|
|
7
|
+
} from "./chunk-AZEL2IEK.js";
|
|
8
|
+
import {
|
|
9
|
+
summarizeTool
|
|
10
|
+
} from "./chunk-B3R6L2GW.js";
|
|
11
|
+
import {
|
|
12
|
+
parseArgs
|
|
13
|
+
} from "./chunk-D424ZQGI.js";
|
|
14
|
+
import {
|
|
15
|
+
daemonFetch
|
|
16
|
+
} from "./chunk-7L4AN5D4.js";
|
|
17
|
+
import "./chunk-UX25Z2ND.js";
|
|
18
|
+
import "./chunk-K3NQKI34.js";
|
|
19
|
+
|
|
20
|
+
// src/commands/conversation.ts
|
|
21
|
+
import { userInfo } from "os";
|
|
22
|
+
async function run(args) {
|
|
23
|
+
const subcommand = args[0];
|
|
24
|
+
switch (subcommand) {
|
|
25
|
+
case "create":
|
|
26
|
+
await createConversation(args.slice(1));
|
|
27
|
+
break;
|
|
28
|
+
case "list":
|
|
29
|
+
await listConversations(args.slice(1));
|
|
30
|
+
break;
|
|
31
|
+
case "send":
|
|
32
|
+
await sendToConversation(args.slice(1));
|
|
33
|
+
break;
|
|
34
|
+
case "--help":
|
|
35
|
+
case "-h":
|
|
36
|
+
case void 0:
|
|
37
|
+
printUsage();
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
printUsage();
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function printUsage() {
|
|
45
|
+
console.log(`Usage:
|
|
46
|
+
volute conversation create --participants user1,agent1 [--title "..."] [--agent <name>]
|
|
47
|
+
volute conversation list [--agent <name>]
|
|
48
|
+
volute conversation send <id> "<message>" [--agent <name>]
|
|
49
|
+
echo "message" | volute conversation send <id> [--agent <name>]`);
|
|
50
|
+
}
|
|
51
|
+
async function createConversation(args) {
|
|
52
|
+
const { flags } = parseArgs(args, {
|
|
53
|
+
agent: { type: "string" },
|
|
54
|
+
participants: { type: "string" },
|
|
55
|
+
title: { type: "string" }
|
|
56
|
+
});
|
|
57
|
+
const agentName = resolveAgentName(flags);
|
|
58
|
+
if (!flags.participants) {
|
|
59
|
+
console.error("--participants is required (comma-separated usernames)");
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
const participantNames = flags.participants.split(",").map((s) => s.trim());
|
|
63
|
+
const res = await daemonFetch(`/api/agents/${encodeURIComponent(agentName)}/conversations`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: { "Content-Type": "application/json" },
|
|
66
|
+
body: JSON.stringify({ participantNames, title: flags.title })
|
|
67
|
+
});
|
|
68
|
+
if (!res.ok) {
|
|
69
|
+
const data = await res.json();
|
|
70
|
+
console.error(data.error ?? `Failed to create conversation: ${res.status}`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
const conv = await res.json();
|
|
74
|
+
console.log(`Created conversation: ${conv.id}`);
|
|
75
|
+
if (conv.title) console.log(`Title: ${conv.title}`);
|
|
76
|
+
}
|
|
77
|
+
async function listConversations(args) {
|
|
78
|
+
const { flags } = parseArgs(args, {
|
|
79
|
+
agent: { type: "string" }
|
|
80
|
+
});
|
|
81
|
+
const agentName = resolveAgentName(flags);
|
|
82
|
+
const res = await daemonFetch(`/api/agents/${encodeURIComponent(agentName)}/conversations`);
|
|
83
|
+
if (!res.ok) {
|
|
84
|
+
const data = await res.json();
|
|
85
|
+
console.error(data.error ?? `Failed to list conversations: ${res.status}`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
const convs = await res.json();
|
|
89
|
+
if (convs.length === 0) {
|
|
90
|
+
console.log("No conversations.");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
for (const conv of convs) {
|
|
94
|
+
const title = conv.title || "(untitled)";
|
|
95
|
+
console.log(`${conv.id} ${title} ${conv.updated_at}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function sendToConversation(args) {
|
|
99
|
+
const { positional, flags } = parseArgs(args, {
|
|
100
|
+
agent: { type: "string" }
|
|
101
|
+
});
|
|
102
|
+
const conversationId = positional[0];
|
|
103
|
+
const message = positional[1] ?? await readStdin();
|
|
104
|
+
if (!conversationId || !message) {
|
|
105
|
+
console.error('Usage: volute conversation send <id> "<message>" [--agent <name>]');
|
|
106
|
+
console.error(' echo "message" | volute conversation send <id> [--agent <name>]');
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
const agentName = resolveAgentName(flags);
|
|
110
|
+
const res = await daemonFetch(`/api/agents/${encodeURIComponent(agentName)}/chat`, {
|
|
111
|
+
method: "POST",
|
|
112
|
+
headers: { "Content-Type": "application/json" },
|
|
113
|
+
body: JSON.stringify({
|
|
114
|
+
message,
|
|
115
|
+
conversationId,
|
|
116
|
+
sender: process.env.VOLUTE_AGENT || userInfo().username
|
|
117
|
+
})
|
|
118
|
+
});
|
|
119
|
+
if (!res.ok) {
|
|
120
|
+
const data = await res.json();
|
|
121
|
+
console.error(data.error ?? `Failed to send message: ${res.status}`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
if (!res.body) {
|
|
125
|
+
console.error("No response body");
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
const reader = res.body.getReader();
|
|
129
|
+
const decoder = new TextDecoder();
|
|
130
|
+
let buffer = "";
|
|
131
|
+
while (true) {
|
|
132
|
+
const { done, value } = await reader.read();
|
|
133
|
+
if (done) break;
|
|
134
|
+
buffer += decoder.decode(value, { stream: true });
|
|
135
|
+
const lines = buffer.split("\n");
|
|
136
|
+
buffer = lines.pop() ?? "";
|
|
137
|
+
for (const line of lines) {
|
|
138
|
+
if (!line.startsWith("data:")) continue;
|
|
139
|
+
const data = line.slice(5).trim();
|
|
140
|
+
if (!data) continue;
|
|
141
|
+
let event;
|
|
142
|
+
try {
|
|
143
|
+
event = JSON.parse(data);
|
|
144
|
+
} catch {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (event.type === "text") {
|
|
148
|
+
process.stdout.write(event.content);
|
|
149
|
+
} else if (event.type === "tool_use") {
|
|
150
|
+
process.stderr.write(`${summarizeTool(event.name, event.input)}
|
|
151
|
+
`);
|
|
152
|
+
}
|
|
153
|
+
if (event.type === "done") {
|
|
154
|
+
process.stdout.write("\n");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
process.stdout.write("\n");
|
|
160
|
+
}
|
|
161
|
+
export {
|
|
162
|
+
run
|
|
163
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
applyInitFiles,
|
|
4
|
+
composeTemplate,
|
|
5
|
+
copyTemplateToDir,
|
|
6
|
+
findTemplatesRoot,
|
|
7
|
+
listFiles
|
|
8
|
+
} from "./chunk-XUA3JUFK.js";
|
|
9
|
+
import {
|
|
10
|
+
parseArgs
|
|
11
|
+
} from "./chunk-D424ZQGI.js";
|
|
12
|
+
import {
|
|
13
|
+
chownAgentDir,
|
|
14
|
+
createAgentUser,
|
|
15
|
+
ensureVoluteGroup
|
|
16
|
+
} from "./chunk-UAVD2AHX.js";
|
|
17
|
+
import {
|
|
18
|
+
exec,
|
|
19
|
+
execInherit
|
|
20
|
+
} from "./chunk-5SKQ6J7T.js";
|
|
21
|
+
import {
|
|
22
|
+
addAgent,
|
|
23
|
+
agentDir,
|
|
24
|
+
ensureVoluteHome,
|
|
25
|
+
nextPort
|
|
26
|
+
} from "./chunk-UX25Z2ND.js";
|
|
27
|
+
import "./chunk-K3NQKI34.js";
|
|
28
|
+
|
|
29
|
+
// src/commands/create.ts
|
|
30
|
+
import { existsSync, rmSync } from "fs";
|
|
31
|
+
import { resolve } from "path";
|
|
32
|
+
var TEMPLATE_BRANCH = "volute/template";
|
|
33
|
+
async function run(args) {
|
|
34
|
+
const { positional, flags } = parseArgs(args, {
|
|
35
|
+
template: { type: "string" }
|
|
36
|
+
});
|
|
37
|
+
const name = positional[0];
|
|
38
|
+
const template = flags.template ?? "agent-sdk";
|
|
39
|
+
if (!name) {
|
|
40
|
+
console.error("Usage: volute agent create <name> [--template <name>]");
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
ensureVoluteHome();
|
|
44
|
+
const dest = agentDir(name);
|
|
45
|
+
if (existsSync(dest)) {
|
|
46
|
+
console.error(`Agent already exists: ${name}`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
const templatesRoot = findTemplatesRoot();
|
|
50
|
+
const { composedDir, manifest } = composeTemplate(templatesRoot, template);
|
|
51
|
+
try {
|
|
52
|
+
copyTemplateToDir(composedDir, dest, name, manifest);
|
|
53
|
+
applyInitFiles(dest);
|
|
54
|
+
const port = nextPort();
|
|
55
|
+
addAgent(name, port);
|
|
56
|
+
console.log("Installing dependencies...");
|
|
57
|
+
await execInherit("npm", ["install"], { cwd: dest });
|
|
58
|
+
try {
|
|
59
|
+
await exec("git", ["init"], { cwd: dest });
|
|
60
|
+
await initTemplateBranch(dest, composedDir, manifest);
|
|
61
|
+
} catch (err) {
|
|
62
|
+
rmSync(resolve(dest, ".git"), { recursive: true, force: true });
|
|
63
|
+
console.warn(
|
|
64
|
+
"\nWarning: git setup failed \u2014 variants and upgrades won't be available.",
|
|
65
|
+
"\nTo fix: ensure git is installed with user.name/user.email configured."
|
|
66
|
+
);
|
|
67
|
+
console.warn("Details:", err.message ?? err);
|
|
68
|
+
}
|
|
69
|
+
ensureVoluteGroup();
|
|
70
|
+
createAgentUser(name);
|
|
71
|
+
chownAgentDir(dest, name);
|
|
72
|
+
console.log(`
|
|
73
|
+
Created agent: ${name} (port ${port})`);
|
|
74
|
+
console.log(`
|
|
75
|
+
volute agent start ${name}`);
|
|
76
|
+
} finally {
|
|
77
|
+
rmSync(composedDir, { recursive: true, force: true });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function initTemplateBranch(projectRoot, composedDir, manifest) {
|
|
81
|
+
const templateFiles = listFiles(composedDir).filter((f) => !f.startsWith(".init/") && !f.startsWith(".init\\")).map((f) => manifest.rename[f] ?? f);
|
|
82
|
+
await exec("git", ["checkout", "--orphan", TEMPLATE_BRANCH], { cwd: projectRoot });
|
|
83
|
+
await exec("git", ["add", "--", ...templateFiles], { cwd: projectRoot });
|
|
84
|
+
await exec("git", ["commit", "-m", "template update"], { cwd: projectRoot });
|
|
85
|
+
await exec("git", ["checkout", "-b", "main"], { cwd: projectRoot });
|
|
86
|
+
await exec("git", ["add", "-A"], { cwd: projectRoot });
|
|
87
|
+
await exec("git", ["commit", "-m", "initial commit"], { cwd: projectRoot });
|
|
88
|
+
}
|
|
89
|
+
export {
|
|
90
|
+
run
|
|
91
|
+
};
|