@vellumai/assistant 0.3.19 → 0.3.20
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/ARCHITECTURE.md +151 -15
- package/Dockerfile +1 -0
- package/README.md +40 -4
- package/docs/architecture/integrations.md +7 -11
- package/package.json +1 -1
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +54 -0
- package/src/__tests__/approval-primitive.test.ts +540 -0
- package/src/__tests__/assistant-feature-flag-guard.test.ts +206 -0
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +198 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +272 -0
- package/src/__tests__/call-controller.test.ts +439 -108
- package/src/__tests__/channel-invite-transport.test.ts +264 -0
- package/src/__tests__/cli.test.ts +42 -1
- package/src/__tests__/config-schema.test.ts +11 -127
- package/src/__tests__/config-watcher.test.ts +0 -8
- package/src/__tests__/daemon-lifecycle.test.ts +1 -0
- package/src/__tests__/daemon-server-session-init.test.ts +8 -2
- package/src/__tests__/diff.test.ts +22 -0
- package/src/__tests__/guardian-action-copy-generator.test.ts +5 -0
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +300 -32
- package/src/__tests__/guardian-action-late-reply.test.ts +546 -1
- package/src/__tests__/guardian-actions-endpoint.test.ts +774 -0
- package/src/__tests__/guardian-control-plane-policy.test.ts +36 -3
- package/src/__tests__/guardian-dispatch.test.ts +124 -0
- package/src/__tests__/guardian-grant-minting.test.ts +6 -17
- package/src/__tests__/inbound-invite-redemption.test.ts +367 -0
- package/src/__tests__/invite-redemption-service.test.ts +306 -0
- package/src/__tests__/ipc-snapshot.test.ts +57 -0
- package/src/__tests__/notification-decision-fallback.test.ts +88 -0
- package/src/__tests__/sandbox-diagnostics.test.ts +6 -249
- package/src/__tests__/sandbox-host-parity.test.ts +6 -13
- package/src/__tests__/scoped-approval-grants.test.ts +6 -6
- package/src/__tests__/scoped-grant-security-matrix.test.ts +5 -4
- package/src/__tests__/script-proxy-session-manager.test.ts +1 -19
- package/src/__tests__/session-load-history-repair.test.ts +169 -2
- package/src/__tests__/session-runtime-assembly.test.ts +33 -5
- package/src/__tests__/skill-feature-flags-integration.test.ts +171 -0
- package/src/__tests__/skill-feature-flags.test.ts +188 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +141 -0
- package/src/__tests__/skill-mirror-parity.test.ts +1 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +363 -0
- package/src/__tests__/system-prompt.test.ts +1 -1
- package/src/__tests__/terminal-sandbox.test.ts +142 -9
- package/src/__tests__/terminal-tools.test.ts +2 -93
- package/src/__tests__/thread-seed-composer.test.ts +18 -0
- package/src/__tests__/tool-approval-handler.test.ts +350 -0
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +8 -10
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +46 -84
- package/src/agent/loop.ts +36 -1
- package/src/approvals/approval-primitive.ts +381 -0
- package/src/approvals/guardian-decision-primitive.ts +191 -0
- package/src/calls/call-controller.ts +252 -209
- package/src/calls/call-domain.ts +44 -6
- package/src/calls/guardian-dispatch.ts +48 -0
- package/src/calls/types.ts +1 -1
- package/src/calls/voice-session-bridge.ts +46 -30
- package/src/cli/core-commands.ts +0 -4
- package/src/cli.ts +76 -34
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +179 -0
- package/src/config/assistant-feature-flags.ts +162 -0
- package/src/config/bundled-skills/api-mapping/icon.svg +18 -0
- package/src/config/bundled-skills/messaging/TOOLS.json +30 -0
- package/src/config/bundled-skills/messaging/tools/slack-delete-message.ts +24 -0
- package/src/config/bundled-skills/notifications/SKILL.md +1 -1
- package/src/config/bundled-skills/reminder/SKILL.md +49 -2
- package/src/config/bundled-skills/time-based-actions/SKILL.md +49 -2
- package/src/config/bundled-skills/voice-setup/SKILL.md +122 -0
- package/src/config/core-schema.ts +1 -1
- package/src/config/env-registry.ts +10 -0
- package/src/config/feature-flag-registry.json +61 -0
- package/src/config/loader.ts +22 -1
- package/src/config/sandbox-schema.ts +0 -39
- package/src/config/schema.ts +6 -2
- package/src/config/skill-state.ts +34 -0
- package/src/config/skills-schema.ts +0 -1
- package/src/config/skills.ts +9 -0
- package/src/config/system-prompt.ts +110 -46
- package/src/config/templates/SOUL.md +1 -1
- package/src/config/types.ts +19 -1
- package/src/config/vellum-skills/catalog.json +1 -1
- package/src/config/vellum-skills/guardian-verify-setup/SKILL.md +1 -0
- package/src/config/vellum-skills/sms-setup/SKILL.md +1 -1
- package/src/config/vellum-skills/telegram-setup/SKILL.md +1 -1
- package/src/config/vellum-skills/trusted-contacts/SKILL.md +104 -3
- package/src/config/vellum-skills/twilio-setup/SKILL.md +1 -1
- package/src/daemon/config-watcher.ts +0 -1
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/guardian-invite-intent.ts +124 -0
- package/src/daemon/handlers/avatar.ts +68 -0
- package/src/daemon/handlers/browser.ts +2 -2
- package/src/daemon/handlers/guardian-actions.ts +120 -0
- package/src/daemon/handlers/index.ts +4 -0
- package/src/daemon/handlers/sessions.ts +19 -0
- package/src/daemon/handlers/shared.ts +3 -1
- package/src/daemon/install-cli-launchers.ts +58 -13
- package/src/daemon/ipc-contract/guardian-actions.ts +53 -0
- package/src/daemon/ipc-contract/sessions.ts +8 -2
- package/src/daemon/ipc-contract/settings.ts +25 -2
- package/src/daemon/ipc-contract-inventory.json +10 -0
- package/src/daemon/ipc-contract.ts +4 -0
- package/src/daemon/lifecycle.ts +6 -2
- package/src/daemon/main.ts +1 -0
- package/src/daemon/server.ts +1 -0
- package/src/daemon/session-lifecycle.ts +52 -7
- package/src/daemon/session-memory.ts +45 -0
- package/src/daemon/session-process.ts +258 -432
- package/src/daemon/session-runtime-assembly.ts +12 -0
- package/src/daemon/session-skill-tools.ts +14 -1
- package/src/daemon/session-tool-setup.ts +5 -0
- package/src/daemon/session.ts +11 -0
- package/src/daemon/tool-side-effects.ts +35 -9
- package/src/index.ts +0 -2
- package/src/memory/conversation-display-order-migration.ts +44 -0
- package/src/memory/conversation-queries.ts +2 -0
- package/src/memory/conversation-store.ts +91 -0
- package/src/memory/db-init.ts +5 -1
- package/src/memory/embedding-local.ts +13 -8
- package/src/memory/guardian-action-store.ts +125 -2
- package/src/memory/ingress-invite-store.ts +95 -1
- package/src/memory/migrations/035-guardian-action-supersession.ts +23 -0
- package/src/memory/migrations/index.ts +2 -1
- package/src/memory/schema.ts +5 -1
- package/src/memory/scoped-approval-grants.ts +14 -5
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/types.ts +5 -0
- package/src/notifications/decision-engine.ts +49 -12
- package/src/notifications/emit-signal.ts +7 -0
- package/src/notifications/signal.ts +7 -0
- package/src/notifications/thread-seed-composer.ts +2 -1
- package/src/runtime/channel-approval-types.ts +16 -6
- package/src/runtime/channel-approvals.ts +19 -15
- package/src/runtime/channel-invite-transport.ts +85 -0
- package/src/runtime/channel-invite-transports/telegram.ts +105 -0
- package/src/runtime/guardian-action-grant-minter.ts +92 -35
- package/src/runtime/guardian-action-message-composer.ts +30 -0
- package/src/runtime/guardian-decision-types.ts +91 -0
- package/src/runtime/http-server.ts +23 -1
- package/src/runtime/ingress-service.ts +22 -0
- package/src/runtime/invite-redemption-service.ts +181 -0
- package/src/runtime/invite-redemption-templates.ts +39 -0
- package/src/runtime/routes/call-routes.ts +2 -1
- package/src/runtime/routes/guardian-action-routes.ts +206 -0
- package/src/runtime/routes/guardian-approval-interception.ts +66 -190
- package/src/runtime/routes/inbound-message-handler.ts +486 -394
- package/src/runtime/routes/pairing-routes.ts +4 -0
- package/src/security/encrypted-store.ts +31 -17
- package/src/security/keychain.ts +176 -2
- package/src/security/secure-keys.ts +97 -0
- package/src/security/tool-approval-digest.ts +1 -1
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/browser-manager.ts +46 -32
- package/src/tools/browser/browser-screencast.ts +2 -2
- package/src/tools/calls/call-start.ts +1 -1
- package/src/tools/executor.ts +22 -17
- package/src/tools/network/script-proxy/session-manager.ts +1 -5
- package/src/tools/skills/load.ts +22 -8
- package/src/tools/system/avatar-generator.ts +119 -0
- package/src/tools/system/navigate-settings.ts +65 -0
- package/src/tools/system/open-system-settings.ts +75 -0
- package/src/tools/system/voice-config.ts +121 -32
- package/src/tools/terminal/backends/native.ts +40 -19
- package/src/tools/terminal/backends/types.ts +3 -3
- package/src/tools/terminal/parser.ts +1 -1
- package/src/tools/terminal/sandbox-diagnostics.ts +6 -87
- package/src/tools/terminal/sandbox.ts +1 -12
- package/src/tools/terminal/shell.ts +3 -31
- package/src/tools/tool-approval-handler.ts +141 -3
- package/src/tools/tool-manifest.ts +6 -0
- package/src/tools/types.ts +6 -0
- package/src/util/diff.ts +36 -13
- package/Dockerfile.sandbox +0 -5
- package/src/__tests__/doordash-client.test.ts +0 -187
- package/src/__tests__/doordash-session.test.ts +0 -154
- package/src/__tests__/signup-e2e.test.ts +0 -354
- package/src/__tests__/terminal-sandbox-docker.test.ts +0 -1065
- package/src/__tests__/terminal-sandbox.integration.test.ts +0 -180
- package/src/cli/doordash.ts +0 -1057
- package/src/config/bundled-skills/doordash/SKILL.md +0 -163
- package/src/config/templates/LOOKS.md +0 -25
- package/src/doordash/cart-queries.ts +0 -787
- package/src/doordash/client.ts +0 -1016
- package/src/doordash/order-queries.ts +0 -85
- package/src/doordash/queries.ts +0 -13
- package/src/doordash/query-extractor.ts +0 -94
- package/src/doordash/search-queries.ts +0 -203
- package/src/doordash/session.ts +0 -84
- package/src/doordash/store-queries.ts +0 -246
- package/src/doordash/types.ts +0 -367
- package/src/tools/terminal/backends/docker.ts +0 -379
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runtime-gated Docker integration tests.
|
|
3
|
-
*
|
|
4
|
-
* These tests run real Docker containers — they are skipped automatically
|
|
5
|
-
* when Docker is not available or the sandbox image is not pulled locally.
|
|
6
|
-
* To run them locally:
|
|
7
|
-
* 1. Install Docker Desktop / Docker Engine
|
|
8
|
-
* 2. docker pull <configured sandbox image>
|
|
9
|
-
* 3. bun test src/__tests__/terminal-sandbox.integration.test.ts
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { execFileSync, spawnSync } from 'node:child_process';
|
|
13
|
-
import {
|
|
14
|
-
existsSync,
|
|
15
|
-
mkdirSync,
|
|
16
|
-
mkdtempSync,
|
|
17
|
-
readFileSync,
|
|
18
|
-
realpathSync,
|
|
19
|
-
rmSync,
|
|
20
|
-
statSync,
|
|
21
|
-
writeFileSync,
|
|
22
|
-
} from 'node:fs';
|
|
23
|
-
import { join } from 'node:path';
|
|
24
|
-
|
|
25
|
-
import { afterAll, beforeAll, describe, expect, test } from 'bun:test';
|
|
26
|
-
|
|
27
|
-
import { DEFAULT_CONFIG } from '../config/defaults.js';
|
|
28
|
-
import { getSandboxWorkingDir } from '../util/platform.js';
|
|
29
|
-
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
// Runtime gate: skip entire file if Docker is not usable
|
|
32
|
-
// ---------------------------------------------------------------------------
|
|
33
|
-
|
|
34
|
-
function dockerAvailable(): boolean {
|
|
35
|
-
try {
|
|
36
|
-
execFileSync('docker', ['info'], { stdio: 'ignore', timeout: 10000 });
|
|
37
|
-
return true;
|
|
38
|
-
} catch {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const IMAGE = DEFAULT_CONFIG.sandbox.docker.image;
|
|
44
|
-
|
|
45
|
-
function imageAvailable(): boolean {
|
|
46
|
-
try {
|
|
47
|
-
execFileSync('docker', ['image', 'inspect', IMAGE], {
|
|
48
|
-
stdio: 'ignore',
|
|
49
|
-
timeout: 10000,
|
|
50
|
-
});
|
|
51
|
-
return true;
|
|
52
|
-
} catch {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const DOCKER_OK = dockerAvailable() && imageAvailable();
|
|
58
|
-
|
|
59
|
-
// ---------------------------------------------------------------------------
|
|
60
|
-
// Helpers
|
|
61
|
-
// ---------------------------------------------------------------------------
|
|
62
|
-
|
|
63
|
-
let sandboxRoot: string;
|
|
64
|
-
|
|
65
|
-
beforeAll(() => {
|
|
66
|
-
if (!DOCKER_OK) return;
|
|
67
|
-
const parent = getSandboxWorkingDir();
|
|
68
|
-
if (!existsSync(parent)) {
|
|
69
|
-
mkdirSync(parent, { recursive: true });
|
|
70
|
-
}
|
|
71
|
-
sandboxRoot = realpathSync(mkdtempSync(join(parent, 'docker-integ-')));
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
afterAll(() => {
|
|
75
|
-
if (sandboxRoot && existsSync(sandboxRoot)) {
|
|
76
|
-
rmSync(sandboxRoot, { recursive: true, force: true });
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
interface DockerRunOptions {
|
|
81
|
-
/** Run as root instead of the host UID:GID. Useful for testing filesystem-level protections. */
|
|
82
|
-
asRoot?: boolean;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** Run a command inside a Docker container with the sandbox root mounted. */
|
|
86
|
-
function dockerRun(cmd: string, opts?: DockerRunOptions): { stdout: string; exitCode: number } {
|
|
87
|
-
const uid = process.getuid?.() ?? 1000;
|
|
88
|
-
const gid = process.getgid?.() ?? 1000;
|
|
89
|
-
const userArgs = opts?.asRoot ? ['--user', '0:0'] : ['--user', `${uid}:${gid}`];
|
|
90
|
-
const result = spawnSync('docker', [
|
|
91
|
-
'run', '--rm',
|
|
92
|
-
'--network=none',
|
|
93
|
-
'--cap-drop=ALL',
|
|
94
|
-
'--security-opt=no-new-privileges',
|
|
95
|
-
'--read-only',
|
|
96
|
-
'--tmpfs', '/tmp:rw,nosuid,nodev,noexec',
|
|
97
|
-
'--mount', `type=bind,src=${sandboxRoot},dst=/workspace`,
|
|
98
|
-
'--workdir', '/workspace',
|
|
99
|
-
...userArgs,
|
|
100
|
-
IMAGE,
|
|
101
|
-
'bash', '-c', cmd,
|
|
102
|
-
], { timeout: 30000, encoding: 'utf-8' });
|
|
103
|
-
return {
|
|
104
|
-
stdout: (result.stdout ?? '').trim(),
|
|
105
|
-
exitCode: result.status ?? -1,
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// ---------------------------------------------------------------------------
|
|
110
|
-
// Tests
|
|
111
|
-
// ---------------------------------------------------------------------------
|
|
112
|
-
|
|
113
|
-
describe.skipIf(!DOCKER_OK)('Docker integration: write inside sandbox', () => {
|
|
114
|
-
test('writing a file inside /workspace succeeds', () => {
|
|
115
|
-
const { exitCode } = dockerRun('echo "hello" > /workspace/test-write.txt && cat /workspace/test-write.txt');
|
|
116
|
-
expect(exitCode).toBe(0);
|
|
117
|
-
// Verify the file appeared on the host
|
|
118
|
-
const hostPath = join(sandboxRoot, 'test-write.txt');
|
|
119
|
-
expect(existsSync(hostPath)).toBe(true);
|
|
120
|
-
expect(readFileSync(hostPath, 'utf-8').trim()).toBe('hello');
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test('creating nested directories inside /workspace succeeds', () => {
|
|
124
|
-
const { exitCode, stdout } = dockerRun('mkdir -p /workspace/a/b/c && echo ok');
|
|
125
|
-
expect(exitCode).toBe(0);
|
|
126
|
-
expect(stdout).toBe('ok');
|
|
127
|
-
expect(existsSync(join(sandboxRoot, 'a/b/c'))).toBe(true);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
describe.skipIf(!DOCKER_OK)('Docker integration: write outside workspace fails', () => {
|
|
132
|
-
// Run as root so Unix permissions are not a factor — the read-only
|
|
133
|
-
// filesystem mount is the only thing preventing these writes.
|
|
134
|
-
test('writing to /etc inside container fails (read-only root)', () => {
|
|
135
|
-
const { exitCode } = dockerRun('touch /etc/evil 2>/dev/null', { asRoot: true });
|
|
136
|
-
expect(exitCode).not.toBe(0);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
test('writing to /home inside container fails (read-only root)', () => {
|
|
140
|
-
const { exitCode } = dockerRun('touch /home/evil 2>/dev/null', { asRoot: true });
|
|
141
|
-
expect(exitCode).not.toBe(0);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
test('writing to /tmp succeeds (tmpfs mount)', () => {
|
|
145
|
-
// /tmp is an explicit tmpfs mount so writes should work
|
|
146
|
-
const { exitCode, stdout } = dockerRun('echo ok > /tmp/test.txt && cat /tmp/test.txt');
|
|
147
|
-
expect(exitCode).toBe(0);
|
|
148
|
-
expect(stdout).toBe('ok');
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
describe.skipIf(!DOCKER_OK)('Docker integration: host-writable files', () => {
|
|
153
|
-
test('files created in container are owned by host UID:GID', () => {
|
|
154
|
-
const filename = 'host-owner-test.txt';
|
|
155
|
-
dockerRun(`echo "owned" > /workspace/${filename}`);
|
|
156
|
-
const hostPath = join(sandboxRoot, filename);
|
|
157
|
-
expect(existsSync(hostPath)).toBe(true);
|
|
158
|
-
const stat = statSync(hostPath);
|
|
159
|
-
const expectedUid = process.getuid?.() ?? 1000;
|
|
160
|
-
const expectedGid = process.getgid?.() ?? 1000;
|
|
161
|
-
expect(stat.uid).toBe(expectedUid);
|
|
162
|
-
expect(stat.gid).toBe(expectedGid);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
test('host can read files created by container', () => {
|
|
166
|
-
const filename = 'host-readable-test.txt';
|
|
167
|
-
const content = 'container-created-content';
|
|
168
|
-
dockerRun(`echo "${content}" > /workspace/${filename}`);
|
|
169
|
-
const hostPath = join(sandboxRoot, filename);
|
|
170
|
-
expect(readFileSync(hostPath, 'utf-8').trim()).toBe(content);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
test('container can read files created by host', () => {
|
|
174
|
-
const filename = 'host-created.txt';
|
|
175
|
-
writeFileSync(join(sandboxRoot, filename), 'from-host');
|
|
176
|
-
const { stdout, exitCode } = dockerRun(`cat /workspace/${filename}`);
|
|
177
|
-
expect(exitCode).toBe(0);
|
|
178
|
-
expect(stdout).toBe('from-host');
|
|
179
|
-
});
|
|
180
|
-
});
|