@vellumai/assistant 0.3.3 → 0.3.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/README.md +8 -16
- package/package.json +1 -1
- package/src/__tests__/call-orchestrator.test.ts +321 -0
- package/src/__tests__/channel-approval-routes.test.ts +382 -124
- package/src/__tests__/channel-approvals.test.ts +51 -2
- package/src/__tests__/channel-delivery-store.test.ts +30 -4
- package/src/__tests__/channel-guardian.test.ts +187 -0
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/daemon-lifecycle.test.ts +635 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +19 -13
- package/src/__tests__/handlers-twilio-config.test.ts +73 -0
- package/src/__tests__/secret-scanner.test.ts +223 -0
- package/src/__tests__/shell-parser-property.test.ts +357 -2
- package/src/__tests__/system-prompt.test.ts +25 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +34 -1
- package/src/__tests__/user-reference.test.ts +68 -0
- package/src/calls/call-orchestrator.ts +63 -11
- package/src/cli/map.ts +6 -0
- package/src/commands/__tests__/cc-command-registry.test.ts +67 -0
- package/src/commands/cc-command-registry.ts +14 -1
- package/src/config/bundled-skills/claude-code/TOOLS.json +10 -3
- package/src/config/bundled-skills/messaging/SKILL.md +4 -0
- package/src/config/defaults.ts +1 -1
- package/src/config/schema.ts +3 -3
- package/src/config/skills.ts +5 -32
- package/src/config/system-prompt.ts +16 -0
- package/src/config/user-reference.ts +29 -0
- package/src/config/vellum-skills/catalog.json +52 -0
- package/src/config/vellum-skills/telegram-setup/SKILL.md +6 -1
- package/src/config/vellum-skills/twilio-setup/SKILL.md +38 -0
- package/src/daemon/auth-manager.ts +103 -0
- package/src/daemon/computer-use-session.ts +8 -1
- package/src/daemon/config-watcher.ts +253 -0
- package/src/daemon/handlers/config.ts +36 -13
- package/src/daemon/handlers/skills.ts +6 -7
- package/src/daemon/ipc-contract.ts +6 -0
- package/src/daemon/ipc-handler.ts +87 -0
- package/src/daemon/lifecycle.ts +16 -4
- package/src/daemon/ride-shotgun-handler.ts +11 -1
- package/src/daemon/server.ts +105 -502
- package/src/daemon/session-agent-loop.ts +5 -14
- package/src/daemon/session-runtime-assembly.ts +60 -44
- package/src/daemon/session.ts +8 -1
- package/src/memory/db-connection.ts +28 -0
- package/src/memory/db-init.ts +1019 -0
- package/src/memory/db.ts +2 -2007
- package/src/memory/embedding-backend.ts +79 -11
- package/src/memory/indexer.ts +2 -0
- package/src/memory/job-utils.ts +64 -4
- package/src/memory/jobs-worker.ts +7 -1
- package/src/memory/recall-cache.ts +107 -0
- package/src/memory/retriever.ts +30 -1
- package/src/memory/schema-migration.ts +984 -0
- package/src/memory/schema.ts +1 -0
- package/src/memory/search/types.ts +2 -0
- package/src/permissions/prompter.ts +14 -3
- package/src/permissions/trust-store.ts +7 -0
- package/src/runtime/channel-approvals.ts +17 -3
- package/src/runtime/gateway-client.ts +2 -1
- package/src/runtime/http-server.ts +15 -4
- package/src/runtime/routes/channel-routes.ts +172 -84
- package/src/runtime/routes/run-routes.ts +7 -1
- package/src/runtime/run-orchestrator.ts +8 -1
- package/src/security/secret-scanner.ts +218 -0
- package/src/skills/frontmatter.ts +63 -0
- package/src/skills/slash-commands.ts +23 -0
- package/src/skills/vellum-catalog-remote.ts +107 -0
- package/src/tools/browser/auto-navigate.ts +132 -24
- package/src/tools/browser/browser-manager.ts +67 -61
- package/src/tools/claude-code/claude-code.ts +55 -3
- package/src/tools/executor.ts +10 -2
- package/src/tools/skills/vellum-catalog.ts +61 -156
- package/src/tools/terminal/parser.ts +21 -5
- package/src/util/platform.ts +8 -1
- package/src/util/retry.ts +4 -4
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IPC wire-level helpers: socket writing, broadcast, and assistant-event
|
|
3
|
+
* hub publishing. Extracted from DaemonServer to separate transport
|
|
4
|
+
* concerns from session management and business logic.
|
|
5
|
+
*/
|
|
6
|
+
import * as net from 'node:net';
|
|
7
|
+
import { serialize, type ServerMessage } from './ipc-protocol.js';
|
|
8
|
+
import { assistantEventHub } from '../runtime/assistant-event-hub.js';
|
|
9
|
+
import { buildAssistantEvent } from '../runtime/assistant-event.js';
|
|
10
|
+
import { getLogger } from '../util/logger.js';
|
|
11
|
+
|
|
12
|
+
const log = getLogger('ipc-handler');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Manages IPC message delivery: writing to individual sockets,
|
|
16
|
+
* broadcasting to all authenticated sockets, and publishing events
|
|
17
|
+
* to the assistant-events hub in order.
|
|
18
|
+
*/
|
|
19
|
+
export class IpcSender {
|
|
20
|
+
private _hubChain: Promise<void> = Promise.resolve();
|
|
21
|
+
|
|
22
|
+
/** Write to a single socket without publishing to the event hub. */
|
|
23
|
+
writeToSocket(socket: net.Socket, msg: ServerMessage): void {
|
|
24
|
+
if (!socket.destroyed && socket.writable) {
|
|
25
|
+
socket.write(serialize(msg));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Send a message to a single socket and publish to the event hub.
|
|
31
|
+
* `sessionId` is resolved from the message itself or the socket binding.
|
|
32
|
+
*/
|
|
33
|
+
send(
|
|
34
|
+
socket: net.Socket,
|
|
35
|
+
msg: ServerMessage,
|
|
36
|
+
socketToSession: Map<net.Socket, string>,
|
|
37
|
+
assistantId: string,
|
|
38
|
+
): void {
|
|
39
|
+
this.writeToSocket(socket, msg);
|
|
40
|
+
const sessionId = extractSessionId(msg) ?? socketToSession.get(socket);
|
|
41
|
+
this.publishAssistantEvent(msg, sessionId, assistantId);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Broadcast a message to all authenticated sockets, then publish
|
|
46
|
+
* a single event to the hub.
|
|
47
|
+
*/
|
|
48
|
+
broadcast(
|
|
49
|
+
authenticatedSockets: Set<net.Socket>,
|
|
50
|
+
msg: ServerMessage,
|
|
51
|
+
socketToSession: Map<net.Socket, string>,
|
|
52
|
+
assistantId: string,
|
|
53
|
+
excludeSocket?: net.Socket,
|
|
54
|
+
): void {
|
|
55
|
+
for (const socket of authenticatedSockets) {
|
|
56
|
+
if (socket === excludeSocket) continue;
|
|
57
|
+
this.writeToSocket(socket, msg);
|
|
58
|
+
}
|
|
59
|
+
const sessionId = extractSessionId(msg)
|
|
60
|
+
?? (excludeSocket ? socketToSession.get(excludeSocket) : undefined);
|
|
61
|
+
this.publishAssistantEvent(msg, sessionId, assistantId);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Publish `msg` as an `AssistantEvent` to the process-level hub.
|
|
66
|
+
* Publications are serialized via a promise chain so subscribers
|
|
67
|
+
* always observe events in send order.
|
|
68
|
+
*/
|
|
69
|
+
private publishAssistantEvent(msg: ServerMessage, sessionId?: string, assistantId?: string): void {
|
|
70
|
+
const id = assistantId ?? 'default';
|
|
71
|
+
const event = buildAssistantEvent(id, msg, sessionId);
|
|
72
|
+
this._hubChain = this._hubChain
|
|
73
|
+
.then(() => assistantEventHub.publish(event))
|
|
74
|
+
.catch((err: unknown) => {
|
|
75
|
+
log.warn({ err }, 'assistant-events hub subscriber threw during IPC send');
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Extract sessionId from a ServerMessage if present. */
|
|
81
|
+
function extractSessionId(msg: ServerMessage): string | undefined {
|
|
82
|
+
const record = msg as unknown as Record<string, unknown>;
|
|
83
|
+
if ('sessionId' in msg && typeof record.sessionId === 'string') {
|
|
84
|
+
return record.sessionId as string;
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
package/src/daemon/lifecycle.ts
CHANGED
|
@@ -429,11 +429,23 @@ export async function runDaemon(): Promise<void> {
|
|
|
429
429
|
if (httpPortEnv) {
|
|
430
430
|
const port = parseInt(httpPortEnv, 10);
|
|
431
431
|
if (!isNaN(port) && port > 0) {
|
|
432
|
-
//
|
|
433
|
-
//
|
|
434
|
-
//
|
|
435
|
-
|
|
432
|
+
// Resolve the bearer token in priority order:
|
|
433
|
+
// 1. Explicit env var (e.g. cloud deploys)
|
|
434
|
+
// 2. Existing token file on disk (preserves QR-paired iOS devices across restarts)
|
|
435
|
+
// 3. Fresh random token (first-time startup)
|
|
436
436
|
const httpTokenPath = getHttpTokenPath();
|
|
437
|
+
let bearerToken = process.env.RUNTIME_PROXY_BEARER_TOKEN;
|
|
438
|
+
if (!bearerToken) {
|
|
439
|
+
try {
|
|
440
|
+
const existing = readFileSync(httpTokenPath, 'utf-8').trim();
|
|
441
|
+
if (existing) bearerToken = existing;
|
|
442
|
+
} catch {
|
|
443
|
+
// File doesn't exist or can't be read — will generate below
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (!bearerToken) {
|
|
447
|
+
bearerToken = randomBytes(32).toString('hex');
|
|
448
|
+
}
|
|
437
449
|
writeFileSync(httpTokenPath, bearerToken, { mode: 0o600 });
|
|
438
450
|
chmodSync(httpTokenPath, 0o600);
|
|
439
451
|
|
|
@@ -169,7 +169,17 @@ export async function handleRideShotgunStart(
|
|
|
169
169
|
clearInterval(checkInterval);
|
|
170
170
|
}
|
|
171
171
|
}, 1000);
|
|
172
|
-
autoNavigate(navDomain, abortSignal)
|
|
172
|
+
autoNavigate(navDomain, abortSignal, (progress) => {
|
|
173
|
+
// Send progress to connected client
|
|
174
|
+
if (progress.type === 'visiting' && progress.url) {
|
|
175
|
+
const shortUrl = progress.url.replace(/^https?:\/\//, '');
|
|
176
|
+
ctx.send(socket, {
|
|
177
|
+
type: 'ride_shotgun_progress',
|
|
178
|
+
watchId,
|
|
179
|
+
message: `[${progress.pageNumber || '?'}] ${shortUrl}`,
|
|
180
|
+
} as any);
|
|
181
|
+
}
|
|
182
|
+
}).then(visited => {
|
|
173
183
|
clearInterval(checkInterval);
|
|
174
184
|
log.info({ watchId, visitedPages: visited.length }, 'Generic auto-navigation finished');
|
|
175
185
|
if (session.status === 'active') {
|