@vellumai/assistant 0.5.15 → 0.5.16

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 (175) hide show
  1. package/ARCHITECTURE.md +2 -2
  2. package/docs/architecture/integrations.md +15 -14
  3. package/knip.json +3 -1
  4. package/openapi.yaml +11 -43
  5. package/package.json +1 -1
  6. package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -375
  7. package/src/__tests__/ces-rpc-credential-backend.test.ts +4 -1
  8. package/src/__tests__/checker.test.ts +59 -0
  9. package/src/__tests__/cli-command-risk-guard.test.ts +98 -10
  10. package/src/__tests__/cli-memory.test.ts +372 -0
  11. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -2
  12. package/src/__tests__/config-schema.test.ts +0 -2
  13. package/src/__tests__/config-watcher-feature-flags.test.ts +211 -0
  14. package/src/__tests__/conversation-runtime-assembly.test.ts +7 -4
  15. package/src/__tests__/conversation-slash-commands.test.ts +2 -6
  16. package/src/__tests__/conversation-usage.test.ts +1 -0
  17. package/src/__tests__/credential-security-e2e.test.ts +4 -1
  18. package/src/__tests__/docker-signing-key-bootstrap.test.ts +7 -73
  19. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -7
  20. package/src/__tests__/guardian-routing-invariants.test.ts +151 -0
  21. package/src/__tests__/heartbeat-service.test.ts +1 -3
  22. package/src/__tests__/intent-routing.test.ts +6 -18
  23. package/src/__tests__/log-export-workspace.test.ts +2 -28
  24. package/src/__tests__/managed-skill-lifecycle.test.ts +7 -37
  25. package/src/__tests__/managed-store.test.ts +2 -10
  26. package/src/__tests__/messaging-send-tool.test.ts +6 -6
  27. package/src/__tests__/migration-cross-version-compatibility.test.ts +1 -29
  28. package/src/__tests__/migration-export-http.test.ts +3 -34
  29. package/src/__tests__/migration-import-commit-http.test.ts +1 -29
  30. package/src/__tests__/migration-import-preflight-http.test.ts +3 -34
  31. package/src/__tests__/no-domain-routing-in-prompt-guard.test.ts +2 -1
  32. package/src/__tests__/oauth-apps-routes.test.ts +120 -10
  33. package/src/__tests__/oauth-connect-orchestrator.test.ts +709 -0
  34. package/src/__tests__/oauth-provider-serializer.test.ts +2 -1
  35. package/src/__tests__/oauth-provider-visibility.test.ts +149 -0
  36. package/src/__tests__/oauth-providers-routes.test.ts +5 -2
  37. package/src/__tests__/oauth-store.test.ts +0 -5
  38. package/src/__tests__/outlook-messaging-provider.test.ts +576 -0
  39. package/src/__tests__/path-policy.test.ts +2 -17
  40. package/src/__tests__/permission-types.test.ts +0 -1
  41. package/src/__tests__/platform-callback-registration.test.ts +3 -7
  42. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  43. package/src/__tests__/provider-error-scenarios.test.ts +0 -2
  44. package/src/__tests__/qdrant-manager.test.ts +68 -21
  45. package/src/__tests__/require-fresh-approval.test.ts +0 -1
  46. package/src/__tests__/sandbox-diagnostics.test.ts +20 -29
  47. package/src/__tests__/scaffold-managed-skill-tool.test.ts +2 -10
  48. package/src/__tests__/secret-allowlist.test.ts +20 -35
  49. package/src/__tests__/shell-credential-ref.test.ts +0 -5
  50. package/src/__tests__/skill-load-feature-flag.test.ts +2 -43
  51. package/src/__tests__/skill-load-inline-command.test.ts +3 -65
  52. package/src/__tests__/skill-load-inline-includes.test.ts +3 -65
  53. package/src/__tests__/skill-load-tool.test.ts +3 -67
  54. package/src/__tests__/skill-memory.test.ts +362 -119
  55. package/src/__tests__/skills.test.ts +22 -49
  56. package/src/__tests__/slack-channel-config.test.ts +2 -21
  57. package/src/__tests__/starter-bundle.test.ts +2 -8
  58. package/src/__tests__/stt-hints.test.ts +7 -2
  59. package/src/__tests__/system-prompt.test.ts +25 -45
  60. package/src/__tests__/task-compiler.test.ts +0 -21
  61. package/src/__tests__/task-management-tools.test.ts +0 -21
  62. package/src/__tests__/task-memory-cleanup.test.ts +0 -21
  63. package/src/__tests__/task-runner.test.ts +0 -21
  64. package/src/__tests__/task-scheduler.test.ts +0 -21
  65. package/src/__tests__/terminal-tools.test.ts +1 -17
  66. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +0 -79
  67. package/src/__tests__/tool-approval-handler.test.ts +1 -20
  68. package/src/__tests__/tool-execution-abort-cleanup.test.ts +2 -11
  69. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -25
  70. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  71. package/src/__tests__/tool-executor.test.ts +0 -1
  72. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -20
  73. package/src/__tests__/tool-preview-lifecycle.test.ts +0 -20
  74. package/src/__tests__/trust-store.test.ts +9 -41
  75. package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -30
  76. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -21
  77. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -22
  78. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -22
  79. package/src/__tests__/trusted-contact-verification.test.ts +0 -22
  80. package/src/__tests__/turn-boundary-resolution.test.ts +0 -28
  81. package/src/__tests__/twilio-provider.test.ts +0 -16
  82. package/src/__tests__/twilio-routes-twiml.test.ts +7 -12
  83. package/src/__tests__/twilio-routes.test.ts +0 -24
  84. package/src/__tests__/update-bulletin.test.ts +17 -89
  85. package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -20
  86. package/src/__tests__/usage-routes.test.ts +0 -21
  87. package/src/__tests__/user-reference.test.ts +1 -5
  88. package/src/__tests__/vbundle-pax-and-symlink.test.ts +4 -34
  89. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +2 -53
  90. package/src/__tests__/voice-invite-redemption.test.ts +0 -21
  91. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -24
  92. package/src/__tests__/voice-session-bridge.test.ts +0 -21
  93. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -23
  94. package/src/__tests__/workspace-migration-012-rename-conversation-disk-view-dirs.test.ts +2 -2
  95. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -23
  96. package/src/__tests__/workspace-migration-down-functions.test.ts +0 -6
  97. package/src/acp/client-handler.ts +1 -2
  98. package/src/cli/__tests__/notifications.test.ts +0 -22
  99. package/src/cli/cli-memory.ts +176 -0
  100. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
  101. package/src/cli/commands/oauth/connect.ts +15 -0
  102. package/src/cli/commands/oauth/providers.ts +49 -42
  103. package/src/cli/commands/platform/__tests__/connect.test.ts +2 -48
  104. package/src/cli/commands/platform/__tests__/disconnect.test.ts +2 -48
  105. package/src/cli/commands/platform/__tests__/status.test.ts +0 -50
  106. package/src/config/bundled-skills/computer-use/TOOLS.json +7 -7
  107. package/src/config/bundled-skills/messaging/SKILL.md +17 -2
  108. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  109. package/src/config/feature-flag-registry.json +16 -0
  110. package/src/config/loader.ts +4 -0
  111. package/src/config/schemas/security.ts +0 -6
  112. package/src/config/schemas/services.ts +8 -0
  113. package/src/context/window-manager.ts +28 -9
  114. package/src/credential-execution/approval-bridge.ts +0 -1
  115. package/src/daemon/config-watcher.ts +51 -0
  116. package/src/daemon/conversation-agent-loop.ts +3 -2
  117. package/src/daemon/conversation-process.ts +1 -0
  118. package/src/daemon/conversation-usage.ts +1 -0
  119. package/src/daemon/handlers/skills.ts +9 -1
  120. package/src/daemon/lifecycle.ts +13 -4
  121. package/src/daemon/message-types/conversations.ts +1 -0
  122. package/src/daemon/providers-setup.ts +2 -0
  123. package/src/daemon/server.ts +26 -22
  124. package/src/events/domain-events.ts +1 -2
  125. package/src/memory/db-init.ts +9 -0
  126. package/src/memory/job-handlers/batch-extraction.ts +16 -4
  127. package/src/memory/job-handlers/embedding.test.ts +3 -27
  128. package/src/memory/job-handlers/journal-carry-forward.test.ts +1 -29
  129. package/src/memory/llm-usage-store.ts +35 -2
  130. package/src/memory/migrations/201-oauth-providers-feature-flag.ts +11 -0
  131. package/src/memory/migrations/202-drop-callback-transport-column.ts +13 -0
  132. package/src/memory/migrations/index.ts +2 -0
  133. package/src/memory/qdrant-manager.ts +26 -5
  134. package/src/memory/query-expansion.ts +1 -1
  135. package/src/memory/retriever.test.ts +22 -20
  136. package/src/memory/retriever.ts +10 -2
  137. package/src/memory/schema/oauth.ts +1 -1
  138. package/src/memory/search/mmr.ts +8 -5
  139. package/src/memory/slack-thread-store.ts +17 -0
  140. package/src/messaging/providers/outlook/adapter.ts +193 -0
  141. package/src/messaging/providers/outlook/client.ts +311 -0
  142. package/src/messaging/providers/outlook/types.ts +83 -0
  143. package/src/notifications/adapters/slack.ts +1 -1
  144. package/src/oauth/__tests__/identity-verifier.test.ts +1 -1
  145. package/src/oauth/connect-orchestrator.ts +10 -3
  146. package/src/oauth/oauth-store.ts +10 -11
  147. package/src/oauth/provider-serializer.ts +3 -0
  148. package/src/oauth/provider-visibility.ts +16 -0
  149. package/src/oauth/seed-providers.ts +49 -17
  150. package/src/permissions/checker.ts +39 -7
  151. package/src/permissions/types.ts +2 -4
  152. package/src/prompts/journal-context.ts +9 -11
  153. package/src/prompts/system-prompt.ts +3 -64
  154. package/src/prompts/templates/UPDATES.md +6 -0
  155. package/src/runtime/auth/__tests__/credential-service.test.ts +1 -27
  156. package/src/runtime/auth/__tests__/token-service.test.ts +1 -25
  157. package/src/runtime/auth/route-policy.ts +0 -4
  158. package/src/runtime/guardian-reply-router.ts +6 -2
  159. package/src/runtime/routes/conversation-query-routes.ts +2 -58
  160. package/src/runtime/routes/inbound-stages/background-dispatch.ts +43 -2
  161. package/src/runtime/routes/memory-item-routes.test.ts +0 -17
  162. package/src/runtime/routes/memory-item-routes.ts +103 -12
  163. package/src/runtime/routes/oauth-apps.ts +18 -1
  164. package/src/runtime/routes/oauth-providers.ts +13 -1
  165. package/src/runtime/routes/settings-routes.ts +1 -0
  166. package/src/runtime/routes/usage-routes.ts +19 -2
  167. package/src/runtime/routes/work-items-routes.test.ts +0 -21
  168. package/src/runtime/routes/workspace-routes.test.ts +3 -27
  169. package/src/security/secret-allowlist.ts +4 -4
  170. package/src/skills/skill-memory.ts +62 -23
  171. package/src/tools/memory/handlers.test.ts +1 -29
  172. package/src/tools/permission-checker.ts +0 -18
  173. package/src/tools/skills/skill-script-runner.ts +1 -1
  174. package/src/util/device-id.ts +3 -65
  175. package/src/workspace/git-service.ts +27 -6
