@vellumai/assistant 0.4.31 → 0.4.33
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 +1 -1
- package/docs/architecture/memory.md +1 -1
- package/package.json +1 -1
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -7
- package/src/__tests__/access-request-decision.test.ts +83 -1
- package/src/__tests__/actor-token-service.test.ts +0 -1
- package/src/__tests__/anthropic-provider.test.ts +86 -1
- package/src/__tests__/approval-routes-http.test.ts +0 -1
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/call-routes-http.test.ts +0 -1
- package/src/__tests__/channel-guardian.test.ts +0 -1
- package/src/__tests__/channel-invite-transport.test.ts +52 -40
- package/src/__tests__/checker.test.ts +37 -98
- package/src/__tests__/commit-message-enrichment-service.test.ts +4 -23
- package/src/__tests__/computer-use-session-working-dir.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +6 -5
- package/src/__tests__/credential-security-invariants.test.ts +2 -0
- package/src/__tests__/daemon-server-session-init.test.ts +1 -19
- package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
- package/src/__tests__/followup-tools.test.ts +0 -30
- package/src/__tests__/gemini-provider.test.ts +79 -1
- package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +0 -1
- package/src/__tests__/handlers-telegram-config.test.ts +0 -1
- package/src/__tests__/inbound-invite-redemption.test.ts +1 -4
- package/src/__tests__/ingress-reconcile.test.ts +3 -36
- package/src/__tests__/ipc-snapshot.test.ts +0 -4
- package/src/__tests__/managed-proxy-context.test.ts +163 -0
- package/src/__tests__/memory-lifecycle-e2e.test.ts +2 -2
- package/src/__tests__/memory-regressions.test.ts +6 -6
- package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1
- package/src/__tests__/migration-export-http.test.ts +0 -1
- package/src/__tests__/migration-import-commit-http.test.ts +0 -1
- package/src/__tests__/migration-import-preflight-http.test.ts +0 -1
- package/src/__tests__/migration-validate-http.test.ts +0 -1
- package/src/__tests__/non-member-access-request.test.ts +0 -1
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/notification-telegram-adapter.test.ts +0 -4
- package/src/__tests__/openai-provider.test.ts +82 -0
- package/src/__tests__/provider-fail-open-selection.test.ts +134 -1
- package/src/__tests__/provider-managed-proxy-integration.test.ts +269 -0
- package/src/__tests__/recurrence-types.test.ts +0 -15
- package/src/__tests__/relay-server.test.ts +145 -2
- package/src/__tests__/sandbox-host-parity.test.ts +5 -2
- package/src/__tests__/schedule-tools.test.ts +28 -44
- package/src/__tests__/session-init.benchmark.test.ts +0 -2
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/slack-channel-config.test.ts +0 -1
- package/src/__tests__/slack-inbound-verification.test.ts +0 -1
- package/src/__tests__/sms-messaging-provider.test.ts +0 -4
- package/src/__tests__/task-management-tools.test.ts +111 -0
- package/src/__tests__/terminal-tools.test.ts +5 -2
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +66 -74
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/trusted-contact-verification.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +0 -3
- package/src/__tests__/twilio-routes.test.ts +0 -1
- package/src/__tests__/update-bulletin.test.ts +0 -2
- package/src/__tests__/user-reference.test.ts +47 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/__tests__/workspace-git-service.test.ts +2 -2
- package/src/amazon/session.ts +30 -91
- package/src/calls/call-controller.ts +423 -571
- package/src/calls/finalize-call.ts +20 -0
- package/src/calls/relay-access-wait.ts +340 -0
- package/src/calls/relay-server.ts +271 -956
- package/src/calls/relay-setup-router.ts +307 -0
- package/src/calls/relay-verification.ts +280 -0
- package/src/calls/twilio-config.ts +1 -8
- package/src/calls/voice-control-protocol.ts +184 -0
- package/src/calls/voice-session-bridge.ts +1 -8
- package/src/channels/config.ts +41 -2
- package/src/config/agent-schema.ts +1 -1
- package/src/config/bundled-skills/followups/TOOLS.json +0 -4
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -10
- package/src/config/bundled-skills/slack/SKILL.md +2 -0
- package/src/config/bundled-skills/slack-digest-setup/SKILL.md +164 -0
- package/src/config/core-schema.ts +1 -1
- package/src/config/env.ts +0 -14
- package/src/config/feature-flag-registry.json +5 -5
- package/src/config/loader.ts +19 -0
- package/src/config/schema.ts +2 -2
- package/src/config/user-reference.ts +47 -9
- package/src/daemon/handlers/config-channels.ts +11 -10
- package/src/daemon/handlers/contacts.ts +5 -1
- package/src/daemon/handlers/session-history.ts +398 -0
- package/src/daemon/handlers/session-user-message.ts +982 -0
- package/src/daemon/handlers/sessions.ts +9 -1338
- package/src/daemon/ipc-contract/sessions.ts +0 -6
- package/src/daemon/ipc-contract-inventory.json +0 -1
- package/src/daemon/lifecycle.ts +18 -55
- package/src/home-base/app-link-store.ts +0 -7
- package/src/memory/channel-delivery-store.ts +1 -0
- package/src/memory/conversation-attention-store.ts +1 -1
- package/src/memory/conversation-store.ts +0 -51
- package/src/memory/db-init.ts +9 -1
- package/src/memory/delivery-crud.ts +13 -0
- package/src/memory/invite-store.ts +71 -1
- package/src/memory/job-handlers/conflict.ts +24 -0
- package/src/memory/migrations/040-invite-code-hash-column.ts +16 -0
- package/src/memory/migrations/105-contacts-and-triage.ts +4 -7
- package/src/memory/migrations/134-contacts-notes-column.ts +50 -33
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/migrations/registry.ts +6 -0
- package/src/memory/recall-cache.ts +0 -5
- package/src/memory/schema/calls.ts +274 -0
- package/src/memory/schema/contacts.ts +127 -0
- package/src/memory/schema/conversations.ts +129 -0
- package/src/memory/schema/guardian.ts +172 -0
- package/src/memory/schema/index.ts +8 -0
- package/src/memory/schema/infrastructure.ts +205 -0
- package/src/memory/schema/memory-core.ts +196 -0
- package/src/memory/schema/notifications.ts +191 -0
- package/src/memory/schema/tasks.ts +78 -0
- package/src/memory/schema.ts +1 -1385
- package/src/memory/slack-thread-store.ts +0 -69
- package/src/notifications/decisions-store.ts +2 -105
- package/src/notifications/deliveries-store.ts +0 -11
- package/src/notifications/preferences-store.ts +1 -58
- package/src/permissions/checker.ts +6 -17
- package/src/providers/anthropic/client.ts +6 -2
- package/src/providers/gemini/client.ts +13 -2
- package/src/providers/managed-proxy/constants.ts +55 -0
- package/src/providers/managed-proxy/context.ts +77 -0
- package/src/providers/registry.ts +112 -0
- package/src/runtime/auth/__tests__/guard-tests.test.ts +52 -26
- package/src/runtime/auth/token-service.ts +50 -0
- package/src/runtime/channel-guardian-service.ts +1 -3
- package/src/runtime/channel-invite-transport.ts +121 -34
- package/src/runtime/channel-invite-transports/email.ts +50 -0
- package/src/runtime/channel-invite-transports/slack.ts +81 -0
- package/src/runtime/channel-invite-transports/sms.ts +70 -0
- package/src/runtime/channel-invite-transports/telegram.ts +29 -11
- package/src/runtime/channel-invite-transports/voice.ts +12 -12
- package/src/runtime/http-server.ts +83 -722
- package/src/runtime/http-types.ts +0 -16
- package/src/runtime/invite-redemption-service.ts +193 -0
- package/src/runtime/invite-redemption-templates.ts +6 -6
- package/src/runtime/invite-service.ts +81 -11
- package/src/runtime/middleware/auth.ts +0 -12
- package/src/runtime/routes/access-request-decision.ts +52 -6
- package/src/runtime/routes/app-routes.ts +33 -0
- package/src/runtime/routes/approval-routes.ts +32 -0
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +6 -0
- package/src/runtime/routes/attachment-routes.ts +32 -0
- package/src/runtime/routes/brain-graph-routes.ts +27 -0
- package/src/runtime/routes/call-routes.ts +41 -0
- package/src/runtime/routes/channel-readiness-routes.ts +20 -0
- package/src/runtime/routes/channel-routes.ts +70 -0
- package/src/runtime/routes/contact-routes.ts +96 -6
- package/src/runtime/routes/conversation-attention-routes.ts +15 -0
- package/src/runtime/routes/conversation-routes.ts +190 -193
- package/src/runtime/routes/debug-routes.ts +15 -0
- package/src/runtime/routes/events-routes.ts +16 -0
- package/src/runtime/routes/global-search-routes.ts +15 -0
- package/src/runtime/routes/guardian-action-routes.ts +22 -0
- package/src/runtime/routes/guardian-bootstrap-routes.ts +21 -6
- package/src/runtime/routes/guardian-refresh-routes.ts +20 -0
- package/src/runtime/routes/identity-routes.ts +20 -0
- package/src/runtime/routes/inbound-message-handler.ts +9 -3
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +295 -10
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +9 -42
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +10 -0
- package/src/runtime/routes/integration-routes.ts +83 -0
- package/src/runtime/routes/invite-routes.ts +32 -0
- package/src/runtime/routes/migration-routes.ts +30 -0
- package/src/runtime/routes/pairing-routes.ts +18 -0
- package/src/runtime/routes/secret-routes.ts +20 -0
- package/src/runtime/routes/surface-action-routes.ts +26 -0
- package/src/runtime/routes/trust-rules-routes.ts +31 -0
- package/src/runtime/routes/twilio-routes.ts +79 -0
- package/src/schedule/recurrence-types.ts +1 -11
- package/src/tools/browser/browser-manager.ts +10 -1
- package/src/tools/browser/runtime-check.ts +3 -1
- package/src/tools/followups/followup_create.ts +9 -3
- package/src/tools/mcp/mcp-tool-factory.ts +0 -17
- package/src/tools/memory/definitions.ts +0 -6
- package/src/tools/network/script-proxy/session-manager.ts +38 -3
- package/src/tools/schedule/create.ts +1 -3
- package/src/tools/schedule/update.ts +9 -6
- package/src/tools/shared/shell-output.ts +7 -2
- package/src/twitter/session.ts +29 -77
- package/src/util/cookie-session.ts +114 -0
- package/src/util/platform.ts +0 -4
- package/src/workspace/git-service.ts +10 -4
- package/src/__tests__/conversation-routes.test.ts +0 -99
- package/src/__tests__/task-tools.test.ts +0 -685
- package/src/contacts/startup-migration.ts +0 -21
|
@@ -76,7 +76,7 @@ describe("schedule_create tool", () => {
|
|
|
76
76
|
const result = await executeScheduleCreate(
|
|
77
77
|
{
|
|
78
78
|
name: "Daily standup",
|
|
79
|
-
|
|
79
|
+
expression: "0 9 * * 1-5",
|
|
80
80
|
message: "Time for standup!",
|
|
81
81
|
},
|
|
82
82
|
ctx,
|
|
@@ -93,7 +93,7 @@ describe("schedule_create tool", () => {
|
|
|
93
93
|
const result = await executeScheduleCreate(
|
|
94
94
|
{
|
|
95
95
|
name: "Paused job",
|
|
96
|
-
|
|
96
|
+
expression: "0 12 * * *",
|
|
97
97
|
message: "Noon check",
|
|
98
98
|
enabled: false,
|
|
99
99
|
},
|
|
@@ -108,7 +108,7 @@ describe("schedule_create tool", () => {
|
|
|
108
108
|
const result = await executeScheduleCreate(
|
|
109
109
|
{
|
|
110
110
|
name: "LA morning",
|
|
111
|
-
|
|
111
|
+
expression: "0 8 * * *",
|
|
112
112
|
message: "Good morning LA",
|
|
113
113
|
timezone: "America/Los_Angeles",
|
|
114
114
|
},
|
|
@@ -122,7 +122,7 @@ describe("schedule_create tool", () => {
|
|
|
122
122
|
test("rejects missing name", async () => {
|
|
123
123
|
const result = await executeScheduleCreate(
|
|
124
124
|
{
|
|
125
|
-
|
|
125
|
+
expression: "0 9 * * *",
|
|
126
126
|
message: "test",
|
|
127
127
|
},
|
|
128
128
|
ctx,
|
|
@@ -142,16 +142,14 @@ describe("schedule_create tool", () => {
|
|
|
142
142
|
);
|
|
143
143
|
|
|
144
144
|
expect(result.isError).toBe(true);
|
|
145
|
-
expect(result.content).toContain(
|
|
146
|
-
"expression (or cron_expression) is required",
|
|
147
|
-
);
|
|
145
|
+
expect(result.content).toContain("expression is required");
|
|
148
146
|
});
|
|
149
147
|
|
|
150
148
|
test("rejects missing message", async () => {
|
|
151
149
|
const result = await executeScheduleCreate(
|
|
152
150
|
{
|
|
153
151
|
name: "Test",
|
|
154
|
-
|
|
152
|
+
expression: "0 9 * * *",
|
|
155
153
|
},
|
|
156
154
|
ctx,
|
|
157
155
|
);
|
|
@@ -164,7 +162,8 @@ describe("schedule_create tool", () => {
|
|
|
164
162
|
const result = await executeScheduleCreate(
|
|
165
163
|
{
|
|
166
164
|
name: "Bad cron",
|
|
167
|
-
|
|
165
|
+
syntax: "cron",
|
|
166
|
+
expression: "not-a-cron",
|
|
168
167
|
message: "test",
|
|
169
168
|
},
|
|
170
169
|
ctx,
|
|
@@ -194,7 +193,7 @@ describe("schedule_list tool", () => {
|
|
|
194
193
|
await executeScheduleCreate(
|
|
195
194
|
{
|
|
196
195
|
name: "Job Alpha",
|
|
197
|
-
|
|
196
|
+
expression: "0 9 * * *",
|
|
198
197
|
message: "Alpha",
|
|
199
198
|
},
|
|
200
199
|
ctx,
|
|
@@ -202,7 +201,7 @@ describe("schedule_list tool", () => {
|
|
|
202
201
|
await executeScheduleCreate(
|
|
203
202
|
{
|
|
204
203
|
name: "Job Beta",
|
|
205
|
-
|
|
204
|
+
expression: "0 17 * * *",
|
|
206
205
|
message: "Beta",
|
|
207
206
|
},
|
|
208
207
|
ctx,
|
|
@@ -220,7 +219,7 @@ describe("schedule_list tool", () => {
|
|
|
220
219
|
await executeScheduleCreate(
|
|
221
220
|
{
|
|
222
221
|
name: "Enabled Job",
|
|
223
|
-
|
|
222
|
+
expression: "0 9 * * *",
|
|
224
223
|
message: "enabled",
|
|
225
224
|
},
|
|
226
225
|
ctx,
|
|
@@ -228,7 +227,7 @@ describe("schedule_list tool", () => {
|
|
|
228
227
|
await executeScheduleCreate(
|
|
229
228
|
{
|
|
230
229
|
name: "Disabled Job",
|
|
231
|
-
|
|
230
|
+
expression: "0 17 * * *",
|
|
232
231
|
message: "disabled",
|
|
233
232
|
enabled: false,
|
|
234
233
|
},
|
|
@@ -246,7 +245,7 @@ describe("schedule_list tool", () => {
|
|
|
246
245
|
await executeScheduleCreate(
|
|
247
246
|
{
|
|
248
247
|
name: "Detail Job",
|
|
249
|
-
|
|
248
|
+
expression: "30 14 * * *",
|
|
250
249
|
message: "Afternoon check",
|
|
251
250
|
},
|
|
252
251
|
ctx,
|
|
@@ -286,7 +285,7 @@ describe("schedule_update tool", () => {
|
|
|
286
285
|
await executeScheduleCreate(
|
|
287
286
|
{
|
|
288
287
|
name: "Old Name",
|
|
289
|
-
|
|
288
|
+
expression: "0 9 * * *",
|
|
290
289
|
message: "test",
|
|
291
290
|
},
|
|
292
291
|
ctx,
|
|
@@ -312,7 +311,7 @@ describe("schedule_update tool", () => {
|
|
|
312
311
|
await executeScheduleCreate(
|
|
313
312
|
{
|
|
314
313
|
name: "Timing Test",
|
|
315
|
-
|
|
314
|
+
expression: "0 9 * * *",
|
|
316
315
|
message: "test",
|
|
317
316
|
},
|
|
318
317
|
ctx,
|
|
@@ -324,7 +323,7 @@ describe("schedule_update tool", () => {
|
|
|
324
323
|
const result = await executeScheduleUpdate(
|
|
325
324
|
{
|
|
326
325
|
job_id: row.id,
|
|
327
|
-
|
|
326
|
+
expression: "0 17 * * *",
|
|
328
327
|
},
|
|
329
328
|
ctx,
|
|
330
329
|
);
|
|
@@ -337,7 +336,7 @@ describe("schedule_update tool", () => {
|
|
|
337
336
|
await executeScheduleCreate(
|
|
338
337
|
{
|
|
339
338
|
name: "Disable Me",
|
|
340
|
-
|
|
339
|
+
expression: "0 9 * * *",
|
|
341
340
|
message: "test",
|
|
342
341
|
},
|
|
343
342
|
ctx,
|
|
@@ -370,7 +369,7 @@ describe("schedule_update tool", () => {
|
|
|
370
369
|
await executeScheduleCreate(
|
|
371
370
|
{
|
|
372
371
|
name: "No Update",
|
|
373
|
-
|
|
372
|
+
expression: "0 9 * * *",
|
|
374
373
|
message: "test",
|
|
375
374
|
},
|
|
376
375
|
ctx,
|
|
@@ -402,7 +401,7 @@ describe("schedule_update tool", () => {
|
|
|
402
401
|
await executeScheduleCreate(
|
|
403
402
|
{
|
|
404
403
|
name: "Bad Update",
|
|
405
|
-
|
|
404
|
+
expression: "0 9 * * *",
|
|
406
405
|
message: "test",
|
|
407
406
|
},
|
|
408
407
|
ctx,
|
|
@@ -414,7 +413,8 @@ describe("schedule_update tool", () => {
|
|
|
414
413
|
const result = await executeScheduleUpdate(
|
|
415
414
|
{
|
|
416
415
|
job_id: row.id,
|
|
417
|
-
|
|
416
|
+
syntax: "cron",
|
|
417
|
+
expression: "invalid",
|
|
418
418
|
},
|
|
419
419
|
ctx,
|
|
420
420
|
);
|
|
@@ -432,22 +432,6 @@ describe("schedule_create with RRULE", () => {
|
|
|
432
432
|
getRawDb().run("DELETE FROM cron_jobs");
|
|
433
433
|
});
|
|
434
434
|
|
|
435
|
-
test("creates a schedule with legacy cron_expression", async () => {
|
|
436
|
-
const result = await executeScheduleCreate(
|
|
437
|
-
{
|
|
438
|
-
name: "Legacy cron",
|
|
439
|
-
cron_expression: "0 9 * * 1-5",
|
|
440
|
-
message: "Legacy test",
|
|
441
|
-
},
|
|
442
|
-
ctx,
|
|
443
|
-
);
|
|
444
|
-
|
|
445
|
-
expect(result.isError).toBe(false);
|
|
446
|
-
expect(result.content).toContain("Schedule created successfully");
|
|
447
|
-
expect(result.content).toContain("Syntax: cron");
|
|
448
|
-
expect(result.content).toContain("Every weekday at 9:00 AM");
|
|
449
|
-
});
|
|
450
|
-
|
|
451
435
|
test("creates a schedule with RRULE syntax + expression", async () => {
|
|
452
436
|
const result = await executeScheduleCreate(
|
|
453
437
|
{
|
|
@@ -507,7 +491,7 @@ describe("schedule_update with RRULE", () => {
|
|
|
507
491
|
await executeScheduleCreate(
|
|
508
492
|
{
|
|
509
493
|
name: "Cron to RRULE",
|
|
510
|
-
|
|
494
|
+
expression: "0 9 * * *",
|
|
511
495
|
message: "test",
|
|
512
496
|
},
|
|
513
497
|
ctx,
|
|
@@ -535,7 +519,7 @@ describe("schedule_update with RRULE", () => {
|
|
|
535
519
|
await executeScheduleCreate(
|
|
536
520
|
{
|
|
537
521
|
name: "Auto-detect on update",
|
|
538
|
-
|
|
522
|
+
expression: "0 9 * * *",
|
|
539
523
|
message: "test",
|
|
540
524
|
},
|
|
541
525
|
ctx,
|
|
@@ -561,7 +545,7 @@ describe("schedule_update with RRULE", () => {
|
|
|
561
545
|
await executeScheduleCreate(
|
|
562
546
|
{
|
|
563
547
|
name: "Cron auto-detect",
|
|
564
|
-
|
|
548
|
+
expression: "0 9 * * *",
|
|
565
549
|
message: "test",
|
|
566
550
|
},
|
|
567
551
|
ctx,
|
|
@@ -593,7 +577,7 @@ describe("schedule_list with RRULE", () => {
|
|
|
593
577
|
await executeScheduleCreate(
|
|
594
578
|
{
|
|
595
579
|
name: "Cron Job",
|
|
596
|
-
|
|
580
|
+
expression: "0 9 * * 1-5",
|
|
597
581
|
message: "Cron test",
|
|
598
582
|
},
|
|
599
583
|
ctx,
|
|
@@ -750,7 +734,7 @@ describe("schedule_update with RRULE set", () => {
|
|
|
750
734
|
await executeScheduleCreate(
|
|
751
735
|
{
|
|
752
736
|
name: "Cron to set",
|
|
753
|
-
|
|
737
|
+
expression: "0 9 * * *",
|
|
754
738
|
message: "test",
|
|
755
739
|
},
|
|
756
740
|
ctx,
|
|
@@ -784,7 +768,7 @@ describe("schedule_update with RRULE set", () => {
|
|
|
784
768
|
await executeScheduleCreate(
|
|
785
769
|
{
|
|
786
770
|
name: "Bad set update",
|
|
787
|
-
|
|
771
|
+
expression: "0 9 * * *",
|
|
788
772
|
message: "test",
|
|
789
773
|
},
|
|
790
774
|
ctx,
|
|
@@ -928,7 +912,7 @@ describe("schedule_delete tool", () => {
|
|
|
928
912
|
await executeScheduleCreate(
|
|
929
913
|
{
|
|
930
914
|
name: "Delete Me",
|
|
931
|
-
|
|
915
|
+
expression: "0 9 * * *",
|
|
932
916
|
message: "test",
|
|
933
917
|
},
|
|
934
918
|
ctx,
|
|
@@ -107,13 +107,11 @@ mock.module("../util/platform.js", () => ({
|
|
|
107
107
|
isWindows: () => process.platform === "win32",
|
|
108
108
|
getPlatformName: () => process.platform,
|
|
109
109
|
getClipboardCommand: () => null,
|
|
110
|
-
getHttpTokenPath: () => join(testDir, "http-token"),
|
|
111
110
|
getPlatformTokenPath: () => join(testDir, "platform-token"),
|
|
112
111
|
getTCPHost: () => "127.0.0.1",
|
|
113
112
|
getTCPPort: () => 8765,
|
|
114
113
|
isIOSPairingEnabled: () => false,
|
|
115
114
|
isTCPEnabled: () => false,
|
|
116
|
-
readHttpToken: () => null,
|
|
117
115
|
readLockfile: () => null,
|
|
118
116
|
readPlatformToken: () => null,
|
|
119
117
|
readSessionToken: () => null,
|
|
@@ -120,10 +120,10 @@ describe("isAssistantFeatureFlagEnabled", () => {
|
|
|
120
120
|
|
|
121
121
|
test("declared keys with no persisted override use registry default", () => {
|
|
122
122
|
const config = makeConfig();
|
|
123
|
-
// browser is declared in the registry with defaultEnabled:
|
|
123
|
+
// browser is declared in the registry with defaultEnabled: true
|
|
124
124
|
expect(
|
|
125
125
|
isAssistantFeatureFlagEnabled("feature_flags.browser.enabled", config),
|
|
126
|
-
).toBe(
|
|
126
|
+
).toBe(true);
|
|
127
127
|
});
|
|
128
128
|
});
|
|
129
129
|
|
|
@@ -30,7 +30,6 @@ mock.module("../util/platform.js", () => ({
|
|
|
30
30
|
getDbPath: () => join(testDir, "test.db"),
|
|
31
31
|
getLogPath: () => join(testDir, "test.log"),
|
|
32
32
|
ensureDataDir: () => {},
|
|
33
|
-
readHttpToken: () => "test-bearer-token",
|
|
34
33
|
}));
|
|
35
34
|
|
|
36
35
|
mock.module("../util/logger.js", () => ({
|
|
@@ -33,10 +33,6 @@ mock.module("../security/secure-keys.js", () => ({
|
|
|
33
33
|
getSecureKey: (key: string) => secureKeys[key],
|
|
34
34
|
}));
|
|
35
35
|
|
|
36
|
-
mock.module("../util/platform.js", () => ({
|
|
37
|
-
readHttpToken: () => "runtime-token",
|
|
38
|
-
}));
|
|
39
|
-
|
|
40
36
|
mock.module("../runtime/auth/token-service.js", () => ({
|
|
41
37
|
mintDaemonDeliveryToken: () => "runtime-token",
|
|
42
38
|
}));
|
|
@@ -39,6 +39,8 @@ mock.module("../tools/registry.js", () => ({
|
|
|
39
39
|
getAllTools: () => [],
|
|
40
40
|
}));
|
|
41
41
|
|
|
42
|
+
import type { Database } from "bun:sqlite";
|
|
43
|
+
|
|
42
44
|
import { getDb, initializeDb, resetDb } from "../memory/db.js";
|
|
43
45
|
import { renderTemplate } from "../tasks/task-runner.js";
|
|
44
46
|
import {
|
|
@@ -54,6 +56,7 @@ import {
|
|
|
54
56
|
import { executeTaskDelete } from "../tools/tasks/task-delete.js";
|
|
55
57
|
import { executeTaskList } from "../tools/tasks/task-list.js";
|
|
56
58
|
import { executeTaskRun } from "../tools/tasks/task-run.js";
|
|
59
|
+
import { executeTaskSave } from "../tools/tasks/task-save.js";
|
|
57
60
|
import { executeTaskListAdd } from "../tools/tasks/work-item-enqueue.js";
|
|
58
61
|
import { executeTaskListShow } from "../tools/tasks/work-item-list.js";
|
|
59
62
|
import { executeTaskListRemove } from "../tools/tasks/work-item-remove.js";
|
|
@@ -90,6 +93,10 @@ const ctx: ToolContext = {
|
|
|
90
93
|
trustClass: "guardian",
|
|
91
94
|
};
|
|
92
95
|
|
|
96
|
+
function getRawDb(): Database {
|
|
97
|
+
return (getDb() as unknown as { $client: Database }).$client;
|
|
98
|
+
}
|
|
99
|
+
|
|
93
100
|
function clearTables() {
|
|
94
101
|
const db = getDb();
|
|
95
102
|
db.run("DELETE FROM work_items");
|
|
@@ -97,6 +104,41 @@ function clearTables() {
|
|
|
97
104
|
db.run("DELETE FROM tasks");
|
|
98
105
|
}
|
|
99
106
|
|
|
107
|
+
function clearTablesWithConversations() {
|
|
108
|
+
const raw = getRawDb();
|
|
109
|
+
raw.run("DELETE FROM work_items");
|
|
110
|
+
raw.run("DELETE FROM task_runs");
|
|
111
|
+
raw.run("DELETE FROM tasks");
|
|
112
|
+
raw.run("DELETE FROM messages");
|
|
113
|
+
raw.run("DELETE FROM conversations");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function createTestConversation(id: string): string {
|
|
117
|
+
const raw = getRawDb();
|
|
118
|
+
const now = Date.now();
|
|
119
|
+
raw
|
|
120
|
+
.query(
|
|
121
|
+
`INSERT INTO conversations (id, title, created_at, updated_at, thread_type, memory_scope_id) VALUES (?, 'Test', ?, ?, 'standard', 'default')`,
|
|
122
|
+
)
|
|
123
|
+
.run(id, now, now);
|
|
124
|
+
return id;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function addTestMessage(
|
|
128
|
+
conversationId: string,
|
|
129
|
+
role: string,
|
|
130
|
+
content: string,
|
|
131
|
+
): void {
|
|
132
|
+
const raw = getRawDb();
|
|
133
|
+
const id = crypto.randomUUID();
|
|
134
|
+
const now = Date.now();
|
|
135
|
+
raw
|
|
136
|
+
.query(
|
|
137
|
+
`INSERT INTO messages (id, conversation_id, role, content, created_at) VALUES (?, ?, ?, ?, ?)`,
|
|
138
|
+
)
|
|
139
|
+
.run(id, conversationId, role, content, now);
|
|
140
|
+
}
|
|
141
|
+
|
|
100
142
|
// ═══════════════════════════════════════════════════════════════════
|
|
101
143
|
// Task Store — CRUD
|
|
102
144
|
// ═══════════════════════════════════════════════════════════════════
|
|
@@ -1043,3 +1085,72 @@ describe("executeTaskListRemove tool", () => {
|
|
|
1043
1085
|
expect(result.content).toContain("Multiple items match");
|
|
1044
1086
|
});
|
|
1045
1087
|
});
|
|
1088
|
+
|
|
1089
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
1090
|
+
// Tool: executeTaskSave
|
|
1091
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
1092
|
+
|
|
1093
|
+
describe("executeTaskSave tool", () => {
|
|
1094
|
+
beforeEach(clearTablesWithConversations);
|
|
1095
|
+
|
|
1096
|
+
test("creates a task from a conversation", async () => {
|
|
1097
|
+
const convId = createTestConversation("conv-save-1");
|
|
1098
|
+
addTestMessage(convId, "user", "Please summarize the document");
|
|
1099
|
+
addTestMessage(
|
|
1100
|
+
convId,
|
|
1101
|
+
"assistant",
|
|
1102
|
+
JSON.stringify([
|
|
1103
|
+
{
|
|
1104
|
+
type: "tool_use",
|
|
1105
|
+
id: "tu1",
|
|
1106
|
+
name: "file_read",
|
|
1107
|
+
input: { path: "/tmp/doc.txt" },
|
|
1108
|
+
},
|
|
1109
|
+
]),
|
|
1110
|
+
);
|
|
1111
|
+
addTestMessage(convId, "assistant", "Here is the summary...");
|
|
1112
|
+
|
|
1113
|
+
const result = await executeTaskSave({ conversation_id: convId }, ctx);
|
|
1114
|
+
|
|
1115
|
+
expect(result.isError).toBe(false);
|
|
1116
|
+
expect(result.content).toContain("Task saved successfully");
|
|
1117
|
+
expect(result.content).toContain("Please summarize the document");
|
|
1118
|
+
expect(result.content).toContain("file_read");
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
test("uses title override when provided", async () => {
|
|
1122
|
+
const convId = createTestConversation("conv-save-2");
|
|
1123
|
+
addTestMessage(convId, "user", "Read and analyze the logs");
|
|
1124
|
+
addTestMessage(convId, "assistant", "Done!");
|
|
1125
|
+
|
|
1126
|
+
const result = await executeTaskSave(
|
|
1127
|
+
{ conversation_id: convId, title: "My Custom Title" },
|
|
1128
|
+
ctx,
|
|
1129
|
+
);
|
|
1130
|
+
|
|
1131
|
+
expect(result.isError).toBe(false);
|
|
1132
|
+
expect(result.content).toContain("My Custom Title");
|
|
1133
|
+
});
|
|
1134
|
+
|
|
1135
|
+
test("uses context conversation_id when missing", async () => {
|
|
1136
|
+
const convId = createTestConversation(ctx.conversationId);
|
|
1137
|
+
addTestMessage(convId, "user", "Summarize the report");
|
|
1138
|
+
addTestMessage(convId, "assistant", "Done.");
|
|
1139
|
+
|
|
1140
|
+
const result = await executeTaskSave({}, ctx);
|
|
1141
|
+
|
|
1142
|
+
expect(result.isError).toBe(false);
|
|
1143
|
+
expect(result.content).toContain("Task saved successfully");
|
|
1144
|
+
expect(result.content).toContain("Summarize the report");
|
|
1145
|
+
});
|
|
1146
|
+
|
|
1147
|
+
test("returns error for nonexistent conversation", async () => {
|
|
1148
|
+
const result = await executeTaskSave(
|
|
1149
|
+
{ conversation_id: "nonexistent" },
|
|
1150
|
+
ctx,
|
|
1151
|
+
);
|
|
1152
|
+
|
|
1153
|
+
expect(result.isError).toBe(true);
|
|
1154
|
+
expect(result.content).toContain("No messages found");
|
|
1155
|
+
});
|
|
1156
|
+
});
|
|
@@ -711,10 +711,13 @@ describe("formatShellOutput", () => {
|
|
|
711
711
|
expect(result.isError).toBe(false);
|
|
712
712
|
});
|
|
713
713
|
|
|
714
|
-
test("failed command with no output shows exit code tag", () => {
|
|
714
|
+
test("failed command with no output shows exit code tag and descriptive message", () => {
|
|
715
715
|
const result = formatShellOutput("", "", 1, false, 120);
|
|
716
|
-
expect(result.content).
|
|
716
|
+
expect(result.content).toContain('<command_exit code="1" />');
|
|
717
|
+
expect(result.content).toContain("Command failed with exit code 1");
|
|
718
|
+
expect(result.content).toContain("No stdout or stderr output was produced");
|
|
717
719
|
expect(result.isError).toBe(true);
|
|
720
|
+
expect(result.status).toContain('<command_exit code="1" />');
|
|
718
721
|
});
|
|
719
722
|
|
|
720
723
|
test("failed command with output includes exit code in status", () => {
|