@vellumai/assistant 0.3.4 → 0.3.5
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/Dockerfile +2 -0
- package/README.md +37 -2
- package/package.json +1 -1
- package/scripts/ipc/generate-swift.ts +13 -0
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +100 -0
- package/src/__tests__/approval-hardcoded-copy-guard.test.ts +41 -0
- package/src/__tests__/approval-message-composer.test.ts +253 -0
- package/src/__tests__/call-domain.test.ts +12 -2
- package/src/__tests__/call-orchestrator.test.ts +70 -1
- package/src/__tests__/call-routes-http.test.ts +27 -2
- package/src/__tests__/channel-approval-routes.test.ts +21 -17
- package/src/__tests__/channel-approvals.test.ts +48 -1
- package/src/__tests__/channel-guardian.test.ts +74 -22
- package/src/__tests__/channel-readiness-service.test.ts +257 -0
- package/src/__tests__/config-schema.test.ts +2 -1
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/daemon-lifecycle.test.ts +13 -12
- package/src/__tests__/dictation-mode-detection.test.ts +63 -0
- package/src/__tests__/entity-search.test.ts +615 -0
- package/src/__tests__/handlers-twilio-config.test.ts +407 -0
- package/src/__tests__/ipc-snapshot.test.ts +63 -0
- package/src/__tests__/messaging-send-tool.test.ts +65 -0
- package/src/__tests__/run-orchestrator-assistant-events.test.ts +4 -0
- package/src/__tests__/run-orchestrator.test.ts +22 -0
- package/src/__tests__/session-runtime-assembly.test.ts +85 -1
- package/src/__tests__/sms-messaging-provider.test.ts +125 -0
- package/src/__tests__/twilio-routes.test.ts +39 -3
- package/src/__tests__/twitter-cli-error-shaping.test.ts +2 -2
- package/src/__tests__/web-search.test.ts +1 -1
- package/src/__tests__/work-item-output.test.ts +110 -0
- package/src/calls/call-domain.ts +8 -5
- package/src/calls/call-orchestrator.ts +22 -11
- package/src/calls/twilio-config.ts +17 -11
- package/src/calls/twilio-rest.ts +276 -0
- package/src/calls/twilio-routes.ts +39 -1
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +15 -0
- package/src/config/bundled-skills/knowledge-graph/TOOLS.json +56 -0
- package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +185 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +199 -0
- package/src/config/bundled-skills/media-processing/TOOLS.json +320 -0
- package/src/config/bundled-skills/media-processing/services/capability-registry.ts +137 -0
- package/src/config/bundled-skills/media-processing/services/event-detection-service.ts +280 -0
- package/src/config/bundled-skills/media-processing/services/feedback-aggregation.ts +144 -0
- package/src/config/bundled-skills/media-processing/services/feedback-store.ts +136 -0
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +261 -0
- package/src/config/bundled-skills/media-processing/services/retrieval-service.ts +95 -0
- package/src/config/bundled-skills/media-processing/services/timeline-service.ts +267 -0
- package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +301 -0
- package/src/config/bundled-skills/media-processing/tools/detect-events.ts +110 -0
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +190 -0
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +195 -0
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +197 -0
- package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +166 -0
- package/src/config/bundled-skills/media-processing/tools/media-status.ts +75 -0
- package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +300 -0
- package/src/config/bundled-skills/media-processing/tools/recalibrate.ts +235 -0
- package/src/config/bundled-skills/media-processing/tools/select-tracking-profile.ts +142 -0
- package/src/config/bundled-skills/media-processing/tools/submit-feedback.ts +150 -0
- package/src/config/bundled-skills/messaging/SKILL.md +21 -6
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/twitter/SKILL.md +19 -3
- package/src/config/defaults.ts +2 -1
- package/src/config/schema.ts +9 -3
- package/src/config/system-prompt.ts +24 -0
- package/src/config/templates/IDENTITY.md +2 -2
- package/src/config/vellum-skills/catalog.json +6 -0
- package/src/config/vellum-skills/google-oauth-setup/SKILL.md +3 -3
- package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +3 -3
- package/src/config/vellum-skills/sms-setup/SKILL.md +118 -0
- package/src/config/vellum-skills/twilio-setup/SKILL.md +40 -8
- package/src/daemon/handlers/config.ts +783 -9
- package/src/daemon/handlers/dictation.ts +182 -0
- package/src/daemon/handlers/identity.ts +14 -23
- package/src/daemon/handlers/index.ts +2 -0
- package/src/daemon/handlers/sessions.ts +2 -0
- package/src/daemon/handlers/shared.ts +3 -0
- package/src/daemon/handlers/work-items.ts +15 -7
- package/src/daemon/ipc-contract-inventory.json +10 -0
- package/src/daemon/ipc-contract.ts +108 -4
- package/src/daemon/lifecycle.ts +2 -0
- package/src/daemon/ride-shotgun-handler.ts +1 -1
- package/src/daemon/server.ts +6 -2
- package/src/daemon/session-agent-loop.ts +5 -1
- package/src/daemon/session-runtime-assembly.ts +55 -0
- package/src/daemon/session-tool-setup.ts +2 -0
- package/src/daemon/session.ts +11 -1
- package/src/inbound/public-ingress-urls.ts +3 -3
- package/src/memory/channel-guardian-store.ts +2 -1
- package/src/memory/db-init.ts +144 -0
- package/src/memory/job-handlers/media-processing.ts +100 -0
- package/src/memory/jobs-store.ts +2 -1
- package/src/memory/jobs-worker.ts +4 -0
- package/src/memory/media-store.ts +759 -0
- package/src/memory/retriever.ts +6 -1
- package/src/memory/schema.ts +98 -0
- package/src/memory/search/entity.ts +208 -25
- package/src/memory/search/ranking.ts +6 -1
- package/src/memory/search/types.ts +24 -0
- package/src/messaging/provider-types.ts +2 -0
- package/src/messaging/providers/sms/adapter.ts +204 -0
- package/src/messaging/providers/sms/client.ts +93 -0
- package/src/messaging/providers/sms/types.ts +7 -0
- package/src/permissions/checker.ts +16 -2
- package/src/runtime/approval-message-composer.ts +143 -0
- package/src/runtime/channel-approvals.ts +12 -4
- package/src/runtime/channel-guardian-service.ts +44 -18
- package/src/runtime/channel-readiness-service.ts +292 -0
- package/src/runtime/channel-readiness-types.ts +29 -0
- package/src/runtime/http-server.ts +53 -27
- package/src/runtime/http-types.ts +3 -0
- package/src/runtime/routes/call-routes.ts +2 -1
- package/src/runtime/routes/channel-routes.ts +67 -21
- package/src/runtime/run-orchestrator.ts +35 -2
- package/src/tools/assets/materialize.ts +2 -2
- package/src/tools/calls/call-start.ts +1 -0
- package/src/tools/credentials/vault.ts +1 -1
- package/src/tools/execution-target.ts +11 -1
- package/src/tools/network/web-search.ts +1 -1
- package/src/tools/types.ts +2 -0
- package/src/twitter/router.ts +1 -1
- package/src/util/platform.ts +35 -0
|
@@ -197,6 +197,7 @@ describe('Invariant 2: no generic plaintext secret read API', () => {
|
|
|
197
197
|
'calls/elevenlabs-config.ts', // ElevenLabs credential lookup
|
|
198
198
|
'cli/config-commands.ts', // CLI config management
|
|
199
199
|
'messaging/providers/telegram-bot/adapter.ts', // Telegram bot token lookup for connectivity check
|
|
200
|
+
'messaging/providers/sms/adapter.ts', // Twilio credential lookup for SMS connectivity check
|
|
200
201
|
]);
|
|
201
202
|
|
|
202
203
|
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { beforeEach, describe, expect, mock, test } from 'bun:test';
|
|
2
2
|
import type * as net from 'node:net';
|
|
3
3
|
|
|
4
4
|
// ── Mocks ────────────────────────────────────────────────────────────
|
|
@@ -141,7 +141,7 @@ mock.module('../daemon/session.js', () => ({
|
|
|
141
141
|
|
|
142
142
|
import { DaemonServer } from '../daemon/server.js';
|
|
143
143
|
import { SessionEvictor, type EvictableSession } from '../daemon/session-evictor.js';
|
|
144
|
-
import { createMessageParser, serialize
|
|
144
|
+
import { createMessageParser, serialize } from '../daemon/ipc-protocol.js';
|
|
145
145
|
|
|
146
146
|
// ── Test Helpers ─────────────────────────────────────────────────────
|
|
147
147
|
|
|
@@ -165,7 +165,7 @@ function internals(server: DaemonServer): DaemonServerInternals {
|
|
|
165
165
|
|
|
166
166
|
function createFakeSocket(overrides?: Partial<net.Socket>) {
|
|
167
167
|
const writes: string[] = [];
|
|
168
|
-
const
|
|
168
|
+
const base: Record<string, unknown> = {
|
|
169
169
|
destroyed: false,
|
|
170
170
|
writable: true,
|
|
171
171
|
remoteAddress: '127.0.0.1',
|
|
@@ -174,16 +174,17 @@ function createFakeSocket(overrides?: Partial<net.Socket>) {
|
|
|
174
174
|
return true;
|
|
175
175
|
},
|
|
176
176
|
destroy(): void {
|
|
177
|
-
|
|
177
|
+
base.destroyed = true;
|
|
178
178
|
},
|
|
179
179
|
on(_event: string, _handler: (...args: unknown[]) => void): unknown {
|
|
180
|
-
return
|
|
180
|
+
return socket;
|
|
181
181
|
},
|
|
182
182
|
once(_event: string, _handler: (...args: unknown[]) => void): unknown {
|
|
183
|
-
return
|
|
183
|
+
return socket;
|
|
184
184
|
},
|
|
185
185
|
...overrides,
|
|
186
|
-
}
|
|
186
|
+
};
|
|
187
|
+
const socket = base as unknown as net.Socket;
|
|
187
188
|
return { socket, writes };
|
|
188
189
|
}
|
|
189
190
|
|
|
@@ -586,7 +587,7 @@ describe('IPC protocol', () => {
|
|
|
586
587
|
const parser = createMessageParser();
|
|
587
588
|
const messages = parser.feed('{"type":"ping"}\n');
|
|
588
589
|
expect(messages).toHaveLength(1);
|
|
589
|
-
expect((messages[0] as Record<string, unknown>).type).toBe('ping');
|
|
590
|
+
expect((messages[0] as unknown as Record<string, unknown>).type).toBe('ping');
|
|
590
591
|
});
|
|
591
592
|
|
|
592
593
|
test('buffers partial messages until newline arrives', () => {
|
|
@@ -597,22 +598,22 @@ describe('IPC protocol', () => {
|
|
|
597
598
|
|
|
598
599
|
const partial2 = parser.feed('"ping"}\n');
|
|
599
600
|
expect(partial2).toHaveLength(1);
|
|
600
|
-
expect((partial2[0] as Record<string, unknown>).type).toBe('ping');
|
|
601
|
+
expect((partial2[0] as unknown as Record<string, unknown>).type).toBe('ping');
|
|
601
602
|
});
|
|
602
603
|
|
|
603
604
|
test('handles multiple messages in a single chunk', () => {
|
|
604
605
|
const parser = createMessageParser();
|
|
605
606
|
const messages = parser.feed('{"type":"ping"}\n{"type":"pong"}\n');
|
|
606
607
|
expect(messages).toHaveLength(2);
|
|
607
|
-
expect((messages[0] as Record<string, unknown>).type).toBe('ping');
|
|
608
|
-
expect((messages[1] as Record<string, unknown>).type).toBe('pong');
|
|
608
|
+
expect((messages[0] as unknown as Record<string, unknown>).type).toBe('ping');
|
|
609
|
+
expect((messages[1] as unknown as Record<string, unknown>).type).toBe('pong');
|
|
609
610
|
});
|
|
610
611
|
|
|
611
612
|
test('skips malformed JSON lines gracefully', () => {
|
|
612
613
|
const parser = createMessageParser();
|
|
613
614
|
const messages = parser.feed('not json\n{"type":"valid"}\n');
|
|
614
615
|
expect(messages).toHaveLength(1);
|
|
615
|
-
expect((messages[0] as Record<string, unknown>).type).toBe('valid');
|
|
616
|
+
expect((messages[0] as unknown as Record<string, unknown>).type).toBe('valid');
|
|
616
617
|
});
|
|
617
618
|
|
|
618
619
|
test('throws when line exceeds maxLineSize', () => {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
import type { DictationRequest } from '../daemon/ipc-protocol.js';
|
|
3
|
+
import { detectDictationMode } from '../daemon/handlers/dictation.js';
|
|
4
|
+
|
|
5
|
+
type DictationRequestOverrides = Omit<Partial<DictationRequest>, 'context'> & {
|
|
6
|
+
context?: Partial<DictationRequest['context']>;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
function makeRequest(overrides: DictationRequestOverrides = {}): DictationRequest {
|
|
10
|
+
const base: DictationRequest = {
|
|
11
|
+
type: 'dictation_request',
|
|
12
|
+
transcription: 'hello there',
|
|
13
|
+
context: {
|
|
14
|
+
bundleIdentifier: 'com.google.Chrome',
|
|
15
|
+
appName: 'Google Chrome',
|
|
16
|
+
windowTitle: 'Inbox - Gmail',
|
|
17
|
+
selectedText: undefined,
|
|
18
|
+
cursorInTextField: false,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
return {
|
|
22
|
+
...base,
|
|
23
|
+
...overrides,
|
|
24
|
+
context: {
|
|
25
|
+
...base.context,
|
|
26
|
+
...(overrides.context ?? {}),
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe('detectDictationMode', () => {
|
|
32
|
+
test('uses command mode when selected text exists', () => {
|
|
33
|
+
const mode = detectDictationMode(makeRequest({
|
|
34
|
+
transcription: 'make this friendlier',
|
|
35
|
+
context: { selectedText: 'Please send me the files.', cursorInTextField: true },
|
|
36
|
+
}));
|
|
37
|
+
expect(mode).toBe('command');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('uses action mode for action-verb utterances', () => {
|
|
41
|
+
const mode = detectDictationMode(makeRequest({
|
|
42
|
+
transcription: 'send Alex a follow up',
|
|
43
|
+
context: { selectedText: undefined, cursorInTextField: false },
|
|
44
|
+
}));
|
|
45
|
+
expect(mode).toBe('action');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('uses dictation mode when cursor is in a text field', () => {
|
|
49
|
+
const mode = detectDictationMode(makeRequest({
|
|
50
|
+
transcription: 'quick update on status',
|
|
51
|
+
context: { cursorInTextField: true },
|
|
52
|
+
}));
|
|
53
|
+
expect(mode).toBe('dictation');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('defaults to dictation when context is ambiguous', () => {
|
|
57
|
+
const mode = detectDictationMode(makeRequest({
|
|
58
|
+
transcription: 'just checking in about tomorrow',
|
|
59
|
+
context: { selectedText: undefined, cursorInTextField: false },
|
|
60
|
+
}));
|
|
61
|
+
expect(mode).toBe('dictation');
|
|
62
|
+
});
|
|
63
|
+
});
|