@vellumai/cli 0.4.41 → 0.4.42
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/package.json
CHANGED
|
@@ -23,6 +23,7 @@ describe("constants", () => {
|
|
|
23
23
|
expect(VALID_REMOTE_HOSTS).toContain("local");
|
|
24
24
|
expect(VALID_REMOTE_HOSTS).toContain("gcp");
|
|
25
25
|
expect(VALID_REMOTE_HOSTS).toContain("aws");
|
|
26
|
+
expect(VALID_REMOTE_HOSTS).toContain("docker");
|
|
26
27
|
expect(VALID_REMOTE_HOSTS).toContain("custom");
|
|
27
28
|
});
|
|
28
29
|
|
|
@@ -39,7 +39,11 @@ import {
|
|
|
39
39
|
saveAssistantEntry,
|
|
40
40
|
type AssistantEntry,
|
|
41
41
|
} from "../lib/assistant-config.js";
|
|
42
|
-
import {
|
|
42
|
+
import {
|
|
43
|
+
DEFAULT_DAEMON_PORT,
|
|
44
|
+
DEFAULT_GATEWAY_PORT,
|
|
45
|
+
DEFAULT_QDRANT_PORT,
|
|
46
|
+
} from "../lib/constants.js";
|
|
43
47
|
|
|
44
48
|
afterAll(() => {
|
|
45
49
|
rmSync(testDir, { recursive: true, force: true });
|
|
@@ -91,40 +95,50 @@ describe("multi-local", () => {
|
|
|
91
95
|
});
|
|
92
96
|
|
|
93
97
|
describe("allocateLocalResources() produces non-conflicting ports", () => {
|
|
94
|
-
test("
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
test("first instance returns default legacy resources", async () => {
|
|
99
|
+
// GIVEN no local assistants exist in the lockfile
|
|
100
|
+
|
|
101
|
+
// WHEN we allocate resources for the first instance
|
|
102
|
+
const res = await allocateLocalResources("instance-a");
|
|
103
|
+
|
|
104
|
+
// THEN it returns the default legacy layout (home dir, default ports)
|
|
105
|
+
expect(res.instanceDir).toBe(testDir);
|
|
106
|
+
expect(res.daemonPort).toBe(DEFAULT_DAEMON_PORT);
|
|
107
|
+
expect(res.gatewayPort).toBe(DEFAULT_GATEWAY_PORT);
|
|
108
|
+
expect(res.qdrantPort).toBe(DEFAULT_QDRANT_PORT);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("second instance gets distinct ports and dir when first instance is saved", async () => {
|
|
112
|
+
// GIVEN a first local assistant already exists in the lockfile
|
|
113
|
+
saveAssistantEntry(makeEntry("instance-a"));
|
|
114
|
+
|
|
115
|
+
// AND the default ports are occupied
|
|
98
116
|
const occupiedPorts = new Set([
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
117
|
+
DEFAULT_DAEMON_PORT,
|
|
118
|
+
DEFAULT_GATEWAY_PORT,
|
|
119
|
+
DEFAULT_QDRANT_PORT,
|
|
102
120
|
]);
|
|
103
121
|
probePortMock.mockImplementation((port: number) =>
|
|
104
122
|
Promise.resolve(occupiedPorts.has(port)),
|
|
105
123
|
);
|
|
106
124
|
|
|
125
|
+
// WHEN we allocate resources for a second instance
|
|
107
126
|
const b = await allocateLocalResources("instance-b");
|
|
108
127
|
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
b.gatewayPort,
|
|
116
|
-
b.qdrantPort,
|
|
117
|
-
];
|
|
118
|
-
expect(new Set(allPorts).size).toBe(6);
|
|
119
|
-
|
|
120
|
-
// Instance dirs must be distinct
|
|
121
|
-
expect(a.instanceDir).not.toBe(b.instanceDir);
|
|
122
|
-
expect(a.instanceDir).toContain("instance-a");
|
|
128
|
+
// THEN the second instance gets non-default ports
|
|
129
|
+
expect(occupiedPorts.has(b.daemonPort)).toBe(false);
|
|
130
|
+
expect(occupiedPorts.has(b.gatewayPort)).toBe(false);
|
|
131
|
+
expect(occupiedPorts.has(b.qdrantPort)).toBe(false);
|
|
132
|
+
|
|
133
|
+
// AND it gets its own dedicated instance directory
|
|
123
134
|
expect(b.instanceDir).toContain("instance-b");
|
|
124
135
|
});
|
|
125
136
|
|
|
126
137
|
test("skips ports that probePort reports as in-use", async () => {
|
|
127
|
-
//
|
|
138
|
+
// GIVEN a first local assistant already exists in the lockfile
|
|
139
|
+
saveAssistantEntry(makeEntry("existing"));
|
|
140
|
+
|
|
141
|
+
// AND the default daemon ports are occupied
|
|
128
142
|
const portsInUse = new Set([
|
|
129
143
|
DEFAULT_DAEMON_PORT,
|
|
130
144
|
DEFAULT_DAEMON_PORT + 1,
|
|
@@ -133,7 +147,10 @@ describe("multi-local", () => {
|
|
|
133
147
|
Promise.resolve(portsInUse.has(port)),
|
|
134
148
|
);
|
|
135
149
|
|
|
150
|
+
// WHEN we allocate resources for a new instance
|
|
136
151
|
const res = await allocateLocalResources("probe-test");
|
|
152
|
+
|
|
153
|
+
// THEN the daemon port skips all occupied ports
|
|
137
154
|
expect(res.daemonPort).toBeGreaterThan(DEFAULT_DAEMON_PORT + 1);
|
|
138
155
|
expect(portsInUse.has(res.daemonPort)).toBe(false);
|
|
139
156
|
});
|
package/src/commands/hatch.ts
CHANGED
|
@@ -201,7 +201,7 @@ function parseArgs(): HatchArgs {
|
|
|
201
201
|
console.log(" -d Run in detached mode");
|
|
202
202
|
console.log(" --name <name> Custom instance name");
|
|
203
203
|
console.log(
|
|
204
|
-
" --remote <host> Remote host (local, gcp, aws, custom)",
|
|
204
|
+
" --remote <host> Remote host (local, gcp, aws, docker, custom)",
|
|
205
205
|
);
|
|
206
206
|
console.log(
|
|
207
207
|
" --daemon-only Start assistant only, skip gateway",
|
|
@@ -830,6 +830,11 @@ export async function hatch(): Promise<void> {
|
|
|
830
830
|
return;
|
|
831
831
|
}
|
|
832
832
|
|
|
833
|
+
if (remote === "docker") {
|
|
834
|
+
console.error("Error: Docker remote host is not yet implemented.");
|
|
835
|
+
process.exit(1);
|
|
836
|
+
}
|
|
837
|
+
|
|
833
838
|
console.error(`Error: Remote host '${remote}' is not yet supported.`);
|
|
834
839
|
process.exit(1);
|
|
835
840
|
}
|
package/src/lib/constants.ts
CHANGED
|
@@ -8,7 +8,7 @@ export const DEFAULT_DAEMON_PORT = 7821;
|
|
|
8
8
|
export const DEFAULT_GATEWAY_PORT = 7830;
|
|
9
9
|
export const DEFAULT_QDRANT_PORT = 6333;
|
|
10
10
|
|
|
11
|
-
export const VALID_REMOTE_HOSTS = ["local", "gcp", "aws", "custom"] as const;
|
|
11
|
+
export const VALID_REMOTE_HOSTS = ["local", "gcp", "aws", "docker", "custom"] as const;
|
|
12
12
|
export type RemoteHost = (typeof VALID_REMOTE_HOSTS)[number];
|
|
13
13
|
export const VALID_SPECIES = ["openclaw", "vellum"] as const;
|
|
14
14
|
export type Species = (typeof VALID_SPECIES)[number];
|