@@ -19,7 +19,6 @@ function makeRow(overrides: Partial<OAuthProviderRow> = {}): OAuthProviderRow {
19
19
  defaultScopes: "[]",
20
20
  scopePolicy: "{}",
21
21
  extraParams: null,
22
- callbackTransport: null,
23
22
  pingUrl: null,
24
23
  pingMethod: null,
25
24
  pingHeaders: null,
@@ -41,6 +40,7 @@ function makeRow(overrides: Partial<OAuthProviderRow> = {}): OAuthProviderRow {
41
40
  identityResponsePaths: null,
42
41
  identityFormat: null,
43
42
  identityOkField: null,
43
+ featureFlag: null,
44
44
  createdAt: now,
45
45
  updatedAt: now,
46
46
  ...overrides,
@@ -191,6 +191,7 @@ describe("serializeProviderSummary", () => {
191
191
  client_id_placeholder: "your-client-id.apps.googleusercontent.com",
192
192
  requires_client_secret: true,
193
193
  supports_managed_mode: true,
194
+ feature_flag: null,
194
195
  });
195
196
  });
196
197
 
@@ -0,0 +1,149 @@
1
+ import {
2
+ afterAll,
3
+ afterEach,
4
+ beforeEach,
5
+ describe,
6
+ expect,
7
+ mock,
8
+ test,
9
+ } from "bun:test";
10
+
11
+ mock.module("../util/logger.js", () => ({
12
+ getLogger: () =>
13
+ new Proxy({} as Record<string, unknown>, {
14
+ get: () => () => {},
15
+ }),
16
+ }));
17
+
18
+ mock.module("../security/secure-keys.js", () => ({
19
+ deleteSecureKeyAsync: () => Promise.resolve("deleted" as const),
20
+ setSecureKeyAsync: () => Promise.resolve(true),
21
+ getSecureKeyAsync: () => Promise.resolve(undefined),
22
+ }));
23
+
24
+ import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
25
+ import type { AssistantConfig } from "../config/schema.js";
26
+ import { initializeDb, resetDb, resetTestTables } from "../memory/db.js";
27
+ import { listProviders, seedProviders } from "../oauth/oauth-store.js";
28
+ import { isProviderVisible } from "../oauth/provider-visibility.js";
29
+
30
+ initializeDb();
31
+
32
+ /** Create a minimal AssistantConfig for testing. */
33
+ function makeConfig(): AssistantConfig {
34
+ return {} as AssistantConfig;
35
+ }
36
+
37
+ beforeEach(() => {
38
+ resetTestTables("oauth_connections", "oauth_apps", "oauth_providers");
39
+ _setOverridesForTesting({});
40
+ });
41
+
42
+ afterEach(() => {
43
+ _setOverridesForTesting({});
44
+ });
45
+
46
+ afterAll(() => {
47
+ resetDb();
48
+ });
49
+
50
+ describe("isProviderVisible", () => {
51
+ test("returns true when featureFlag is null", () => {
52
+ seedProviders([
53
+ {
54
+ providerKey: "no-flag-provider",
55
+ authUrl: "https://example.com/auth",
56
+ tokenUrl: "https://example.com/token",
57
+ defaultScopes: ["read"],
58
+ scopePolicy: {},
59
+ },
60
+ ]);
61
+
62
+ const providers = listProviders();
63
+ const provider = providers.find(
64
+ (p) => p.providerKey === "no-flag-provider",
65
+ );
66
+ expect(provider).toBeDefined();
67
+ expect(provider!.featureFlag).toBeNull();
68
+
69
+ const config = makeConfig();
70
+ expect(isProviderVisible(provider!, config)).toBe(true);
71
+ });
72
+
73
+ test("returns true when featureFlag is set and the flag is enabled", () => {
74
+ _setOverridesForTesting({ "test-gate": true });
75
+
76
+ seedProviders([
77
+ {
78
+ providerKey: "gated-provider",
79
+ authUrl: "https://example.com/auth",
80
+ tokenUrl: "https://example.com/token",
81
+ defaultScopes: ["read"],
82
+ scopePolicy: {},
83
+ featureFlag: "test-gate",
84
+ },
85
+ ]);
86
+
87
+ const providers = listProviders();
88
+ const provider = providers.find((p) => p.providerKey === "gated-provider");
89
+ expect(provider).toBeDefined();
90
+ expect(provider!.featureFlag).toBe("test-gate");
91
+
92
+ const config = makeConfig();
93
+ expect(isProviderVisible(provider!, config)).toBe(true);
94
+ });
95
+
96
+ test("returns false when featureFlag is set and the flag is disabled", () => {
97
+ _setOverridesForTesting({ "test-gate": false });
98
+
99
+ seedProviders([
100
+ {
101
+ providerKey: "gated-provider",
102
+ authUrl: "https://example.com/auth",
103
+ tokenUrl: "https://example.com/token",
104
+ defaultScopes: ["read"],
105
+ scopePolicy: {},
106
+ featureFlag: "test-gate",
107
+ },
108
+ ]);
109
+
110
+ const providers = listProviders();
111
+ const provider = providers.find((p) => p.providerKey === "gated-provider");
112
+ expect(provider).toBeDefined();
113
+
114
+ const config = makeConfig();
115
+ expect(isProviderVisible(provider!, config)).toBe(false);
116
+ });
117
+
118
+ test("listProviders returns all providers but isProviderVisible filters gated ones when flag is disabled", () => {
119
+ _setOverridesForTesting({ "test-gate": false });
120
+
121
+ seedProviders([
122
+ {
123
+ providerKey: "visible-provider",
124
+ authUrl: "https://example.com/auth",
125
+ tokenUrl: "https://example.com/token",
126
+ defaultScopes: ["read"],
127
+ scopePolicy: {},
128
+ },
129
+ {
130
+ providerKey: "gated-provider",
131
+ authUrl: "https://gated.example.com/auth",
132
+ tokenUrl: "https://gated.example.com/token",
133
+ defaultScopes: ["read"],
134
+ scopePolicy: {},
135
+ featureFlag: "test-gate",
136
+ },
137
+ ]);
138
+
139
+ const allProviders = listProviders();
140
+ expect(allProviders).toHaveLength(2);
141
+
142
+ const config = makeConfig();
143
+ const visibleProviders = allProviders.filter((p) =>
144
+ isProviderVisible(p, config),
145
+ );
146
+ expect(visibleProviders).toHaveLength(1);
147
+ expect(visibleProviders[0]!.providerKey).toBe("visible-provider");
148
+ });
149
+ });
@@ -17,7 +17,7 @@ const mockListProviders = mock(() => [
17
17
  defaultScopes: "[]",
18
18
  scopePolicy: "[]",
19
19
  extraParams: null,
20
- callbackTransport: null,
20
+
21
21
  pingUrl: null,
22
22
  pingMethod: null,
23
23
  pingHeaders: null,
@@ -33,6 +33,7 @@ const mockListProviders = mock(() => [
33
33
  identityFormat: null,
34
34
  identityOkField: null,
35
35
  identityResponsePaths: null,
36
+ featureFlag: null,
36
37
  createdAt: 1735689500000,
37
38
  updatedAt: 1735689550000,
38
39
  },
@@ -52,7 +53,7 @@ const mockListProviders = mock(() => [
52
53
  defaultScopes: "[]",
53
54
  scopePolicy: "[]",
54
55
  extraParams: null,
55
- callbackTransport: null,
56
+
56
57
  pingUrl: null,
57
58
  pingMethod: null,
58
59
  pingHeaders: null,
@@ -68,6 +69,7 @@ const mockListProviders = mock(() => [
68
69
  identityFormat: null,
69
70
  identityOkField: null,
70
71
  identityResponsePaths: null,
72
+ featureFlag: null,
71
73
  createdAt: 1735689600000,
72
74
  updatedAt: 1735689650000,
73
75
  },
@@ -148,6 +150,7 @@ describe("GET /v1/oauth/providers", () => {
148
150
  "client_id_placeholder",
149
151
  "requires_client_secret",
150
152
  "supports_managed_mode",
153
+ "feature_flag",
151
154
  ];
152
155
 
153
156
  for (const provider of body.providers) {
@@ -208,7 +208,6 @@ describe("provider operations", () => {
208
208
  userinfoUrl: "https://api.github.com/user",
209
209
  baseUrl: "https://api.github.com",
210
210
  extraParams: { prompt: "consent" },
211
- callbackTransport: "loopback",
212
211
 
213
212
  pingUrl: "https://api.github.com/user",
214
213
  },
@@ -249,7 +248,6 @@ describe("provider operations", () => {
249
248
  userinfoUrl: "https://api.github.com/user-v2",
250
249
  baseUrl: "https://api.github.com/v2",
251
250
  extraParams: { prompt: "login" },
252
- callbackTransport: "gateway",
253
251
 
254
252
  pingUrl: "https://api.github.com/user-v2",
255
253
  },
@@ -272,7 +270,6 @@ describe("provider operations", () => {
272
270
  expect(row!.tokenEndpointAuthMethod).toBe("client_secret_basic");
273
271
  expect(row!.userinfoUrl).toBe("https://api.github.com/user-v2");
274
272
  expect(JSON.parse(row!.extraParams!)).toEqual({ prompt: "login" });
275
- expect(row!.callbackTransport).toBe("gateway");
276
273
  expect(row!.pingUrl).toBe("https://api.github.com/user-v2");
277
274
  });
278
275
  });
@@ -286,14 +283,12 @@ describe("provider operations", () => {
286
283
  tokenUrl: "https://github.com/token",
287
284
  defaultScopes: ["repo"],
288
285
  scopePolicy: {},
289
- callbackTransport: "loopback",
290
286
  },
291
287
  ]);
292
288
 
293
289
  const row = getProvider("github");
294
290
  expect(row).toBeDefined();
295
291
  expect(row!.providerKey).toBe("github");
296
- expect(row!.callbackTransport).toBe("loopback");
297
292
  });
298
293
 
299
294
  test("returns undefined for unknown keys", () => {