@vellumai/assistant 0.4.3 → 0.4.4
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/.env.example +3 -0
- package/ARCHITECTURE.md +40 -3
- package/README.md +43 -35
- package/package.json +1 -1
- package/scripts/ipc/generate-swift.ts +1 -0
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +58 -120
- package/src/__tests__/actor-token-service.test.ts +1099 -0
- package/src/__tests__/agent-loop.test.ts +51 -0
- package/src/__tests__/approval-routes-http.test.ts +2 -0
- package/src/__tests__/assistant-events-sse-hardening.test.ts +7 -5
- package/src/__tests__/assistant-id-boundary-guard.test.ts +125 -0
- package/src/__tests__/call-controller.test.ts +49 -0
- package/src/__tests__/call-pointer-message-composer.test.ts +171 -0
- package/src/__tests__/call-pointer-messages.test.ts +93 -3
- package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +42 -0
- package/src/__tests__/callback-handoff-copy.test.ts +186 -0
- package/src/__tests__/channel-approval-routes.test.ts +133 -12
- package/src/__tests__/channel-guardian.test.ts +0 -87
- package/src/__tests__/channel-readiness-service.test.ts +10 -16
- package/src/__tests__/checker.test.ts +33 -12
- package/src/__tests__/config-schema.test.ts +4 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +410 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +256 -0
- package/src/__tests__/conversation-routes.test.ts +12 -3
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/daemon-server-session-init.test.ts +4 -0
- package/src/__tests__/guardian-actions-endpoint.test.ts +19 -14
- package/src/__tests__/guardian-dispatch.test.ts +8 -0
- package/src/__tests__/guardian-outbound-http.test.ts +4 -4
- package/src/__tests__/guardian-question-mode.test.ts +200 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +178 -0
- package/src/__tests__/guardian-routing-state.test.ts +525 -0
- package/src/__tests__/handle-user-message-secret-resume.test.ts +2 -0
- package/src/__tests__/handlers-telegram-config.test.ts +0 -83
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +55 -0
- package/src/__tests__/headless-browser-navigate.test.ts +2 -0
- package/src/__tests__/ipc-snapshot.test.ts +18 -51
- package/src/__tests__/non-member-access-request.test.ts +131 -8
- package/src/__tests__/notification-decision-fallback.test.ts +129 -4
- package/src/__tests__/notification-decision-strategy.test.ts +62 -2
- package/src/__tests__/notification-guardian-path.test.ts +3 -0
- package/src/__tests__/recording-intent-handler.test.ts +1 -0
- package/src/__tests__/relay-server.test.ts +841 -39
- package/src/__tests__/send-endpoint-busy.test.ts +5 -0
- package/src/__tests__/session-agent-loop.test.ts +1 -0
- package/src/__tests__/session-confirmation-signals.test.ts +523 -0
- package/src/__tests__/session-init.benchmark.test.ts +0 -1
- package/src/__tests__/session-surfaces-task-progress.test.ts +1 -1
- package/src/__tests__/session-tool-setup-app-refresh.test.ts +81 -2
- package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -1
- package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +21 -2
- package/src/__tests__/tool-grant-request-escalation.test.ts +333 -27
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +678 -0
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1064 -0
- package/src/__tests__/twilio-config.test.ts +2 -13
- package/src/agent/loop.ts +1 -1
- package/src/approvals/guardian-decision-primitive.ts +10 -2
- package/src/approvals/guardian-request-resolvers.ts +128 -9
- package/src/calls/call-constants.ts +21 -0
- package/src/calls/call-controller.ts +9 -2
- package/src/calls/call-domain.ts +28 -7
- package/src/calls/call-pointer-message-composer.ts +154 -0
- package/src/calls/call-pointer-messages.ts +106 -27
- package/src/calls/guardian-dispatch.ts +4 -2
- package/src/calls/relay-server.ts +424 -12
- package/src/calls/twilio-config.ts +4 -11
- package/src/calls/twilio-routes.ts +1 -1
- package/src/calls/types.ts +3 -1
- package/src/cli.ts +5 -4
- package/src/config/bundled-skills/agentmail/SKILL.md +4 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +146 -10
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -1
- package/src/config/bundled-skills/email-setup/SKILL.md +1 -1
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +105 -81
- package/src/config/bundled-skills/messaging/SKILL.md +61 -12
- package/src/config/bundled-skills/messaging/TOOLS.json +58 -0
- package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +6 -1
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +35 -0
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +52 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +30 -39
- package/src/config/bundled-skills/twitter/SKILL.md +3 -3
- package/src/config/bundled-skills/vercel-token-setup/SKILL.md +1 -0
- package/src/config/calls-schema.ts +24 -0
- package/src/config/env.ts +22 -0
- package/src/config/feature-flag-registry.json +8 -0
- package/src/config/schema.ts +2 -2
- package/src/config/skills.ts +11 -0
- package/src/config/system-prompt.ts +11 -1
- package/src/config/templates/SOUL.md +2 -0
- package/src/config/vellum-skills/sms-setup/SKILL.md +71 -82
- package/src/config/vellum-skills/trusted-contacts/SKILL.md +10 -9
- package/src/config/vellum-skills/twilio-setup/SKILL.md +88 -73
- package/src/daemon/call-pointer-generators.ts +59 -0
- package/src/daemon/computer-use-session.ts +2 -5
- package/src/daemon/handlers/apps.ts +76 -20
- package/src/daemon/handlers/config-channels.ts +5 -55
- package/src/daemon/handlers/config-inbox.ts +9 -3
- package/src/daemon/handlers/config-ingress.ts +28 -3
- package/src/daemon/handlers/config-telegram.ts +12 -0
- package/src/daemon/handlers/config.ts +2 -6
- package/src/daemon/handlers/pairing.ts +2 -0
- package/src/daemon/handlers/sessions.ts +48 -3
- package/src/daemon/handlers/shared.ts +17 -2
- package/src/daemon/ipc-contract/integrations.ts +1 -99
- package/src/daemon/ipc-contract/messages.ts +47 -1
- package/src/daemon/ipc-contract/notifications.ts +11 -0
- package/src/daemon/ipc-contract-inventory.json +2 -4
- package/src/daemon/lifecycle.ts +17 -0
- package/src/daemon/server.ts +14 -1
- package/src/daemon/session-agent-loop-handlers.ts +20 -0
- package/src/daemon/session-agent-loop.ts +22 -11
- package/src/daemon/session-lifecycle.ts +1 -1
- package/src/daemon/session-process.ts +11 -1
- package/src/daemon/session-runtime-assembly.ts +3 -0
- package/src/daemon/session-surfaces.ts +3 -2
- package/src/daemon/session.ts +88 -1
- package/src/daemon/tool-side-effects.ts +22 -0
- package/src/home-base/prebuilt/brain-graph.html +1483 -0
- package/src/home-base/prebuilt/index.html +40 -0
- package/src/inbound/platform-callback-registration.ts +157 -0
- package/src/memory/canonical-guardian-store.ts +1 -1
- package/src/memory/db-init.ts +4 -0
- package/src/memory/migrations/038-actor-token-records.ts +39 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/schema.ts +16 -0
- package/src/messaging/provider-types.ts +24 -0
- package/src/messaging/provider.ts +7 -0
- package/src/messaging/providers/gmail/adapter.ts +127 -0
- package/src/messaging/providers/sms/adapter.ts +40 -37
- package/src/notifications/adapters/macos.ts +45 -2
- package/src/notifications/broadcaster.ts +16 -0
- package/src/notifications/copy-composer.ts +39 -1
- package/src/notifications/decision-engine.ts +22 -9
- package/src/notifications/destination-resolver.ts +16 -2
- package/src/notifications/emit-signal.ts +16 -8
- package/src/notifications/guardian-question-mode.ts +419 -0
- package/src/notifications/signal.ts +14 -3
- package/src/permissions/checker.ts +13 -1
- package/src/permissions/prompter.ts +14 -0
- package/src/providers/anthropic/client.ts +20 -0
- package/src/providers/provider-send-message.ts +15 -3
- package/src/runtime/access-request-helper.ts +71 -1
- package/src/runtime/actor-token-service.ts +234 -0
- package/src/runtime/actor-token-store.ts +236 -0
- package/src/runtime/channel-approvals.ts +5 -3
- package/src/runtime/channel-readiness-service.ts +23 -64
- package/src/runtime/channel-readiness-types.ts +3 -4
- package/src/runtime/channel-retry-sweep.ts +4 -1
- package/src/runtime/confirmation-request-guardian-bridge.ts +197 -0
- package/src/runtime/guardian-action-followup-executor.ts +1 -1
- package/src/runtime/guardian-context-resolver.ts +82 -0
- package/src/runtime/guardian-outbound-actions.ts +0 -3
- package/src/runtime/guardian-reply-router.ts +67 -30
- package/src/runtime/guardian-vellum-migration.ts +57 -0
- package/src/runtime/http-server.ts +65 -12
- package/src/runtime/http-types.ts +13 -0
- package/src/runtime/invite-redemption-service.ts +8 -0
- package/src/runtime/local-actor-identity.ts +76 -0
- package/src/runtime/middleware/actor-token.ts +271 -0
- package/src/runtime/routes/approval-routes.ts +82 -7
- package/src/runtime/routes/brain-graph-routes.ts +222 -0
- package/src/runtime/routes/channel-readiness-routes.ts +71 -0
- package/src/runtime/routes/conversation-routes.ts +140 -52
- package/src/runtime/routes/events-routes.ts +20 -5
- package/src/runtime/routes/guardian-action-routes.ts +45 -3
- package/src/runtime/routes/guardian-approval-interception.ts +29 -0
- package/src/runtime/routes/guardian-bootstrap-routes.ts +145 -0
- package/src/runtime/routes/inbound-message-handler.ts +143 -2
- package/src/runtime/routes/integration-routes.ts +7 -15
- package/src/runtime/routes/pairing-routes.ts +163 -0
- package/src/runtime/routes/twilio-routes.ts +934 -0
- package/src/runtime/tool-grant-request-helper.ts +3 -1
- package/src/security/oauth2.ts +27 -2
- package/src/security/token-manager.ts +46 -10
- package/src/tools/browser/browser-execution.ts +4 -3
- package/src/tools/browser/browser-handoff.ts +10 -18
- package/src/tools/browser/browser-manager.ts +80 -25
- package/src/tools/browser/browser-screencast.ts +35 -119
- package/src/tools/permission-checker.ts +15 -4
- package/src/tools/tool-approval-handler.ts +242 -18
- package/src/__tests__/handlers-twilio-config.test.ts +0 -1928
- package/src/daemon/handlers/config-twilio.ts +0 -1082
|
@@ -1338,7 +1338,6 @@ describe('IPC handler channel-aware guardian status', () => {
|
|
|
1338
1338
|
type: 'guardian_verification',
|
|
1339
1339
|
action: 'status',
|
|
1340
1340
|
channel: 'telegram',
|
|
1341
|
-
assistantId: 'self',
|
|
1342
1341
|
};
|
|
1343
1342
|
|
|
1344
1343
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -1358,7 +1357,6 @@ describe('IPC handler channel-aware guardian status', () => {
|
|
|
1358
1357
|
type: 'guardian_verification',
|
|
1359
1358
|
action: 'status',
|
|
1360
1359
|
channel: 'sms',
|
|
1361
|
-
assistantId: 'self',
|
|
1362
1360
|
};
|
|
1363
1361
|
|
|
1364
1362
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -1384,7 +1382,6 @@ describe('IPC handler channel-aware guardian status', () => {
|
|
|
1384
1382
|
type: 'guardian_verification',
|
|
1385
1383
|
action: 'status',
|
|
1386
1384
|
channel: 'telegram',
|
|
1387
|
-
assistantId: 'self',
|
|
1388
1385
|
};
|
|
1389
1386
|
|
|
1390
1387
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -1413,7 +1410,6 @@ describe('IPC handler channel-aware guardian status', () => {
|
|
|
1413
1410
|
type: 'guardian_verification',
|
|
1414
1411
|
action: 'status',
|
|
1415
1412
|
channel: 'telegram',
|
|
1416
|
-
assistantId: 'self',
|
|
1417
1413
|
};
|
|
1418
1414
|
|
|
1419
1415
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -1457,36 +1453,6 @@ describe('IPC handler channel-aware guardian status', () => {
|
|
|
1457
1453
|
expect(resp!.channel).toBe('sms');
|
|
1458
1454
|
});
|
|
1459
1455
|
|
|
1460
|
-
test('status action with custom assistantId is ignored (daemon uses internal scope)', () => {
|
|
1461
|
-
// Create binding under the internal scope constant — the handler always
|
|
1462
|
-
// uses DAEMON_INTERNAL_ASSISTANT_ID regardless of what the caller passes.
|
|
1463
|
-
createBinding({
|
|
1464
|
-
assistantId: 'self',
|
|
1465
|
-
channel: 'telegram',
|
|
1466
|
-
guardianExternalUserId: 'user-77',
|
|
1467
|
-
guardianDeliveryChatId: 'chat-77',
|
|
1468
|
-
});
|
|
1469
|
-
|
|
1470
|
-
const { ctx, lastResponse } = createMockCtx();
|
|
1471
|
-
const msg: GuardianVerificationRequest = {
|
|
1472
|
-
type: 'guardian_verification',
|
|
1473
|
-
action: 'status',
|
|
1474
|
-
channel: 'telegram',
|
|
1475
|
-
assistantId: 'asst-custom', // ignored by handler
|
|
1476
|
-
};
|
|
1477
|
-
|
|
1478
|
-
handleGuardianVerification(msg, mockSocket, ctx);
|
|
1479
|
-
|
|
1480
|
-
const resp = lastResponse();
|
|
1481
|
-
expect(resp).not.toBeNull();
|
|
1482
|
-
expect(resp!.success).toBe(true);
|
|
1483
|
-
expect(resp!.bound).toBe(true);
|
|
1484
|
-
expect(resp!.assistantId).toBe('self');
|
|
1485
|
-
expect(resp!.channel).toBe('telegram');
|
|
1486
|
-
expect(resp!.guardianExternalUserId).toBe('user-77');
|
|
1487
|
-
expect(resp!.guardianDeliveryChatId).toBe('chat-77');
|
|
1488
|
-
});
|
|
1489
|
-
|
|
1490
1456
|
test('status action for unbound sms does not return guardianDeliveryChatId', () => {
|
|
1491
1457
|
const { ctx, lastResponse } = createMockCtx();
|
|
1492
1458
|
const msg: GuardianVerificationRequest = {
|
|
@@ -1512,7 +1478,6 @@ describe('IPC handler channel-aware guardian status', () => {
|
|
|
1512
1478
|
type: 'guardian_verification',
|
|
1513
1479
|
action: 'status',
|
|
1514
1480
|
channel: 'voice',
|
|
1515
|
-
assistantId: 'self',
|
|
1516
1481
|
};
|
|
1517
1482
|
|
|
1518
1483
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -1529,7 +1494,6 @@ describe('IPC handler channel-aware guardian status', () => {
|
|
|
1529
1494
|
type: 'guardian_verification',
|
|
1530
1495
|
action: 'status',
|
|
1531
1496
|
channel: 'voice',
|
|
1532
|
-
assistantId: 'self',
|
|
1533
1497
|
};
|
|
1534
1498
|
|
|
1535
1499
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -1944,7 +1908,6 @@ describe('IPC handler voice guardian verification', () => {
|
|
|
1944
1908
|
type: 'guardian_verification',
|
|
1945
1909
|
action: 'create_challenge',
|
|
1946
1910
|
channel: 'voice',
|
|
1947
|
-
assistantId: 'self',
|
|
1948
1911
|
};
|
|
1949
1912
|
|
|
1950
1913
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -1965,7 +1928,6 @@ describe('IPC handler voice guardian verification', () => {
|
|
|
1965
1928
|
type: 'guardian_verification',
|
|
1966
1929
|
action: 'status',
|
|
1967
1930
|
channel: 'voice',
|
|
1968
|
-
assistantId: 'self',
|
|
1969
1931
|
};
|
|
1970
1932
|
|
|
1971
1933
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -1991,7 +1953,6 @@ describe('IPC handler voice guardian verification', () => {
|
|
|
1991
1953
|
type: 'guardian_verification',
|
|
1992
1954
|
action: 'status',
|
|
1993
1955
|
channel: 'voice',
|
|
1994
|
-
assistantId: 'self',
|
|
1995
1956
|
};
|
|
1996
1957
|
|
|
1997
1958
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -2018,7 +1979,6 @@ describe('IPC handler voice guardian verification', () => {
|
|
|
2018
1979
|
type: 'guardian_verification',
|
|
2019
1980
|
action: 'revoke',
|
|
2020
1981
|
channel: 'voice',
|
|
2021
|
-
assistantId: 'self',
|
|
2022
1982
|
};
|
|
2023
1983
|
|
|
2024
1984
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -2051,7 +2011,6 @@ describe('IPC handler voice guardian verification', () => {
|
|
|
2051
2011
|
type: 'guardian_verification',
|
|
2052
2012
|
action: 'revoke',
|
|
2053
2013
|
channel: 'voice',
|
|
2054
|
-
assistantId: 'self',
|
|
2055
2014
|
};
|
|
2056
2015
|
|
|
2057
2016
|
handleGuardianVerification(msg, mockSocket, ctx);
|
|
@@ -2516,7 +2475,6 @@ describe('outbound SMS verification', () => {
|
|
|
2516
2475
|
type: 'guardian_verification',
|
|
2517
2476
|
action: 'start_outbound',
|
|
2518
2477
|
channel: 'sms',
|
|
2519
|
-
assistantId: 'self',
|
|
2520
2478
|
destination: '+15551234567',
|
|
2521
2479
|
};
|
|
2522
2480
|
|
|
@@ -2553,7 +2511,6 @@ describe('outbound SMS verification', () => {
|
|
|
2553
2511
|
type: 'guardian_verification',
|
|
2554
2512
|
action: 'start_outbound',
|
|
2555
2513
|
channel: 'sms',
|
|
2556
|
-
assistantId: 'self',
|
|
2557
2514
|
destination: '+15559876543',
|
|
2558
2515
|
rebind: false,
|
|
2559
2516
|
};
|
|
@@ -2580,7 +2537,6 @@ describe('outbound SMS verification', () => {
|
|
|
2580
2537
|
type: 'guardian_verification',
|
|
2581
2538
|
action: 'start_outbound',
|
|
2582
2539
|
channel: 'sms',
|
|
2583
|
-
assistantId: 'self',
|
|
2584
2540
|
destination: '+15559876543',
|
|
2585
2541
|
rebind: true,
|
|
2586
2542
|
};
|
|
@@ -2600,7 +2556,6 @@ describe('outbound SMS verification', () => {
|
|
|
2600
2556
|
type: 'guardian_verification',
|
|
2601
2557
|
action: 'start_outbound',
|
|
2602
2558
|
channel: 'sms',
|
|
2603
|
-
assistantId: 'self',
|
|
2604
2559
|
destination: '+15551234567',
|
|
2605
2560
|
}, mockSocket, startCtx);
|
|
2606
2561
|
|
|
@@ -2610,7 +2565,6 @@ describe('outbound SMS verification', () => {
|
|
|
2610
2565
|
type: 'guardian_verification',
|
|
2611
2566
|
action: 'resend_outbound',
|
|
2612
2567
|
channel: 'sms',
|
|
2613
|
-
assistantId: 'self',
|
|
2614
2568
|
}, mockSocket, ctx);
|
|
2615
2569
|
|
|
2616
2570
|
const resp = lastResponse();
|
|
@@ -2626,7 +2580,6 @@ describe('outbound SMS verification', () => {
|
|
|
2626
2580
|
type: 'guardian_verification',
|
|
2627
2581
|
action: 'start_outbound',
|
|
2628
2582
|
channel: 'sms',
|
|
2629
|
-
assistantId: 'self',
|
|
2630
2583
|
destination: '+15551234567',
|
|
2631
2584
|
}, mockSocket, startCtx);
|
|
2632
2585
|
|
|
@@ -2644,7 +2597,6 @@ describe('outbound SMS verification', () => {
|
|
|
2644
2597
|
type: 'guardian_verification',
|
|
2645
2598
|
action: 'resend_outbound',
|
|
2646
2599
|
channel: 'sms',
|
|
2647
|
-
assistantId: 'self',
|
|
2648
2600
|
}, mockSocket, ctx);
|
|
2649
2601
|
|
|
2650
2602
|
const resp = lastResponse();
|
|
@@ -2661,7 +2613,6 @@ describe('outbound SMS verification', () => {
|
|
|
2661
2613
|
type: 'guardian_verification',
|
|
2662
2614
|
action: 'start_outbound',
|
|
2663
2615
|
channel: 'sms',
|
|
2664
|
-
assistantId: 'self',
|
|
2665
2616
|
destination: '+15551234567',
|
|
2666
2617
|
}, mockSocket, startCtx);
|
|
2667
2618
|
|
|
@@ -2681,7 +2632,6 @@ describe('outbound SMS verification', () => {
|
|
|
2681
2632
|
type: 'guardian_verification',
|
|
2682
2633
|
action: 'resend_outbound',
|
|
2683
2634
|
channel: 'sms',
|
|
2684
|
-
assistantId: 'self',
|
|
2685
2635
|
}, mockSocket, ctx);
|
|
2686
2636
|
|
|
2687
2637
|
const resp = lastResponse();
|
|
@@ -2697,7 +2647,6 @@ describe('outbound SMS verification', () => {
|
|
|
2697
2647
|
type: 'guardian_verification',
|
|
2698
2648
|
action: 'start_outbound',
|
|
2699
2649
|
channel: 'sms',
|
|
2700
|
-
assistantId: 'self',
|
|
2701
2650
|
destination: '+15551234567',
|
|
2702
2651
|
}, mockSocket, startCtx);
|
|
2703
2652
|
|
|
@@ -2711,7 +2660,6 @@ describe('outbound SMS verification', () => {
|
|
|
2711
2660
|
type: 'guardian_verification',
|
|
2712
2661
|
action: 'cancel_outbound',
|
|
2713
2662
|
channel: 'sms',
|
|
2714
|
-
assistantId: 'self',
|
|
2715
2663
|
}, mockSocket, ctx);
|
|
2716
2664
|
|
|
2717
2665
|
const resp = lastResponse();
|
|
@@ -2803,7 +2751,6 @@ describe('outbound SMS verification', () => {
|
|
|
2803
2751
|
type: 'guardian_verification',
|
|
2804
2752
|
action: 'start_outbound',
|
|
2805
2753
|
channel: 'slack',
|
|
2806
|
-
assistantId: 'self',
|
|
2807
2754
|
destination: '@some_user',
|
|
2808
2755
|
}, mockSocket, ctx);
|
|
2809
2756
|
|
|
@@ -2819,7 +2766,6 @@ describe('outbound SMS verification', () => {
|
|
|
2819
2766
|
type: 'guardian_verification',
|
|
2820
2767
|
action: 'start_outbound',
|
|
2821
2768
|
channel: 'sms',
|
|
2822
|
-
assistantId: 'self',
|
|
2823
2769
|
// no destination
|
|
2824
2770
|
}, mockSocket, ctx);
|
|
2825
2771
|
|
|
@@ -2835,7 +2781,6 @@ describe('outbound SMS verification', () => {
|
|
|
2835
2781
|
type: 'guardian_verification',
|
|
2836
2782
|
action: 'start_outbound',
|
|
2837
2783
|
channel: 'sms',
|
|
2838
|
-
assistantId: 'self',
|
|
2839
2784
|
destination: 'not-a-phone',
|
|
2840
2785
|
}, mockSocket, ctx);
|
|
2841
2786
|
|
|
@@ -2851,7 +2796,6 @@ describe('outbound SMS verification', () => {
|
|
|
2851
2796
|
type: 'guardian_verification',
|
|
2852
2797
|
action: 'start_outbound',
|
|
2853
2798
|
channel: 'sms',
|
|
2854
|
-
assistantId: 'self',
|
|
2855
2799
|
destination: '(555) 123-4567',
|
|
2856
2800
|
}, mockSocket, ctx);
|
|
2857
2801
|
|
|
@@ -2892,7 +2836,6 @@ describe('outbound SMS verification', () => {
|
|
|
2892
2836
|
type: 'guardian_verification',
|
|
2893
2837
|
action: 'cancel_outbound',
|
|
2894
2838
|
channel: 'sms',
|
|
2895
|
-
assistantId: 'self',
|
|
2896
2839
|
}, mockSocket, ctx);
|
|
2897
2840
|
|
|
2898
2841
|
const resp = lastResponse();
|
|
@@ -2917,7 +2860,6 @@ describe('outbound Telegram verification', () => {
|
|
|
2917
2860
|
type: 'guardian_verification',
|
|
2918
2861
|
action: 'start_outbound',
|
|
2919
2862
|
channel: 'telegram',
|
|
2920
|
-
assistantId: 'self',
|
|
2921
2863
|
destination: '@someuser',
|
|
2922
2864
|
}, mockSocket, ctx);
|
|
2923
2865
|
|
|
@@ -2947,7 +2889,6 @@ describe('outbound Telegram verification', () => {
|
|
|
2947
2889
|
type: 'guardian_verification',
|
|
2948
2890
|
action: 'start_outbound',
|
|
2949
2891
|
channel: 'telegram',
|
|
2950
|
-
assistantId: 'self',
|
|
2951
2892
|
destination: 'someuser',
|
|
2952
2893
|
}, mockSocket, ctx);
|
|
2953
2894
|
|
|
@@ -2964,7 +2905,6 @@ describe('outbound Telegram verification', () => {
|
|
|
2964
2905
|
type: 'guardian_verification',
|
|
2965
2906
|
action: 'start_outbound',
|
|
2966
2907
|
channel: 'telegram',
|
|
2967
|
-
assistantId: 'self',
|
|
2968
2908
|
destination: '123456789',
|
|
2969
2909
|
}, mockSocket, ctx);
|
|
2970
2910
|
|
|
@@ -3002,7 +2942,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3002
2942
|
type: 'guardian_verification',
|
|
3003
2943
|
action: 'start_outbound',
|
|
3004
2944
|
channel: 'telegram',
|
|
3005
|
-
assistantId: 'self',
|
|
3006
2945
|
destination: '@someuser',
|
|
3007
2946
|
}, mockSocket, ctx);
|
|
3008
2947
|
|
|
@@ -3025,7 +2964,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3025
2964
|
type: 'guardian_verification',
|
|
3026
2965
|
action: 'start_outbound',
|
|
3027
2966
|
channel: 'telegram',
|
|
3028
|
-
assistantId: 'self',
|
|
3029
2967
|
destination: '@newuser',
|
|
3030
2968
|
rebind: false,
|
|
3031
2969
|
}, mockSocket, ctx);
|
|
@@ -3196,7 +3134,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3196
3134
|
type: 'guardian_verification',
|
|
3197
3135
|
action: 'start_outbound',
|
|
3198
3136
|
channel: 'telegram',
|
|
3199
|
-
assistantId: 'self',
|
|
3200
3137
|
destination: '123456789',
|
|
3201
3138
|
}, mockSocket, startCtx);
|
|
3202
3139
|
|
|
@@ -3210,7 +3147,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3210
3147
|
type: 'guardian_verification',
|
|
3211
3148
|
action: 'resend_outbound',
|
|
3212
3149
|
channel: 'telegram',
|
|
3213
|
-
assistantId: 'self',
|
|
3214
3150
|
}, mockSocket, ctx);
|
|
3215
3151
|
|
|
3216
3152
|
const resp = lastResponse();
|
|
@@ -3231,7 +3167,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3231
3167
|
type: 'guardian_verification',
|
|
3232
3168
|
action: 'start_outbound',
|
|
3233
3169
|
channel: 'telegram',
|
|
3234
|
-
assistantId: 'self',
|
|
3235
3170
|
destination: '@someuser',
|
|
3236
3171
|
}, mockSocket, startCtx);
|
|
3237
3172
|
|
|
@@ -3240,7 +3175,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3240
3175
|
type: 'guardian_verification',
|
|
3241
3176
|
action: 'resend_outbound',
|
|
3242
3177
|
channel: 'telegram',
|
|
3243
|
-
assistantId: 'self',
|
|
3244
3178
|
}, mockSocket, ctx);
|
|
3245
3179
|
|
|
3246
3180
|
const resp = lastResponse();
|
|
@@ -3256,7 +3190,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3256
3190
|
type: 'guardian_verification',
|
|
3257
3191
|
action: 'start_outbound',
|
|
3258
3192
|
channel: 'telegram',
|
|
3259
|
-
assistantId: 'self',
|
|
3260
3193
|
destination: '123456789',
|
|
3261
3194
|
}, mockSocket, startCtx);
|
|
3262
3195
|
|
|
@@ -3268,7 +3201,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3268
3201
|
type: 'guardian_verification',
|
|
3269
3202
|
action: 'cancel_outbound',
|
|
3270
3203
|
channel: 'telegram',
|
|
3271
|
-
assistantId: 'self',
|
|
3272
3204
|
}, mockSocket, ctx);
|
|
3273
3205
|
|
|
3274
3206
|
const resp = lastResponse();
|
|
@@ -3314,7 +3246,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3314
3246
|
type: 'guardian_verification',
|
|
3315
3247
|
action: 'start_outbound',
|
|
3316
3248
|
channel: 'telegram',
|
|
3317
|
-
assistantId: 'self',
|
|
3318
3249
|
}, mockSocket, ctx);
|
|
3319
3250
|
|
|
3320
3251
|
const resp = lastResponse();
|
|
@@ -3330,7 +3261,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3330
3261
|
type: 'guardian_verification',
|
|
3331
3262
|
action: 'start_outbound',
|
|
3332
3263
|
channel: 'telegram',
|
|
3333
|
-
assistantId: 'self',
|
|
3334
3264
|
destination: '123456789',
|
|
3335
3265
|
}, mockSocket, startCtx);
|
|
3336
3266
|
|
|
@@ -3350,7 +3280,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3350
3280
|
type: 'guardian_verification',
|
|
3351
3281
|
action: 'resend_outbound',
|
|
3352
3282
|
channel: 'telegram',
|
|
3353
|
-
assistantId: 'self',
|
|
3354
3283
|
}, mockSocket, ctx);
|
|
3355
3284
|
|
|
3356
3285
|
const resp = lastResponse();
|
|
@@ -3366,7 +3295,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3366
3295
|
type: 'guardian_verification',
|
|
3367
3296
|
action: 'start_outbound',
|
|
3368
3297
|
channel: 'telegram',
|
|
3369
|
-
assistantId: 'self',
|
|
3370
3298
|
destination: '123456789',
|
|
3371
3299
|
}, mockSocket, startCtx);
|
|
3372
3300
|
|
|
@@ -3376,7 +3304,6 @@ describe('outbound Telegram verification', () => {
|
|
|
3376
3304
|
type: 'guardian_verification',
|
|
3377
3305
|
action: 'resend_outbound',
|
|
3378
3306
|
channel: 'telegram',
|
|
3379
|
-
assistantId: 'self',
|
|
3380
3307
|
}, mockSocket, ctx);
|
|
3381
3308
|
|
|
3382
3309
|
const resp = lastResponse();
|
|
@@ -3401,7 +3328,6 @@ describe('outbound voice verification', () => {
|
|
|
3401
3328
|
type: 'guardian_verification',
|
|
3402
3329
|
action: 'start_outbound',
|
|
3403
3330
|
channel: 'voice',
|
|
3404
|
-
assistantId: 'self',
|
|
3405
3331
|
destination: '+15551234567',
|
|
3406
3332
|
}, mockSocket, ctx);
|
|
3407
3333
|
|
|
@@ -3440,7 +3366,6 @@ describe('outbound voice verification', () => {
|
|
|
3440
3366
|
type: 'guardian_verification',
|
|
3441
3367
|
action: 'start_outbound',
|
|
3442
3368
|
channel: 'voice',
|
|
3443
|
-
assistantId: 'self',
|
|
3444
3369
|
destination: 'not-a-phone',
|
|
3445
3370
|
}, mockSocket, ctx);
|
|
3446
3371
|
|
|
@@ -3456,7 +3381,6 @@ describe('outbound voice verification', () => {
|
|
|
3456
3381
|
type: 'guardian_verification',
|
|
3457
3382
|
action: 'start_outbound',
|
|
3458
3383
|
channel: 'voice',
|
|
3459
|
-
assistantId: 'self',
|
|
3460
3384
|
destination: '555-123-4567',
|
|
3461
3385
|
}, mockSocket, ctx);
|
|
3462
3386
|
|
|
@@ -3496,7 +3420,6 @@ describe('outbound voice verification', () => {
|
|
|
3496
3420
|
type: 'guardian_verification',
|
|
3497
3421
|
action: 'start_outbound',
|
|
3498
3422
|
channel: 'voice',
|
|
3499
|
-
assistantId: 'self',
|
|
3500
3423
|
destination: '+15559876543',
|
|
3501
3424
|
rebind: false,
|
|
3502
3425
|
}, mockSocket, ctx);
|
|
@@ -3514,7 +3437,6 @@ describe('outbound voice verification', () => {
|
|
|
3514
3437
|
type: 'guardian_verification',
|
|
3515
3438
|
action: 'start_outbound',
|
|
3516
3439
|
channel: 'voice',
|
|
3517
|
-
assistantId: 'self',
|
|
3518
3440
|
destination: '+15551234567',
|
|
3519
3441
|
}, mockSocket, startCtx);
|
|
3520
3442
|
|
|
@@ -3524,7 +3446,6 @@ describe('outbound voice verification', () => {
|
|
|
3524
3446
|
type: 'guardian_verification',
|
|
3525
3447
|
action: 'resend_outbound',
|
|
3526
3448
|
channel: 'voice',
|
|
3527
|
-
assistantId: 'self',
|
|
3528
3449
|
}, mockSocket, ctx);
|
|
3529
3450
|
|
|
3530
3451
|
const resp = lastResponse();
|
|
@@ -3540,7 +3461,6 @@ describe('outbound voice verification', () => {
|
|
|
3540
3461
|
type: 'guardian_verification',
|
|
3541
3462
|
action: 'start_outbound',
|
|
3542
3463
|
channel: 'voice',
|
|
3543
|
-
assistantId: 'self',
|
|
3544
3464
|
destination: '+15551234567',
|
|
3545
3465
|
}, mockSocket, startCtx);
|
|
3546
3466
|
|
|
@@ -3550,7 +3470,6 @@ describe('outbound voice verification', () => {
|
|
|
3550
3470
|
type: 'guardian_verification',
|
|
3551
3471
|
action: 'cancel_outbound',
|
|
3552
3472
|
channel: 'voice',
|
|
3553
|
-
assistantId: 'self',
|
|
3554
3473
|
}, mockSocket, ctx);
|
|
3555
3474
|
|
|
3556
3475
|
const resp = lastResponse();
|
|
@@ -3588,7 +3507,6 @@ describe('outbound voice verification', () => {
|
|
|
3588
3507
|
type: 'guardian_verification',
|
|
3589
3508
|
action: 'start_outbound',
|
|
3590
3509
|
channel: 'voice',
|
|
3591
|
-
assistantId: 'self',
|
|
3592
3510
|
destination: '+15551234567',
|
|
3593
3511
|
}, mockSocket, ctx);
|
|
3594
3512
|
|
|
@@ -3604,7 +3522,6 @@ describe('outbound voice verification', () => {
|
|
|
3604
3522
|
type: 'guardian_verification',
|
|
3605
3523
|
action: 'start_outbound',
|
|
3606
3524
|
channel: 'voice',
|
|
3607
|
-
assistantId: 'self',
|
|
3608
3525
|
}, mockSocket, ctx);
|
|
3609
3526
|
|
|
3610
3527
|
const resp = lastResponse();
|
|
@@ -3637,7 +3554,6 @@ describe('M1–M4 hardening coverage', () => {
|
|
|
3637
3554
|
type: 'guardian_verification',
|
|
3638
3555
|
action: 'start_outbound',
|
|
3639
3556
|
channel: 'sms',
|
|
3640
|
-
assistantId: 'self',
|
|
3641
3557
|
destination: '+15551234567',
|
|
3642
3558
|
}, mockSocket, ctx);
|
|
3643
3559
|
|
|
@@ -3658,7 +3574,6 @@ describe('M1–M4 hardening coverage', () => {
|
|
|
3658
3574
|
type: 'guardian_verification',
|
|
3659
3575
|
action: 'start_outbound',
|
|
3660
3576
|
channel: 'sms',
|
|
3661
|
-
assistantId: 'self',
|
|
3662
3577
|
destination: '+15551234567',
|
|
3663
3578
|
}, mockSocket, startCtx);
|
|
3664
3579
|
|
|
@@ -3673,7 +3588,6 @@ describe('M1–M4 hardening coverage', () => {
|
|
|
3673
3588
|
type: 'guardian_verification',
|
|
3674
3589
|
action: 'resend_outbound',
|
|
3675
3590
|
channel: 'sms',
|
|
3676
|
-
assistantId: 'self',
|
|
3677
3591
|
}, mockSocket, ctx);
|
|
3678
3592
|
|
|
3679
3593
|
const resp = lastResponse();
|
|
@@ -3692,7 +3606,6 @@ describe('M1–M4 hardening coverage', () => {
|
|
|
3692
3606
|
type: 'guardian_verification',
|
|
3693
3607
|
action: 'start_outbound',
|
|
3694
3608
|
channel: 'telegram',
|
|
3695
|
-
assistantId: 'self',
|
|
3696
3609
|
destination: '@someuser',
|
|
3697
3610
|
}, mockSocket, ctx);
|
|
3698
3611
|
|
|
@@ -302,24 +302,18 @@ describe('ChannelReadinessService', () => {
|
|
|
302
302
|
expect(snapshot.reasons).toEqual([]);
|
|
303
303
|
});
|
|
304
304
|
|
|
305
|
-
test('remote cache
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const key = context?.assistantId ?? '__default__';
|
|
312
|
-
remoteCalls[key] = (remoteCalls[key] ?? 0) + 1;
|
|
313
|
-
return [{ name: 'remote', passed: true, message: `ok-${key}` }];
|
|
314
|
-
},
|
|
315
|
-
};
|
|
305
|
+
test('remote cache uses fixed internal scope (no per-assistantId scoping)', async () => {
|
|
306
|
+
const probe = makeProbe(
|
|
307
|
+
'sms',
|
|
308
|
+
[{ name: 'local', passed: true, message: 'ok' }],
|
|
309
|
+
[{ name: 'remote', passed: true, message: 'ok' }],
|
|
310
|
+
);
|
|
316
311
|
service.registerProbe(probe);
|
|
317
312
|
|
|
318
|
-
|
|
319
|
-
await service.getReadiness('sms', true
|
|
320
|
-
await service.getReadiness('sms', true
|
|
313
|
+
// All calls share the same cache key since there is no assistantId dimension
|
|
314
|
+
await service.getReadiness('sms', true);
|
|
315
|
+
await service.getReadiness('sms', true);
|
|
321
316
|
|
|
322
|
-
expect(
|
|
323
|
-
expect(remoteCalls['ast-beta']).toBe(1);
|
|
317
|
+
expect(probe.remoteCallCount).toBe(1);
|
|
324
318
|
});
|
|
325
319
|
});
|
|
@@ -63,7 +63,7 @@ mock.module('../config/loader.js', () => ({
|
|
|
63
63
|
setNestedValue: () => {},
|
|
64
64
|
}));
|
|
65
65
|
|
|
66
|
-
import { _resetLegacyDeprecationWarning,check, classifyRisk, generateAllowlistOptions, generateScopeOptions } from '../permissions/checker.js';
|
|
66
|
+
import { _resetLegacyDeprecationWarning,check, classifyRisk, generateAllowlistOptions, generateScopeOptions, SCOPE_AWARE_TOOLS } from '../permissions/checker.js';
|
|
67
67
|
import { getDefaultRuleTemplates } from '../permissions/defaults.js';
|
|
68
68
|
import { addRule, clearCache, findHighestPriorityRule } from '../permissions/trust-store.js';
|
|
69
69
|
import type { TrustRule } from '../permissions/types.js';
|
|
@@ -1341,21 +1341,42 @@ describe('Permission Checker', () => {
|
|
|
1341
1341
|
expect(options[2]).toEqual({ label: 'everywhere', scope: 'everywhere' });
|
|
1342
1342
|
});
|
|
1343
1343
|
|
|
1344
|
-
test('scope
|
|
1344
|
+
test('scope-aware tools all produce the same directory-based ordering', () => {
|
|
1345
1345
|
const workingDir = join(homedir(), 'projects', 'myapp');
|
|
1346
1346
|
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
expect(
|
|
1350
|
-
expect(nonHostOpts[nonHostOpts.length - 1].scope).toBe('everywhere');
|
|
1347
|
+
const bashOpts = generateScopeOptions(workingDir, 'bash');
|
|
1348
|
+
expect(bashOpts[0].scope).toBe(workingDir);
|
|
1349
|
+
expect(bashOpts[bashOpts.length - 1].scope).toBe('everywhere');
|
|
1351
1350
|
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
expect(hostOpts[0].scope).toBe(workingDir);
|
|
1355
|
-
expect(hostOpts[hostOpts.length - 1].scope).toBe('everywhere');
|
|
1351
|
+
const hostBashOpts = generateScopeOptions(workingDir, 'host_bash');
|
|
1352
|
+
expect(bashOpts.map(o => o.scope)).toEqual(hostBashOpts.map(o => o.scope));
|
|
1356
1353
|
|
|
1357
|
-
|
|
1358
|
-
expect(
|
|
1354
|
+
const fileOpts = generateScopeOptions(workingDir, 'file_write');
|
|
1355
|
+
expect(bashOpts.map(o => o.scope)).toEqual(fileOpts.map(o => o.scope));
|
|
1356
|
+
});
|
|
1357
|
+
|
|
1358
|
+
test('returns empty for non-scoped tools', () => {
|
|
1359
|
+
const workingDir = join(homedir(), 'projects', 'myapp');
|
|
1360
|
+
expect(generateScopeOptions(workingDir, 'web_fetch')).toHaveLength(0);
|
|
1361
|
+
expect(generateScopeOptions(workingDir, 'browser_navigate')).toHaveLength(0);
|
|
1362
|
+
expect(generateScopeOptions(workingDir, 'skill_load')).toHaveLength(0);
|
|
1363
|
+
expect(generateScopeOptions(workingDir, 'credential_store')).toHaveLength(0);
|
|
1364
|
+
expect(generateScopeOptions(workingDir, 'computer_use_click')).toHaveLength(0);
|
|
1365
|
+
expect(generateScopeOptions(workingDir, 'my_custom_mcp_tool')).toHaveLength(0);
|
|
1366
|
+
});
|
|
1367
|
+
|
|
1368
|
+
test('returns directory options when toolName is omitted (backward compat)', () => {
|
|
1369
|
+
const options = generateScopeOptions('/home/user/project');
|
|
1370
|
+
expect(options).toHaveLength(3);
|
|
1371
|
+
expect(options[0].scope).toBe('/home/user/project');
|
|
1372
|
+
});
|
|
1373
|
+
|
|
1374
|
+
test('SCOPE_AWARE_TOOLS contains only filesystem and shell tools', () => {
|
|
1375
|
+
expect(SCOPE_AWARE_TOOLS).toEqual(new Set([
|
|
1376
|
+
'bash', 'host_bash',
|
|
1377
|
+
'file_read', 'file_write', 'file_edit',
|
|
1378
|
+
'host_file_read', 'host_file_write', 'host_file_edit',
|
|
1379
|
+
]));
|
|
1359
1380
|
});
|
|
1360
1381
|
});
|
|
1361
1382
|
|
|
@@ -583,6 +583,10 @@ describe('AssistantConfigSchema', () => {
|
|
|
583
583
|
userConsultTimeoutSeconds: 120,
|
|
584
584
|
ttsPlaybackDelayMs: 3000,
|
|
585
585
|
accessRequestPollIntervalMs: 500,
|
|
586
|
+
guardianWaitUpdateInitialIntervalMs: 5000,
|
|
587
|
+
guardianWaitUpdateInitialWindowMs: 30000,
|
|
588
|
+
guardianWaitUpdateSteadyMinIntervalMs: 7000,
|
|
589
|
+
guardianWaitUpdateSteadyMaxIntervalMs: 10000,
|
|
586
590
|
disclosure: {
|
|
587
591
|
enabled: true,
|
|
588
592
|
text: 'At the very beginning of the call, introduce yourself as an assistant calling on behalf of the person you represent. Do not say "AI assistant".',
|