@vellumai/assistant 0.4.9 → 0.4.11
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 +24 -0
- package/Dockerfile +1 -1
- package/README.md +16 -9
- package/package.json +1 -1
- package/src/__tests__/account-registry.test.ts +1 -0
- package/src/__tests__/actor-token-service.test.ts +1 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/asset-materialize-tool.test.ts +7 -0
- package/src/__tests__/asset-search-tool.test.ts +7 -0
- package/src/__tests__/browser-fill-credential.test.ts +1 -0
- package/src/__tests__/call-start-guardian-guard.test.ts +1 -0
- package/src/__tests__/channel-approval-routes.test.ts +29 -0
- package/src/__tests__/channel-guardian.test.ts +2143 -1546
- package/src/__tests__/channel-retry-sweep.test.ts +169 -14
- package/src/__tests__/claude-code-tool-profiles.test.ts +1 -0
- package/src/__tests__/computer-use-tools.test.ts +1 -0
- package/src/__tests__/contacts-tools.test.ts +1 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +1 -0
- package/src/__tests__/credential-policy-validate.test.ts +97 -0
- package/src/__tests__/credential-security-e2e.test.ts +1 -0
- package/src/__tests__/credential-vault-unit.test.ts +1 -0
- package/src/__tests__/credential-vault.test.ts +1 -0
- package/src/__tests__/delete-managed-skill-tool.test.ts +1 -0
- package/src/__tests__/file-edit-tool.test.ts +1 -0
- package/src/__tests__/file-read-tool.test.ts +1 -0
- package/src/__tests__/file-write-tool.test.ts +1 -0
- package/src/__tests__/followup-tools.test.ts +1 -0
- package/src/__tests__/gateway-only-guard.test.ts +1 -1
- package/src/__tests__/guardian-control-plane-policy.test.ts +5 -4
- package/src/__tests__/guardian-grant-minting.test.ts +3 -0
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +4 -3
- package/src/__tests__/guardian-routing-state.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +1 -0
- package/src/__tests__/headless-browser-navigate.test.ts +1 -0
- package/src/__tests__/headless-browser-read-tools.test.ts +1 -0
- package/src/__tests__/headless-browser-snapshot.test.ts +1 -0
- package/src/__tests__/host-file-edit-tool.test.ts +1 -0
- package/src/__tests__/host-file-read-tool.test.ts +1 -0
- package/src/__tests__/host-file-write-tool.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -0
- package/src/__tests__/lifecycle-docs-guard.test.ts +207 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -0
- package/src/__tests__/media-reuse-story.e2e.test.ts +8 -0
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/playbook-execution.test.ts +1 -0
- package/src/__tests__/playbook-tools.test.ts +1 -0
- package/src/__tests__/relay-server.test.ts +4 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +1 -0
- package/src/__tests__/schedule-tools.test.ts +1 -0
- package/src/__tests__/secret-onetime-send.test.ts +4 -0
- package/src/__tests__/secret-scanner-executor.test.ts +2 -0
- package/src/__tests__/send-notification-tool.test.ts +2 -0
- package/src/__tests__/shell-credential-ref.test.ts +1 -0
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +1 -0
- package/src/__tests__/skill-script-runner-host.test.ts +1 -0
- package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -0
- package/src/__tests__/skill-script-runner.test.ts +1 -0
- package/src/__tests__/skill-tool-factory.test.ts +1 -0
- package/src/__tests__/subagent-tools.test.ts +1 -1
- package/src/__tests__/swarm-recursion.test.ts +1 -0
- package/src/__tests__/swarm-session-integration.test.ts +1 -0
- package/src/__tests__/swarm-tool.test.ts +1 -0
- package/src/__tests__/task-management-tools.test.ts +1 -0
- package/src/__tests__/task-tools.test.ts +1 -0
- package/src/__tests__/terminal-tools.test.ts +1 -0
- package/src/__tests__/tool-approval-handler.test.ts +2 -2
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -0
- package/src/__tests__/tool-executor-shell-integration.test.ts +1 -0
- package/src/__tests__/tool-executor.test.ts +1 -0
- package/src/__tests__/trust-context-guards.test.ts +218 -0
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +6 -0
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +6 -0
- package/src/__tests__/trusted-contact-multichannel.test.ts +1 -0
- package/src/__tests__/trusted-contact-verification.test.ts +1 -0
- package/src/__tests__/view-image-tool.test.ts +1 -0
- package/src/calls/guardian-dispatch.ts +4 -4
- package/src/cli/mcp.ts +183 -3
- package/src/config/bundled-skills/agentmail/SKILL.md +4 -4
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +1 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +17 -119
- package/src/config/system-prompt.ts +4 -2
- package/src/config/vellum-skills/twilio-setup/SKILL.md +1 -1
- package/src/daemon/computer-use-session.ts +1 -0
- package/src/daemon/session-agent-loop.ts +1 -1
- package/src/daemon/session-memory.ts +2 -2
- package/src/daemon/session-runtime-assembly.ts +2 -2
- package/src/daemon/session-tool-setup.ts +1 -1
- package/src/mcp/client.ts +55 -6
- package/src/mcp/manager.ts +9 -0
- package/src/mcp/mcp-oauth-provider.ts +347 -0
- package/src/memory/channel-delivery-store.ts +1 -0
- package/src/memory/db-init.ts +4 -0
- package/src/memory/delivery-status.ts +43 -0
- package/src/memory/guardian-bindings.ts +3 -3
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +108 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/migrations/registry.ts +6 -0
- package/src/memory/schema.ts +1 -1
- package/src/runtime/actor-trust-resolver.ts +13 -4
- package/src/runtime/channel-retry-sweep.ts +31 -14
- package/src/runtime/guardian-context-resolver.ts +25 -64
- package/src/runtime/guardian-outbound-actions.ts +399 -108
- package/src/runtime/guardian-vellum-migration.ts +1 -23
- package/src/runtime/guardian-verification-templates.ts +66 -30
- package/src/runtime/local-actor-identity.ts +4 -6
- package/src/runtime/middleware/actor-token.ts +2 -8
- package/src/runtime/routes/channel-route-shared.ts +0 -1
- package/src/runtime/routes/inbound-message-handler.ts +3 -4
- package/src/runtime/tool-grant-request-helper.ts +1 -1
- package/src/tools/credentials/policy-validate.ts +22 -0
- package/src/tools/guardian-control-plane-policy.ts +2 -2
- package/src/tools/types.ts +1 -1
package/ARCHITECTURE.md
CHANGED
|
@@ -2085,3 +2085,27 @@ The daemon uses a single fixed internal scope constant — `DAEMON_INTERNAL_ASSI
|
|
|
2085
2085
|
|------|---------|
|
|
2086
2086
|
| `src/runtime/assistant-scope.ts` | Exports `DAEMON_INTERNAL_ASSISTANT_ID` constant |
|
|
2087
2087
|
| `src/__tests__/assistant-id-boundary-guard.test.ts` | Guard tests enforcing the identity boundary |
|
|
2088
|
+
|
|
2089
|
+
### Canonical Trust-Context Model
|
|
2090
|
+
|
|
2091
|
+
The guardian trust system uses a three-valued `TrustClass` — `'guardian'`, `'trusted_contact'`, or `'unknown'` — as the single vocabulary for actor trust classification across all channels and runtime paths. There is no legacy `actorRole` concept; all trust decisions flow through `TrustClass`.
|
|
2092
|
+
|
|
2093
|
+
**`GuardianRuntimeContext`** (in `src/daemon/session-runtime-assembly.ts`) is the single runtime carrier for trust state on channel-originated turns. It carries `trustClass`, guardian identity fields, and requester metadata. The `guardianPrincipalId` field is typed as `?: string` (optional but non-nullable) — a principal ID is present when a guardian binding exists but is never `null`.
|
|
2094
|
+
|
|
2095
|
+
**Explicit trust gates:** `guardianTrustClass` is a **required** field in `ToolContext` (in `src/tools/types.ts`). Every tool execution must carry a trust classification — the field is not optional. This ensures trust-gated tool policies (guardian control-plane restrictions, host-tool blocking for untrusted actors) cannot be bypassed by omitting the classification.
|
|
2096
|
+
|
|
2097
|
+
**Guardian bindings** (in `src/memory/guardian-bindings.ts`) always carry `guardianPrincipalId: string` as a required, non-null field. A binding without a principal ID is invalid and cannot be created.
|
|
2098
|
+
|
|
2099
|
+
**Strict retry sweep parsing:** The channel retry sweep (`src/runtime/channel-retry-sweep.ts`) uses `parseGuardianRuntimeContext()` which validates `trustClass` against the canonical three-value set. There is no fallback to a legacy `actorRole` field — stored payloads that lack a valid `trustClass` are rejected deterministically to prevent silent privilege escalation. When `guardianCtx` is entirely absent from a stored payload (pre-guardian events), the sweep synthesizes an explicit `trustClass: 'unknown'` context so that replay never proceeds without a trust classification.
|
|
2100
|
+
|
|
2101
|
+
**Rollout note — legacy `actorRole` payloads:** Previously failed events stored with only `actorRole` (no `trustClass`) will be marked as failed on each retry attempt and eventually dead-lettered after exhausting `RETRY_MAX_ATTEMPTS`. This is an intentional security tradeoff: replaying these events with inferred trust would violate the explicit-trust model. If legacy events need to be recovered, they should be repaired (adding a canonical `trustClass` to the stored payload) before replay via `replayDeadLetters()`.
|
|
2102
|
+
|
|
2103
|
+
**Key files:**
|
|
2104
|
+
|
|
2105
|
+
| File | Purpose |
|
|
2106
|
+
|------|---------|
|
|
2107
|
+
| `src/daemon/session-runtime-assembly.ts` | `GuardianRuntimeContext` type definition |
|
|
2108
|
+
| `src/tools/types.ts` | `ToolContext.guardianTrustClass` (required trust gate) |
|
|
2109
|
+
| `src/runtime/channel-retry-sweep.ts` | Strict `trustClass` parser for retry sweep |
|
|
2110
|
+
| `src/memory/guardian-bindings.ts` | `GuardianBinding` with required `guardianPrincipalId` |
|
|
2111
|
+
| `src/__tests__/trust-context-guards.test.ts` | Guard tests enforcing trust-context type invariants |
|
package/Dockerfile
CHANGED
|
@@ -87,7 +87,7 @@ RUN echo 'Dir::State "/data/dpkg";' > /etc/apt/apt.conf.d/99data-dir && \
|
|
|
87
87
|
chown -R assistant:assistant /data/apt /data/dpkg
|
|
88
88
|
|
|
89
89
|
ENV PATH="/data/usr/bin:/data/usr/sbin:${PATH}"
|
|
90
|
-
ENV LD_LIBRARY_PATH="/data/usr/lib:/data/usr/lib/x86_64-linux-gnu:${LD_LIBRARY_PATH}"
|
|
90
|
+
ENV LD_LIBRARY_PATH="/data/usr/lib:/data/usr/lib/x86_64-linux-gnu:/data/usr/lib/aarch64-linux-gnu:${LD_LIBRARY_PATH}"
|
|
91
91
|
|
|
92
92
|
USER root
|
|
93
93
|
|
package/README.md
CHANGED
|
@@ -58,30 +58,37 @@ When a release includes relevant updates, the daemon materializes release notes
|
|
|
58
58
|
|
|
59
59
|
## Usage
|
|
60
60
|
|
|
61
|
-
###
|
|
61
|
+
### Lifecycle management (recommended)
|
|
62
|
+
|
|
63
|
+
Use the `vellum` CLI to manage daemon and gateway processes:
|
|
62
64
|
|
|
63
65
|
```bash
|
|
64
|
-
|
|
66
|
+
vellum wake # start daemon + gateway from current checkout
|
|
67
|
+
vellum ps # list assistants and per-assistant process status
|
|
68
|
+
vellum sleep # stop daemon + gateway (directory-agnostic)
|
|
65
69
|
```
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
> **Note:** `vellum wake` requires a hatched assistant. Run `vellum hatch` first, or launch the macOS app which handles hatching automatically.
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
bun run src/index.ts
|
|
71
|
-
```
|
|
73
|
+
### Development: raw bun commands
|
|
72
74
|
|
|
73
|
-
|
|
75
|
+
For low-level development (e.g., working on the daemon itself):
|
|
74
76
|
|
|
75
77
|
```bash
|
|
76
|
-
bun run src/index.ts
|
|
78
|
+
bun run src/index.ts daemon start # start daemon only
|
|
79
|
+
bun run src/index.ts # interactive CLI session
|
|
80
|
+
bun run src/index.ts dev # dev mode (auto-restart on file changes)
|
|
77
81
|
```
|
|
78
82
|
|
|
79
83
|
### CLI commands
|
|
80
84
|
|
|
81
85
|
| Command | Description |
|
|
82
86
|
|---------|-------------|
|
|
87
|
+
| `vellum wake` | Start daemon + gateway from current checkout |
|
|
88
|
+
| `vellum sleep` | Stop daemon + gateway processes |
|
|
89
|
+
| `vellum ps` | List assistants and per-assistant process status |
|
|
83
90
|
| `vellum` | Launch interactive CLI session |
|
|
84
|
-
| `vellum daemon start\|stop\|restart\|status` | Manage the daemon process |
|
|
91
|
+
| `vellum daemon start\|stop\|restart\|status` | Manage the daemon process (low-level) |
|
|
85
92
|
| `vellum dev` | Run daemon with auto-restart on file changes |
|
|
86
93
|
| `vellum sessions list\|new\|export\|clear` | Manage conversation sessions |
|
|
87
94
|
| `vellum config set\|get\|list` | Manage configuration |
|
package/package.json
CHANGED
|
@@ -69,6 +69,7 @@ const dummyContext: ToolContext = {
|
|
|
69
69
|
workingDir: sandboxDir,
|
|
70
70
|
sessionId: 'sess-test',
|
|
71
71
|
conversationId: 'conv-test',
|
|
72
|
+
guardianTrustClass: 'guardian',
|
|
72
73
|
};
|
|
73
74
|
|
|
74
75
|
// ---------------------------------------------------------------------------
|
|
@@ -322,6 +323,7 @@ describe('AssetMaterializeTool visibility policy', () => {
|
|
|
322
323
|
workingDir: sandboxDir,
|
|
323
324
|
sessionId: 'sess-test',
|
|
324
325
|
conversationId: otherConv.id,
|
|
326
|
+
guardianTrustClass: 'guardian',
|
|
325
327
|
};
|
|
326
328
|
|
|
327
329
|
const result = await assetMaterializeTool.execute(
|
|
@@ -344,6 +346,7 @@ describe('AssetMaterializeTool visibility policy', () => {
|
|
|
344
346
|
workingDir: sandboxDir,
|
|
345
347
|
sessionId: 'sess-test',
|
|
346
348
|
conversationId: privateConv.id,
|
|
349
|
+
guardianTrustClass: 'guardian',
|
|
347
350
|
};
|
|
348
351
|
|
|
349
352
|
const result = await assetMaterializeTool.execute(
|
|
@@ -367,6 +370,7 @@ describe('AssetMaterializeTool visibility policy', () => {
|
|
|
367
370
|
workingDir: sandboxDir,
|
|
368
371
|
sessionId: 'sess-test',
|
|
369
372
|
conversationId: otherConv.id,
|
|
373
|
+
guardianTrustClass: 'guardian',
|
|
370
374
|
};
|
|
371
375
|
|
|
372
376
|
const result = await assetMaterializeTool.execute(
|
|
@@ -391,6 +395,7 @@ describe('AssetMaterializeTool visibility policy', () => {
|
|
|
391
395
|
workingDir: sandboxDir,
|
|
392
396
|
sessionId: 'sess-test',
|
|
393
397
|
conversationId: standardConv.id,
|
|
398
|
+
guardianTrustClass: 'guardian',
|
|
394
399
|
};
|
|
395
400
|
|
|
396
401
|
const result = await assetMaterializeTool.execute(
|
|
@@ -417,6 +422,7 @@ describe('AssetMaterializeTool visibility policy', () => {
|
|
|
417
422
|
workingDir: sandboxDir,
|
|
418
423
|
sessionId: 'sess-test',
|
|
419
424
|
conversationId: privateConv2.id,
|
|
425
|
+
guardianTrustClass: 'guardian',
|
|
420
426
|
};
|
|
421
427
|
|
|
422
428
|
const result = await assetMaterializeTool.execute(
|
|
@@ -444,6 +450,7 @@ describe('AssetMaterializeTool visibility policy', () => {
|
|
|
444
450
|
workingDir: sandboxDir,
|
|
445
451
|
sessionId: 'sess-test',
|
|
446
452
|
conversationId: otherConv.id,
|
|
453
|
+
guardianTrustClass: 'guardian',
|
|
447
454
|
};
|
|
448
455
|
|
|
449
456
|
const result = await assetMaterializeTool.execute(
|
|
@@ -88,6 +88,7 @@ const dummyContext: ToolContext = {
|
|
|
88
88
|
workingDir: '/tmp',
|
|
89
89
|
sessionId: 'sess-test',
|
|
90
90
|
conversationId: 'conv-test',
|
|
91
|
+
guardianTrustClass: 'guardian',
|
|
91
92
|
};
|
|
92
93
|
|
|
93
94
|
// ---------------------------------------------------------------------------
|
|
@@ -378,6 +379,7 @@ describe('AssetSearchTool visibility policy', () => {
|
|
|
378
379
|
workingDir: '/tmp',
|
|
379
380
|
sessionId: 'sess-test',
|
|
380
381
|
conversationId: otherConv.id,
|
|
382
|
+
guardianTrustClass: 'guardian',
|
|
381
383
|
};
|
|
382
384
|
|
|
383
385
|
const result = await assetSearchTool.execute({}, context);
|
|
@@ -396,6 +398,7 @@ describe('AssetSearchTool visibility policy', () => {
|
|
|
396
398
|
workingDir: '/tmp',
|
|
397
399
|
sessionId: 'sess-test',
|
|
398
400
|
conversationId: privateConv.id,
|
|
401
|
+
guardianTrustClass: 'guardian',
|
|
399
402
|
};
|
|
400
403
|
|
|
401
404
|
const result = await assetSearchTool.execute({}, context);
|
|
@@ -415,6 +418,7 @@ describe('AssetSearchTool visibility policy', () => {
|
|
|
415
418
|
workingDir: '/tmp',
|
|
416
419
|
sessionId: 'sess-test',
|
|
417
420
|
conversationId: otherPrivateConv.id,
|
|
421
|
+
guardianTrustClass: 'guardian',
|
|
418
422
|
};
|
|
419
423
|
|
|
420
424
|
const result = await assetSearchTool.execute({}, context);
|
|
@@ -434,6 +438,7 @@ describe('AssetSearchTool visibility policy', () => {
|
|
|
434
438
|
workingDir: '/tmp',
|
|
435
439
|
sessionId: 'sess-test',
|
|
436
440
|
conversationId: standardConv.id,
|
|
441
|
+
guardianTrustClass: 'guardian',
|
|
437
442
|
};
|
|
438
443
|
|
|
439
444
|
const result = await assetSearchTool.execute({}, context);
|
|
@@ -457,6 +462,7 @@ describe('AssetSearchTool visibility policy', () => {
|
|
|
457
462
|
workingDir: '/tmp',
|
|
458
463
|
sessionId: 'sess-test',
|
|
459
464
|
conversationId: otherConv.id,
|
|
465
|
+
guardianTrustClass: 'guardian',
|
|
460
466
|
};
|
|
461
467
|
|
|
462
468
|
const result = await assetSearchTool.execute({}, context);
|
|
@@ -472,6 +478,7 @@ describe('AssetSearchTool visibility policy', () => {
|
|
|
472
478
|
workingDir: '/tmp',
|
|
473
479
|
sessionId: 'sess-test',
|
|
474
480
|
conversationId: conv.id,
|
|
481
|
+
guardianTrustClass: 'guardian',
|
|
475
482
|
};
|
|
476
483
|
|
|
477
484
|
const result = await assetSearchTool.execute({}, context);
|
|
@@ -246,6 +246,7 @@ describe('inbound callback metadata triggers decision handling', () => {
|
|
|
246
246
|
channel: 'telegram',
|
|
247
247
|
guardianExternalUserId: 'telegram-user-default',
|
|
248
248
|
guardianDeliveryChatId: 'chat-123',
|
|
249
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
249
250
|
});
|
|
250
251
|
});
|
|
251
252
|
|
|
@@ -321,6 +322,7 @@ describe('inbound text matching approval phrases triggers decision handling', ()
|
|
|
321
322
|
channel: 'telegram',
|
|
322
323
|
guardianExternalUserId: 'telegram-user-default',
|
|
323
324
|
guardianDeliveryChatId: 'chat-123',
|
|
325
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
324
326
|
});
|
|
325
327
|
});
|
|
326
328
|
|
|
@@ -384,6 +386,7 @@ describe('non-decision messages during pending approval (legacy fallback)', () =
|
|
|
384
386
|
channel: 'telegram',
|
|
385
387
|
guardianExternalUserId: 'telegram-user-default',
|
|
386
388
|
guardianDeliveryChatId: 'chat-123',
|
|
389
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
387
390
|
});
|
|
388
391
|
});
|
|
389
392
|
|
|
@@ -458,6 +461,7 @@ describe('empty content with callbackData bypasses validation', () => {
|
|
|
458
461
|
channel: 'telegram',
|
|
459
462
|
guardianExternalUserId: 'telegram-user-default',
|
|
460
463
|
guardianDeliveryChatId: 'chat-123',
|
|
464
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
461
465
|
});
|
|
462
466
|
});
|
|
463
467
|
|
|
@@ -551,6 +555,7 @@ describe('callback requestId validation', () => {
|
|
|
551
555
|
channel: 'telegram',
|
|
552
556
|
guardianExternalUserId: 'telegram-user-default',
|
|
553
557
|
guardianDeliveryChatId: 'chat-123',
|
|
558
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
554
559
|
});
|
|
555
560
|
});
|
|
556
561
|
|
|
@@ -651,6 +656,7 @@ describe('no immediate reply after approval decision', () => {
|
|
|
651
656
|
channel: 'telegram',
|
|
652
657
|
guardianExternalUserId: 'telegram-user-default',
|
|
653
658
|
guardianDeliveryChatId: 'chat-123',
|
|
659
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
654
660
|
});
|
|
655
661
|
});
|
|
656
662
|
|
|
@@ -773,6 +779,7 @@ describe('SMS channel approval decisions', () => {
|
|
|
773
779
|
channel: 'sms',
|
|
774
780
|
guardianExternalUserId: 'sms-user-default',
|
|
775
781
|
guardianDeliveryChatId: 'sms-chat-123',
|
|
782
|
+
guardianPrincipalId: 'sms-user-default',
|
|
776
783
|
});
|
|
777
784
|
});
|
|
778
785
|
|
|
@@ -1026,6 +1033,7 @@ describe('guardian decision scoping — multiple pending approvals', () => {
|
|
|
1026
1033
|
channel: 'telegram',
|
|
1027
1034
|
guardianExternalUserId: 'guardian-scope-user',
|
|
1028
1035
|
guardianDeliveryChatId: 'guardian-scope-chat',
|
|
1036
|
+
guardianPrincipalId: 'guardian-scope-user',
|
|
1029
1037
|
});
|
|
1030
1038
|
|
|
1031
1039
|
const deliverSpy = spyOn(gatewayClient, 'deliverChannelReply').mockResolvedValue(undefined);
|
|
@@ -1099,6 +1107,7 @@ describe('ambiguous plain-text decision with multiple pending requests', () => {
|
|
|
1099
1107
|
channel: 'telegram',
|
|
1100
1108
|
guardianExternalUserId: 'guardian-ambig-user',
|
|
1101
1109
|
guardianDeliveryChatId: 'guardian-ambig-chat',
|
|
1110
|
+
guardianPrincipalId: 'guardian-ambig-user',
|
|
1102
1111
|
});
|
|
1103
1112
|
|
|
1104
1113
|
const deliverSpy = spyOn(gatewayClient, 'deliverChannelReply').mockResolvedValue(undefined);
|
|
@@ -1548,6 +1557,7 @@ describe('conversational approval engine — standard path', () => {
|
|
|
1548
1557
|
channel: 'telegram',
|
|
1549
1558
|
guardianExternalUserId: 'telegram-user-default',
|
|
1550
1559
|
guardianDeliveryChatId: 'chat-123',
|
|
1560
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
1551
1561
|
});
|
|
1552
1562
|
});
|
|
1553
1563
|
|
|
@@ -1717,6 +1727,7 @@ describe('guardian conversational approval via conversation engine', () => {
|
|
|
1717
1727
|
channel: 'telegram',
|
|
1718
1728
|
guardianExternalUserId: 'guardian-conv-user',
|
|
1719
1729
|
guardianDeliveryChatId: 'guardian-conv-chat',
|
|
1730
|
+
guardianPrincipalId: 'guardian-conv-user',
|
|
1720
1731
|
});
|
|
1721
1732
|
|
|
1722
1733
|
const deliverSpy = spyOn(gatewayClient, 'deliverChannelReply').mockResolvedValue(undefined);
|
|
@@ -1781,6 +1792,7 @@ describe('guardian conversational approval via conversation engine', () => {
|
|
|
1781
1792
|
channel: 'telegram',
|
|
1782
1793
|
guardianExternalUserId: 'guardian-nlp-user',
|
|
1783
1794
|
guardianDeliveryChatId: 'guardian-nlp-chat',
|
|
1795
|
+
guardianPrincipalId: 'guardian-nlp-user',
|
|
1784
1796
|
});
|
|
1785
1797
|
|
|
1786
1798
|
const deliverSpy = spyOn(gatewayClient, 'deliverChannelReply').mockResolvedValue(undefined);
|
|
@@ -1843,6 +1855,7 @@ describe('guardian conversational approval via conversation engine', () => {
|
|
|
1843
1855
|
channel: 'telegram',
|
|
1844
1856
|
guardianExternalUserId: 'guardian-dg-user',
|
|
1845
1857
|
guardianDeliveryChatId: 'guardian-dg-chat',
|
|
1858
|
+
guardianPrincipalId: 'guardian-dg-user',
|
|
1846
1859
|
});
|
|
1847
1860
|
|
|
1848
1861
|
const deliverSpy = spyOn(gatewayClient, 'deliverChannelReply').mockResolvedValue(undefined);
|
|
@@ -1892,6 +1905,7 @@ describe('guardian conversational approval via conversation engine', () => {
|
|
|
1892
1905
|
channel: 'telegram',
|
|
1893
1906
|
guardianExternalUserId: 'guardian-multi-user',
|
|
1894
1907
|
guardianDeliveryChatId: 'guardian-multi-chat',
|
|
1908
|
+
guardianPrincipalId: 'guardian-multi-user',
|
|
1895
1909
|
});
|
|
1896
1910
|
|
|
1897
1911
|
const deliverSpy = spyOn(gatewayClient, 'deliverChannelReply').mockResolvedValue(undefined);
|
|
@@ -1981,6 +1995,7 @@ describe('keep_pending remains conversational — standard path', () => {
|
|
|
1981
1995
|
channel: 'telegram',
|
|
1982
1996
|
guardianExternalUserId: 'telegram-user-default',
|
|
1983
1997
|
guardianDeliveryChatId: 'chat-123',
|
|
1998
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
1984
1999
|
});
|
|
1985
2000
|
});
|
|
1986
2001
|
|
|
@@ -2029,6 +2044,7 @@ describe('keep_pending remains conversational — guardian path', () => {
|
|
|
2029
2044
|
channel: 'telegram',
|
|
2030
2045
|
guardianExternalUserId: 'guardian-user-fb',
|
|
2031
2046
|
guardianDeliveryChatId: 'guardian-chat-fb',
|
|
2047
|
+
guardianPrincipalId: 'guardian-user-fb',
|
|
2032
2048
|
});
|
|
2033
2049
|
|
|
2034
2050
|
const deliverSpy = spyOn(gatewayClient, 'deliverChannelReply').mockResolvedValue(undefined);
|
|
@@ -2091,6 +2107,7 @@ describe('requester cancel of guardian-gated pending request', () => {
|
|
|
2091
2107
|
channel: 'telegram',
|
|
2092
2108
|
guardianExternalUserId: 'guardian-cancel',
|
|
2093
2109
|
guardianDeliveryChatId: 'guardian-cancel-chat',
|
|
2110
|
+
guardianPrincipalId: 'guardian-cancel',
|
|
2094
2111
|
});
|
|
2095
2112
|
});
|
|
2096
2113
|
|
|
@@ -2346,6 +2363,7 @@ describe('engine decision race condition — standard path', () => {
|
|
|
2346
2363
|
channel: 'telegram',
|
|
2347
2364
|
guardianExternalUserId: 'telegram-user-default',
|
|
2348
2365
|
guardianDeliveryChatId: 'chat-123',
|
|
2366
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
2349
2367
|
});
|
|
2350
2368
|
});
|
|
2351
2369
|
|
|
@@ -2407,6 +2425,7 @@ describe('engine decision race condition — guardian path', () => {
|
|
|
2407
2425
|
channel: 'telegram',
|
|
2408
2426
|
guardianExternalUserId: 'guardian-race-user',
|
|
2409
2427
|
guardianDeliveryChatId: 'guardian-race-chat',
|
|
2428
|
+
guardianPrincipalId: 'guardian-race-user',
|
|
2410
2429
|
});
|
|
2411
2430
|
|
|
2412
2431
|
const deliverSpy = spyOn(gatewayClient, 'deliverChannelReply').mockResolvedValue(undefined);
|
|
@@ -2482,12 +2501,14 @@ describe('non-decision status reply for different channels', () => {
|
|
|
2482
2501
|
channel: 'telegram',
|
|
2483
2502
|
guardianExternalUserId: 'telegram-user-default',
|
|
2484
2503
|
guardianDeliveryChatId: 'chat-123',
|
|
2504
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
2485
2505
|
});
|
|
2486
2506
|
createBinding({
|
|
2487
2507
|
assistantId: 'self',
|
|
2488
2508
|
channel: 'sms',
|
|
2489
2509
|
guardianExternalUserId: 'telegram-user-default',
|
|
2490
2510
|
guardianDeliveryChatId: 'chat-123',
|
|
2511
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
2491
2512
|
});
|
|
2492
2513
|
});
|
|
2493
2514
|
|
|
@@ -2572,6 +2593,7 @@ describe('background channel processing approval prompts', () => {
|
|
|
2572
2593
|
channel: 'telegram',
|
|
2573
2594
|
guardianExternalUserId: 'telegram-user-default',
|
|
2574
2595
|
guardianDeliveryChatId: 'chat-123',
|
|
2596
|
+
guardianPrincipalId: 'telegram-user-default',
|
|
2575
2597
|
});
|
|
2576
2598
|
|
|
2577
2599
|
const deliverPromptSpy = spyOn(gatewayClient, 'deliverApprovalPrompt').mockResolvedValue(undefined);
|
|
@@ -2625,6 +2647,7 @@ describe('background channel processing approval prompts', () => {
|
|
|
2625
2647
|
channel: 'telegram',
|
|
2626
2648
|
guardianExternalUserId: ' telegram-user-default ',
|
|
2627
2649
|
guardianDeliveryChatId: 'chat-123',
|
|
2650
|
+
guardianPrincipalId: ' telegram-user-default ',
|
|
2628
2651
|
});
|
|
2629
2652
|
|
|
2630
2653
|
const deliverPromptSpy = spyOn(gatewayClient, 'deliverApprovalPrompt').mockResolvedValue(undefined);
|
|
@@ -2676,6 +2699,7 @@ describe('background channel processing approval prompts', () => {
|
|
|
2676
2699
|
channel: 'telegram',
|
|
2677
2700
|
guardianExternalUserId: 'guardian-user-other',
|
|
2678
2701
|
guardianDeliveryChatId: 'guardian-chat-other',
|
|
2702
|
+
guardianPrincipalId: 'guardian-user-other',
|
|
2679
2703
|
});
|
|
2680
2704
|
|
|
2681
2705
|
const processCalls: Array<{ options?: Record<string, unknown> }> = [];
|
|
@@ -2779,6 +2803,8 @@ describe('NL approval routing via destination-scoped canonical requests', () =>
|
|
|
2779
2803
|
channel: 'telegram',
|
|
2780
2804
|
guardianExternalUserId: guardianUserId,
|
|
2781
2805
|
guardianDeliveryChatId: guardianChatId,
|
|
2806
|
+
|
|
2807
|
+
guardianPrincipalId: guardianUserId,
|
|
2782
2808
|
});
|
|
2783
2809
|
|
|
2784
2810
|
// Create canonical tool_approval request WITHOUT guardianExternalUserId
|
|
@@ -2835,6 +2861,8 @@ describe('NL approval routing via destination-scoped canonical requests', () =>
|
|
|
2835
2861
|
channel: 'telegram',
|
|
2836
2862
|
guardianExternalUserId: guardianUserId,
|
|
2837
2863
|
guardianDeliveryChatId: differentChatId,
|
|
2864
|
+
|
|
2865
|
+
guardianPrincipalId: guardianUserId,
|
|
2838
2866
|
});
|
|
2839
2867
|
|
|
2840
2868
|
// Create canonical pending_question WITHOUT guardianExternalUserId
|
|
@@ -2890,6 +2918,7 @@ describe('trusted-contact self-approval blocked before guardian approval row exi
|
|
|
2890
2918
|
channel: 'telegram',
|
|
2891
2919
|
guardianExternalUserId: 'guardian-tc-selfapproval',
|
|
2892
2920
|
guardianDeliveryChatId: 'guardian-tc-selfapproval-chat',
|
|
2921
|
+
guardianPrincipalId: 'guardian-tc-selfapproval',
|
|
2893
2922
|
});
|
|
2894
2923
|
});
|
|
2895
2924
|
|