@vellumai/assistant 0.5.4 → 0.5.6

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.
Files changed (151) hide show
  1. package/Dockerfile +17 -27
  2. package/node_modules/@vellumai/ces-contracts/src/index.ts +1 -0
  3. package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +42 -0
  4. package/package.json +1 -1
  5. package/src/__tests__/actor-token-service.test.ts +113 -0
  6. package/src/__tests__/config-schema.test.ts +2 -2
  7. package/src/__tests__/context-window-manager.test.ts +78 -0
  8. package/src/__tests__/conversation-title-service.test.ts +30 -1
  9. package/src/__tests__/credential-security-invariants.test.ts +2 -0
  10. package/src/__tests__/docker-signing-key-bootstrap.test.ts +207 -0
  11. package/src/__tests__/memory-regressions.test.ts +8 -30
  12. package/src/__tests__/openai-whisper.test.ts +93 -0
  13. package/src/__tests__/require-fresh-approval.test.ts +4 -0
  14. package/src/__tests__/slack-messaging-token-resolution.test.ts +319 -0
  15. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -0
  16. package/src/__tests__/tool-executor.test.ts +4 -0
  17. package/src/__tests__/volume-security-guard.test.ts +155 -0
  18. package/src/cli/commands/conversations.ts +0 -18
  19. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -0
  20. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +16 -37
  21. package/src/config/env-registry.ts +9 -0
  22. package/src/config/env.ts +8 -2
  23. package/src/config/feature-flag-registry.json +8 -8
  24. package/src/config/schema.ts +0 -12
  25. package/src/config/schemas/memory.ts +0 -4
  26. package/src/config/schemas/platform.ts +1 -1
  27. package/src/config/schemas/security.ts +4 -0
  28. package/src/context/window-manager.ts +53 -2
  29. package/src/credential-execution/managed-catalog.ts +5 -15
  30. package/src/daemon/conversation-agent-loop.ts +0 -60
  31. package/src/daemon/conversation-memory.ts +0 -117
  32. package/src/daemon/conversation-runtime-assembly.ts +0 -2
  33. package/src/daemon/daemon-control.ts +7 -0
  34. package/src/daemon/handlers/conversations.ts +0 -11
  35. package/src/daemon/lifecycle.ts +10 -47
  36. package/src/daemon/providers-setup.ts +2 -1
  37. package/src/followups/followup-store.ts +5 -2
  38. package/src/hooks/manager.ts +7 -0
  39. package/src/instrument.ts +33 -1
  40. package/src/memory/conversation-crud.ts +0 -236
  41. package/src/memory/conversation-title-service.ts +26 -10
  42. package/src/memory/db-init.ts +5 -13
  43. package/src/memory/embedding-local.ts +11 -5
  44. package/src/memory/indexer.ts +15 -106
  45. package/src/memory/job-handlers/conversation-starters.ts +24 -36
  46. package/src/memory/job-handlers/embedding.ts +0 -79
  47. package/src/memory/job-utils.ts +1 -1
  48. package/src/memory/jobs-store.ts +0 -8
  49. package/src/memory/jobs-worker.ts +0 -20
  50. package/src/memory/migrations/189-drop-simplified-memory.ts +42 -0
  51. package/src/memory/migrations/index.ts +1 -3
  52. package/src/memory/qdrant-client.ts +4 -6
  53. package/src/memory/schema/conversations.ts +0 -3
  54. package/src/memory/schema/index.ts +0 -2
  55. package/src/messaging/draft-store.ts +2 -2
  56. package/src/messaging/provider.ts +9 -0
  57. package/src/messaging/providers/slack/adapter.ts +29 -2
  58. package/src/oauth/connection-resolver.test.ts +22 -18
  59. package/src/oauth/connection-resolver.ts +92 -7
  60. package/src/oauth/platform-connection.test.ts +78 -69
  61. package/src/oauth/platform-connection.ts +12 -19
  62. package/src/permissions/defaults.ts +3 -3
  63. package/src/permissions/trust-client.ts +332 -0
  64. package/src/permissions/trust-store-interface.ts +105 -0
  65. package/src/permissions/trust-store.ts +531 -39
  66. package/src/platform/client.test.ts +148 -0
  67. package/src/platform/client.ts +71 -0
  68. package/src/providers/speech-to-text/openai-whisper.test.ts +190 -0
  69. package/src/providers/speech-to-text/openai-whisper.ts +68 -0
  70. package/src/providers/speech-to-text/resolve.ts +9 -0
  71. package/src/providers/speech-to-text/types.ts +17 -0
  72. package/src/runtime/auth/route-policy.ts +14 -0
  73. package/src/runtime/auth/token-service.ts +133 -0
  74. package/src/runtime/http-server.ts +4 -2
  75. package/src/runtime/routes/conversation-management-routes.ts +0 -36
  76. package/src/runtime/routes/conversation-query-routes.ts +44 -2
  77. package/src/runtime/routes/conversation-routes.ts +2 -1
  78. package/src/runtime/routes/inbound-message-handler.ts +27 -3
  79. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +16 -1
  80. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +287 -0
  81. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +122 -0
  82. package/src/runtime/routes/log-export-routes.ts +1 -0
  83. package/src/runtime/routes/memory-item-routes.test.ts +221 -3
  84. package/src/runtime/routes/memory-item-routes.ts +124 -2
  85. package/src/runtime/routes/secret-routes.ts +4 -1
  86. package/src/runtime/routes/upgrade-broadcast-routes.ts +151 -0
  87. package/src/schedule/schedule-store.ts +0 -21
  88. package/src/security/ces-credential-client.ts +173 -0
  89. package/src/security/secure-keys.ts +65 -22
  90. package/src/signals/bash.ts +3 -0
  91. package/src/signals/cancel.ts +3 -0
  92. package/src/signals/confirm.ts +3 -0
  93. package/src/signals/conversation-undo.ts +3 -0
  94. package/src/signals/event-stream.ts +7 -0
  95. package/src/signals/shotgun.ts +3 -0
  96. package/src/signals/trust-rule.ts +3 -0
  97. package/src/skills/inline-command-render.ts +5 -1
  98. package/src/skills/inline-command-runner.ts +30 -2
  99. package/src/telemetry/usage-telemetry-reporter.test.ts +23 -36
  100. package/src/telemetry/usage-telemetry-reporter.ts +21 -19
  101. package/src/tools/memory/handlers.ts +1 -129
  102. package/src/tools/permission-checker.ts +18 -0
  103. package/src/tools/skills/load.ts +9 -2
  104. package/src/util/device-id.ts +70 -7
  105. package/src/util/logger.ts +35 -9
  106. package/src/util/platform.ts +29 -5
  107. package/src/util/xml.ts +8 -0
  108. package/src/workspace/heartbeat-service.ts +5 -24
  109. package/src/workspace/migrations/migrate-to-workspace-volume.ts +113 -0
  110. package/src/workspace/migrations/registry.ts +2 -0
  111. package/src/__tests__/archive-recall.test.ts +0 -560
  112. package/src/__tests__/conversation-memory-dirty-tail.test.ts +0 -150
  113. package/src/__tests__/conversation-switch-memory-reduction.test.ts +0 -474
  114. package/src/__tests__/db-memory-archive-migration.test.ts +0 -372
  115. package/src/__tests__/db-memory-brief-state-migration.test.ts +0 -213
  116. package/src/__tests__/db-memory-reducer-checkpoints.test.ts +0 -273
  117. package/src/__tests__/memory-brief-open-loops.test.ts +0 -530
  118. package/src/__tests__/memory-brief-time.test.ts +0 -285
  119. package/src/__tests__/memory-brief-wrapper.test.ts +0 -311
  120. package/src/__tests__/memory-chunk-archive.test.ts +0 -400
  121. package/src/__tests__/memory-chunk-dual-write.test.ts +0 -453
  122. package/src/__tests__/memory-episode-archive.test.ts +0 -370
  123. package/src/__tests__/memory-episode-dual-write.test.ts +0 -626
  124. package/src/__tests__/memory-observation-archive.test.ts +0 -375
  125. package/src/__tests__/memory-observation-dual-write.test.ts +0 -318
  126. package/src/__tests__/memory-reducer-job.test.ts +0 -538
  127. package/src/__tests__/memory-reducer-scheduling.test.ts +0 -473
  128. package/src/__tests__/memory-reducer-store.test.ts +0 -728
  129. package/src/__tests__/memory-reducer-types.test.ts +0 -707
  130. package/src/__tests__/memory-reducer.test.ts +0 -704
  131. package/src/__tests__/memory-simplified-config.test.ts +0 -281
  132. package/src/__tests__/simplified-memory-e2e.test.ts +0 -666
  133. package/src/__tests__/simplified-memory-runtime.test.ts +0 -616
  134. package/src/config/schemas/memory-simplified.ts +0 -101
  135. package/src/memory/archive-recall.ts +0 -516
  136. package/src/memory/archive-store.ts +0 -400
  137. package/src/memory/brief-formatting.ts +0 -33
  138. package/src/memory/brief-open-loops.ts +0 -266
  139. package/src/memory/brief-time.ts +0 -162
  140. package/src/memory/brief.ts +0 -75
  141. package/src/memory/job-handlers/backfill-simplified-memory.ts +0 -462
  142. package/src/memory/job-handlers/reduce-conversation-memory.ts +0 -229
  143. package/src/memory/migrations/185-memory-brief-state.ts +0 -52
  144. package/src/memory/migrations/186-memory-archive.ts +0 -109
  145. package/src/memory/migrations/187-memory-reducer-checkpoints.ts +0 -19
  146. package/src/memory/reducer-scheduler.ts +0 -242
  147. package/src/memory/reducer-store.ts +0 -271
  148. package/src/memory/reducer-types.ts +0 -106
  149. package/src/memory/reducer.ts +0 -467
  150. package/src/memory/schema/memory-archive.ts +0 -121
  151. package/src/memory/schema/memory-brief.ts +0 -55
