@vellumai/assistant 0.5.5 → 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 (102) hide show
  1. package/Dockerfile +3 -4
  2. package/package.json +1 -1
  3. package/src/__tests__/actor-token-service.test.ts +113 -0
  4. package/src/__tests__/config-schema.test.ts +2 -2
  5. package/src/__tests__/context-window-manager.test.ts +78 -0
  6. package/src/__tests__/conversation-title-service.test.ts +30 -1
  7. package/src/__tests__/docker-signing-key-bootstrap.test.ts +207 -0
  8. package/src/__tests__/memory-regressions.test.ts +8 -30
  9. package/src/__tests__/require-fresh-approval.test.ts +4 -0
  10. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -0
  11. package/src/__tests__/tool-executor.test.ts +4 -0
  12. package/src/cli/commands/conversations.ts +0 -18
  13. package/src/config/env.ts +8 -2
  14. package/src/config/feature-flag-registry.json +0 -8
  15. package/src/config/schema.ts +0 -12
  16. package/src/config/schemas/memory.ts +0 -4
  17. package/src/config/schemas/platform.ts +1 -1
  18. package/src/config/schemas/security.ts +4 -0
  19. package/src/context/window-manager.ts +53 -2
  20. package/src/daemon/config-watcher.ts +1 -4
  21. package/src/daemon/conversation-agent-loop.ts +0 -60
  22. package/src/daemon/conversation-memory.ts +0 -117
  23. package/src/daemon/conversation-runtime-assembly.ts +0 -2
  24. package/src/daemon/handlers/conversations.ts +0 -11
  25. package/src/daemon/lifecycle.ts +3 -46
  26. package/src/followups/followup-store.ts +5 -2
  27. package/src/memory/conversation-crud.ts +0 -236
  28. package/src/memory/conversation-title-service.ts +26 -10
  29. package/src/memory/db-init.ts +5 -13
  30. package/src/memory/indexer.ts +15 -106
  31. package/src/memory/job-handlers/embedding.ts +0 -79
  32. package/src/memory/job-utils.ts +1 -1
  33. package/src/memory/jobs-store.ts +0 -8
  34. package/src/memory/jobs-worker.ts +0 -20
  35. package/src/memory/migrations/189-drop-simplified-memory.ts +42 -0
  36. package/src/memory/migrations/index.ts +1 -3
  37. package/src/memory/qdrant-client.ts +4 -6
  38. package/src/memory/schema/conversations.ts +0 -3
  39. package/src/memory/schema/index.ts +0 -2
  40. package/src/messaging/draft-store.ts +2 -2
  41. package/src/permissions/defaults.ts +3 -3
  42. package/src/permissions/trust-client.ts +2 -13
  43. package/src/permissions/trust-store.ts +8 -3
  44. package/src/runtime/auth/route-policy.ts +14 -0
  45. package/src/runtime/auth/token-service.ts +133 -0
  46. package/src/runtime/http-server.ts +2 -0
  47. package/src/runtime/routes/conversation-management-routes.ts +0 -36
  48. package/src/runtime/routes/conversation-query-routes.ts +44 -2
  49. package/src/runtime/routes/conversation-routes.ts +2 -1
  50. package/src/runtime/routes/memory-item-routes.test.ts +221 -3
  51. package/src/runtime/routes/memory-item-routes.ts +124 -2
  52. package/src/runtime/routes/upgrade-broadcast-routes.ts +151 -0
  53. package/src/schedule/schedule-store.ts +0 -21
  54. package/src/skills/inline-command-render.ts +5 -1
  55. package/src/skills/inline-command-runner.ts +30 -2
  56. package/src/tools/memory/handlers.ts +1 -129
  57. package/src/tools/permission-checker.ts +18 -0
  58. package/src/tools/skills/load.ts +9 -2
  59. package/src/util/platform.ts +5 -5
  60. package/src/util/xml.ts +8 -0
  61. package/src/workspace/heartbeat-service.ts +5 -24
  62. package/src/__tests__/archive-recall.test.ts +0 -560
  63. package/src/__tests__/conversation-memory-dirty-tail.test.ts +0 -150
  64. package/src/__tests__/conversation-switch-memory-reduction.test.ts +0 -474
  65. package/src/__tests__/db-memory-archive-migration.test.ts +0 -372
  66. package/src/__tests__/db-memory-brief-state-migration.test.ts +0 -213
  67. package/src/__tests__/db-memory-reducer-checkpoints.test.ts +0 -273
  68. package/src/__tests__/memory-brief-open-loops.test.ts +0 -530
  69. package/src/__tests__/memory-brief-time.test.ts +0 -285
  70. package/src/__tests__/memory-brief-wrapper.test.ts +0 -311
  71. package/src/__tests__/memory-chunk-archive.test.ts +0 -400
  72. package/src/__tests__/memory-chunk-dual-write.test.ts +0 -453
  73. package/src/__tests__/memory-episode-archive.test.ts +0 -370
  74. package/src/__tests__/memory-episode-dual-write.test.ts +0 -626
  75. package/src/__tests__/memory-observation-archive.test.ts +0 -375
  76. package/src/__tests__/memory-observation-dual-write.test.ts +0 -318
  77. package/src/__tests__/memory-reducer-job.test.ts +0 -538
  78. package/src/__tests__/memory-reducer-scheduling.test.ts +0 -473
  79. package/src/__tests__/memory-reducer-store.test.ts +0 -728
  80. package/src/__tests__/memory-reducer-types.test.ts +0 -707
  81. package/src/__tests__/memory-reducer.test.ts +0 -704
  82. package/src/__tests__/memory-simplified-config.test.ts +0 -281
  83. package/src/__tests__/simplified-memory-e2e.test.ts +0 -666
  84. package/src/__tests__/simplified-memory-runtime.test.ts +0 -616
  85. package/src/config/schemas/memory-simplified.ts +0 -101
  86. package/src/memory/archive-recall.ts +0 -516
  87. package/src/memory/archive-store.ts +0 -400
  88. package/src/memory/brief-formatting.ts +0 -33
  89. package/src/memory/brief-open-loops.ts +0 -266
  90. package/src/memory/brief-time.ts +0 -162
  91. package/src/memory/brief.ts +0 -75
  92. package/src/memory/job-handlers/backfill-simplified-memory.ts +0 -462
  93. package/src/memory/job-handlers/reduce-conversation-memory.ts +0 -229
  94. package/src/memory/migrations/185-memory-brief-state.ts +0 -52
  95. package/src/memory/migrations/186-memory-archive.ts +0 -109
  96. package/src/memory/migrations/187-memory-reducer-checkpoints.ts +0 -19
  97. package/src/memory/reducer-scheduler.ts +0 -242
  98. package/src/memory/reducer-store.ts +0 -271
  99. package/src/memory/reducer-types.ts +0 -106
  100. package/src/memory/reducer.ts +0 -467
  101. package/src/memory/schema/memory-archive.ts +0 -121
  102. 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
- });