@@ -1,281 +0,0 @@
1
- import { randomBytes } from "node:crypto";
2
- import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
- import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
6
-
7
- // ---------------------------------------------------------------------------
8
- // Mocks — declared before imports that depend on platform/logger
9
- // ---------------------------------------------------------------------------
10
-
11
- const TEST_DIR = join(
12
- tmpdir(),
13
- `vellum-simplified-mem-test-${randomBytes(4).toString("hex")}`,
14
- );
15
- const WORKSPACE_DIR = join(TEST_DIR, "workspace");
16
- const CONFIG_PATH = join(WORKSPACE_DIR, "config.json");
17
-
18
- function ensureTestDir(): void {
19
- const dirs = [
20
- TEST_DIR,
21
- WORKSPACE_DIR,
22
- join(TEST_DIR, "data"),
23
- join(TEST_DIR, "memory"),
24
- join(TEST_DIR, "memory", "knowledge"),
25
- join(TEST_DIR, "logs"),
26
- ];
27
- for (const dir of dirs) {
28
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
29
- }
30
- }
31
-
32
- function makeLoggerStub(): Record<string, unknown> {
33
- const stub: Record<string, unknown> = {};
34
- for (const m of [
35
- "info",
36
- "warn",
37
- "error",
38
- "debug",
39
- "trace",
40
- "fatal",
41
- "silent",
42
- "child",
43
- ]) {
44
- stub[m] = m === "child" ? () => makeLoggerStub() : () => {};
45
- }
46
- return stub;
47
- }
48
-
49
- mock.module("../util/logger.js", () => ({
50
- getLogger: () => makeLoggerStub(),
51
- }));
52
-
53
- mock.module("../util/platform.js", () => ({
54
- getRootDir: () => TEST_DIR,
55
- getWorkspaceDir: () => WORKSPACE_DIR,
56
- getWorkspaceConfigPath: () => CONFIG_PATH,
57
- getDataDir: () => join(TEST_DIR, "data"),
58
- getLogPath: () => join(TEST_DIR, "logs", "vellum.log"),
59
- ensureDataDir: () => ensureTestDir(),
60
- isMacOS: () => false,
61
- isLinux: () => false,
62
- isWindows: () => false,
63
- }));
64
-
65
- import { invalidateConfigCache, loadConfig } from "../config/loader.js";
66
- import { AssistantConfigSchema } from "../config/schema.js";
67
- import { MemorySimplifiedConfigSchema } from "../config/schemas/memory-simplified.js";
68
- import { _setStorePath } from "../security/encrypted-store.js";
69
-
70
- // ---------------------------------------------------------------------------
71
- // Helpers
72
- // ---------------------------------------------------------------------------
73
-
74
- function writeConfig(obj: unknown): void {
75
- writeFileSync(CONFIG_PATH, JSON.stringify(obj));
76
- }
77
-
78
- // ---------------------------------------------------------------------------
79
- // Tests: MemorySimplifiedConfigSchema (unit)
80
- // ---------------------------------------------------------------------------
81
-
82
- describe("MemorySimplifiedConfigSchema", () => {
83
- test("parses empty object with all defaults", () => {
84
- const result = MemorySimplifiedConfigSchema.parse({});
85
- expect(result).toEqual({
86
- enabled: true,
87
- brief: { maxTokens: 4000 },
88
- reducer: { idleDelayMs: 30_000, switchWaitMs: 5_000 },
89
- archiveRecall: { maxSnippets: 10 },
90
- });
91
- });
92
-
93
- test("accepts explicit enabled=true", () => {
94
- const result = MemorySimplifiedConfigSchema.parse({ enabled: true });
95
- expect(result.enabled).toBe(true);
96
- });
97
-
98
- test("accepts custom brief.maxTokens", () => {
99
- const result = MemorySimplifiedConfigSchema.parse({
100
- brief: { maxTokens: 8000 },
101
- });
102
- expect(result.brief.maxTokens).toBe(8000);
103
- });
104
-
105
- test("accepts custom reducer values", () => {
106
- const result = MemorySimplifiedConfigSchema.parse({
107
- reducer: { idleDelayMs: 60_000, switchWaitMs: 10_000 },
108
- });
109
- expect(result.reducer.idleDelayMs).toBe(60_000);
110
- expect(result.reducer.switchWaitMs).toBe(10_000);
111
- });
112
-
113
- test("accepts custom archiveRecall.maxSnippets", () => {
114
- const result = MemorySimplifiedConfigSchema.parse({
115
- archiveRecall: { maxSnippets: 20 },
116
- });
117
- expect(result.archiveRecall.maxSnippets).toBe(20);
118
- });
119
-
120
- test("rejects non-boolean enabled", () => {
121
- const result = MemorySimplifiedConfigSchema.safeParse({
122
- enabled: "yes",
123
- });
124
- expect(result.success).toBe(false);
125
- });
126
-
127
- test("rejects non-positive brief.maxTokens", () => {
128
- const result = MemorySimplifiedConfigSchema.safeParse({
129
- brief: { maxTokens: 0 },
130
- });
131
- expect(result.success).toBe(false);
132
- });
133
-
134
- test("rejects non-integer brief.maxTokens", () => {
135
- const result = MemorySimplifiedConfigSchema.safeParse({
136
- brief: { maxTokens: 3.5 },
137
- });
138
- expect(result.success).toBe(false);
139
- });
140
-
141
- test("rejects non-positive reducer.idleDelayMs", () => {
142
- const result = MemorySimplifiedConfigSchema.safeParse({
143
- reducer: { idleDelayMs: 0 },
144
- });
145
- expect(result.success).toBe(false);
146
- });
147
-
148
- test("rejects non-positive reducer.switchWaitMs", () => {
149
- const result = MemorySimplifiedConfigSchema.safeParse({
150
- reducer: { switchWaitMs: -1 },
151
- });
152
- expect(result.success).toBe(false);
153
- });
154
-
155
- test("rejects non-positive archiveRecall.maxSnippets", () => {
156
- const result = MemorySimplifiedConfigSchema.safeParse({
157
- archiveRecall: { maxSnippets: 0 },
158
- });
159
- expect(result.success).toBe(false);
160
- });
161
-
162
- test("rejects non-integer archiveRecall.maxSnippets", () => {
163
- const result = MemorySimplifiedConfigSchema.safeParse({
164
- archiveRecall: { maxSnippets: 2.5 },
165
- });
166
- expect(result.success).toBe(false);
167
- });
168
- });
169
-
170
- // ---------------------------------------------------------------------------
171
- // Tests: Wired into AssistantConfigSchema
172
- // ---------------------------------------------------------------------------
173
-
174
- describe("AssistantConfigSchema memory.simplified", () => {
175
- test("empty config exposes memory.simplified with defaults", () => {
176
- const result = AssistantConfigSchema.parse({});
177
- expect(result.memory.simplified).toEqual({
178
- enabled: true,
179
- brief: { maxTokens: 4000 },
180
- reducer: { idleDelayMs: 30_000, switchWaitMs: 5_000 },
181
- archiveRecall: { maxSnippets: 10 },
182
- });
183
- });
184
-
185
- test("memory.simplified does not disturb legacy memory config", () => {
186
- const result = AssistantConfigSchema.parse({});
187
- // Legacy fields still present with their defaults
188
- expect(result.memory.enabled).toBe(true);
189
- expect(result.memory.retrieval).toBeDefined();
190
- expect(result.memory.jobs).toBeDefined();
191
- expect(result.memory.cleanup).toBeDefined();
192
- expect(result.memory.extraction).toBeDefined();
193
- expect(result.memory.summarization).toBeDefined();
194
- expect(result.memory.segmentation).toBeDefined();
195
- expect(result.memory.embeddings).toBeDefined();
196
- expect(result.memory.qdrant).toBeDefined();
197
- expect(result.memory.retention).toBeDefined();
198
- });
199
-
200
- test("accepts memory.simplified overrides alongside legacy config", () => {
201
- const result = AssistantConfigSchema.parse({
202
- memory: {
203
- enabled: true,
204
- simplified: {
205
- enabled: true,
206
- brief: { maxTokens: 6000 },
207
- },
208
- },
209
- });
210
- expect(result.memory.enabled).toBe(true);
211
- expect(result.memory.simplified.enabled).toBe(true);
212
- expect(result.memory.simplified.brief.maxTokens).toBe(6000);
213
- // Defaults preserved for unset simplified fields
214
- expect(result.memory.simplified.reducer.idleDelayMs).toBe(30_000);
215
- expect(result.memory.simplified.archiveRecall.maxSnippets).toBe(10);
216
- });
217
- });
218
-
219
- // ---------------------------------------------------------------------------
220
- // Tests: loadConfig integration (empty config file loads cleanly)
221
- // ---------------------------------------------------------------------------
222
-
223
- describe("loadConfig with memory.simplified", () => {
224
- beforeEach(() => {
225
- ensureTestDir();
226
- const resetPaths = [
227
- CONFIG_PATH,
228
- join(TEST_DIR, "keys.enc"),
229
- join(TEST_DIR, "data"),
230
- join(TEST_DIR, "memory"),
231
- ];
232
- for (const path of resetPaths) {
233
- if (existsSync(path)) {
234
- rmSync(path, { recursive: true, force: true });
235
- }
236
- }
237
- ensureTestDir();
238
- _setStorePath(join(TEST_DIR, "keys.enc"));
239
- invalidateConfigCache();
240
- });
241
-
242
- afterEach(() => {
243
- _setStorePath(null);
244
- invalidateConfigCache();
245
- });
246
-
247
- test("empty config file loads cleanly with simplified defaults", () => {
248
- writeConfig({});
249
- const config = loadConfig();
250
- expect(config.memory.simplified).toEqual({
251
- enabled: true,
252
- brief: { maxTokens: 4000 },
253
- reducer: { idleDelayMs: 30_000, switchWaitMs: 5_000 },
254
- archiveRecall: { maxSnippets: 10 },
255
- });
256
- });
257
-
258
- test("no config file loads cleanly with simplified defaults", () => {
259
- const config = loadConfig();
260
- expect(config.memory.simplified).toEqual({
261
- enabled: true,
262
- brief: { maxTokens: 4000 },
263
- reducer: { idleDelayMs: 30_000, switchWaitMs: 5_000 },
264
- archiveRecall: { maxSnippets: 10 },
265
- });
266
- });
267
-
268
- test("existing memory config with simplified addition loads cleanly", () => {
269
- writeConfig({
270
- memory: {
271
- enabled: true,
272
- simplified: { enabled: true, brief: { maxTokens: 2000 } },
273
- },
274
- });
275
- const config = loadConfig();
276
- expect(config.memory.enabled).toBe(true);
277
- expect(config.memory.simplified.enabled).toBe(true);
278
- expect(config.memory.simplified.brief.maxTokens).toBe(2000);
279
- expect(config.memory.simplified.reducer.idleDelayMs).toBe(30_000);
280
- });
281
- });