@vellumai/assistant 0.3.18 → 0.3.20
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 +155 -15
- package/Dockerfile +1 -0
- package/README.md +40 -4
- package/docs/architecture/integrations.md +7 -11
- package/docs/architecture/security.md +80 -0
- package/package.json +1 -1
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +58 -0
- package/src/__tests__/approval-primitive.test.ts +540 -0
- package/src/__tests__/assistant-feature-flag-guard.test.ts +206 -0
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +198 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +272 -0
- package/src/__tests__/call-controller.test.ts +605 -104
- package/src/__tests__/channel-invite-transport.test.ts +264 -0
- package/src/__tests__/checker.test.ts +60 -0
- package/src/__tests__/cli.test.ts +42 -1
- package/src/__tests__/config-schema.test.ts +11 -127
- package/src/__tests__/config-watcher.test.ts +0 -8
- package/src/__tests__/daemon-lifecycle.test.ts +1 -0
- package/src/__tests__/daemon-server-session-init.test.ts +8 -2
- package/src/__tests__/diff.test.ts +22 -0
- package/src/__tests__/guardian-action-copy-generator.test.ts +5 -0
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +779 -0
- package/src/__tests__/guardian-action-late-reply.test.ts +546 -1
- package/src/__tests__/guardian-actions-endpoint.test.ts +774 -0
- package/src/__tests__/guardian-control-plane-policy.test.ts +36 -3
- package/src/__tests__/guardian-dispatch.test.ts +185 -1
- package/src/__tests__/guardian-grant-minting.test.ts +532 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +367 -0
- package/src/__tests__/invite-redemption-service.test.ts +306 -0
- package/src/__tests__/ipc-snapshot.test.ts +58 -0
- package/src/__tests__/notification-decision-fallback.test.ts +88 -0
- package/src/__tests__/remote-skill-policy.test.ts +215 -0
- package/src/__tests__/sandbox-diagnostics.test.ts +6 -249
- package/src/__tests__/sandbox-host-parity.test.ts +6 -13
- package/src/__tests__/scoped-approval-grants.test.ts +521 -0
- package/src/__tests__/scoped-grant-security-matrix.test.ts +444 -0
- package/src/__tests__/script-proxy-session-manager.test.ts +1 -19
- package/src/__tests__/session-load-history-repair.test.ts +169 -2
- package/src/__tests__/session-runtime-assembly.test.ts +33 -5
- package/src/__tests__/skill-feature-flags-integration.test.ts +171 -0
- package/src/__tests__/skill-feature-flags.test.ts +188 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +141 -0
- package/src/__tests__/skill-mirror-parity.test.ts +1 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +363 -0
- package/src/__tests__/system-prompt.test.ts +1 -1
- package/src/__tests__/terminal-sandbox.test.ts +142 -9
- package/src/__tests__/terminal-tools.test.ts +2 -93
- package/src/__tests__/thread-seed-composer.test.ts +18 -0
- package/src/__tests__/tool-approval-handler.test.ts +350 -0
- package/src/__tests__/trust-store.test.ts +2 -0
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +8 -10
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +533 -0
- package/src/agent/loop.ts +36 -1
- package/src/approvals/approval-primitive.ts +381 -0
- package/src/approvals/guardian-decision-primitive.ts +191 -0
- package/src/calls/call-controller.ts +276 -212
- package/src/calls/call-domain.ts +56 -6
- package/src/calls/guardian-dispatch.ts +56 -0
- package/src/calls/relay-server.ts +13 -0
- package/src/calls/types.ts +1 -1
- package/src/calls/voice-session-bridge.ts +59 -4
- package/src/cli/core-commands.ts +0 -4
- package/src/cli.ts +76 -34
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +179 -0
- package/src/config/assistant-feature-flags.ts +162 -0
- package/src/config/bundled-skills/api-mapping/icon.svg +18 -0
- package/src/config/bundled-skills/messaging/TOOLS.json +30 -0
- package/src/config/bundled-skills/messaging/tools/slack-delete-message.ts +24 -0
- package/src/config/bundled-skills/notifications/SKILL.md +18 -0
- package/src/config/bundled-skills/reminder/SKILL.md +49 -2
- package/src/config/bundled-skills/time-based-actions/SKILL.md +49 -2
- package/src/config/bundled-skills/voice-setup/SKILL.md +122 -0
- package/src/config/core-schema.ts +1 -1
- package/src/config/env-registry.ts +10 -0
- package/src/config/feature-flag-registry.json +61 -0
- package/src/config/loader.ts +22 -1
- package/src/config/sandbox-schema.ts +0 -39
- package/src/config/schema.ts +12 -2
- package/src/config/skill-state.ts +34 -0
- package/src/config/skills-schema.ts +26 -0
- package/src/config/skills.ts +9 -0
- package/src/config/system-prompt.ts +110 -46
- package/src/config/templates/SOUL.md +1 -1
- package/src/config/types.ts +19 -1
- package/src/config/vellum-skills/catalog.json +1 -1
- package/src/config/vellum-skills/guardian-verify-setup/SKILL.md +1 -0
- package/src/config/vellum-skills/sms-setup/SKILL.md +1 -1
- package/src/config/vellum-skills/telegram-setup/SKILL.md +1 -1
- package/src/config/vellum-skills/trusted-contacts/SKILL.md +104 -3
- package/src/config/vellum-skills/twilio-setup/SKILL.md +1 -1
- package/src/daemon/config-watcher.ts +0 -1
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/guardian-invite-intent.ts +124 -0
- package/src/daemon/handlers/avatar.ts +68 -0
- package/src/daemon/handlers/browser.ts +2 -2
- package/src/daemon/handlers/config-channels.ts +18 -0
- package/src/daemon/handlers/guardian-actions.ts +120 -0
- package/src/daemon/handlers/index.ts +4 -0
- package/src/daemon/handlers/sessions.ts +19 -0
- package/src/daemon/handlers/shared.ts +3 -1
- package/src/daemon/handlers/skills.ts +45 -2
- package/src/daemon/install-cli-launchers.ts +58 -13
- package/src/daemon/ipc-contract/guardian-actions.ts +53 -0
- package/src/daemon/ipc-contract/sessions.ts +8 -2
- package/src/daemon/ipc-contract/settings.ts +25 -2
- package/src/daemon/ipc-contract/skills.ts +1 -0
- package/src/daemon/ipc-contract-inventory.json +10 -0
- package/src/daemon/ipc-contract.ts +4 -0
- package/src/daemon/lifecycle.ts +6 -2
- package/src/daemon/main.ts +1 -0
- package/src/daemon/server.ts +1 -0
- package/src/daemon/session-lifecycle.ts +52 -7
- package/src/daemon/session-memory.ts +45 -0
- package/src/daemon/session-process.ts +260 -422
- package/src/daemon/session-runtime-assembly.ts +12 -0
- package/src/daemon/session-skill-tools.ts +14 -1
- package/src/daemon/session-tool-setup.ts +5 -0
- package/src/daemon/session.ts +11 -0
- package/src/daemon/tool-side-effects.ts +35 -9
- package/src/index.ts +0 -2
- package/src/memory/conversation-display-order-migration.ts +44 -0
- package/src/memory/conversation-queries.ts +2 -0
- package/src/memory/conversation-store.ts +91 -0
- package/src/memory/db-init.ts +13 -1
- package/src/memory/embedding-local.ts +22 -8
- package/src/memory/guardian-action-store.ts +133 -2
- package/src/memory/guardian-verification.ts +1 -1
- package/src/memory/ingress-invite-store.ts +95 -1
- package/src/memory/migrations/033-scoped-approval-grants.ts +51 -0
- package/src/memory/migrations/034-guardian-action-tool-metadata.ts +12 -0
- package/src/memory/migrations/035-guardian-action-supersession.ts +23 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/schema.ts +35 -1
- package/src/memory/scoped-approval-grants.ts +518 -0
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/types.ts +5 -0
- package/src/notifications/decision-engine.ts +49 -12
- package/src/notifications/emit-signal.ts +7 -0
- package/src/notifications/signal.ts +7 -0
- package/src/notifications/thread-seed-composer.ts +2 -1
- package/src/permissions/checker.ts +27 -0
- package/src/runtime/channel-approval-types.ts +16 -6
- package/src/runtime/channel-approvals.ts +19 -15
- package/src/runtime/channel-invite-transport.ts +85 -0
- package/src/runtime/channel-invite-transports/telegram.ts +105 -0
- package/src/runtime/guardian-action-grant-minter.ts +154 -0
- package/src/runtime/guardian-action-message-composer.ts +30 -0
- package/src/runtime/guardian-decision-types.ts +91 -0
- package/src/runtime/http-server.ts +23 -1
- package/src/runtime/ingress-service.ts +22 -0
- package/src/runtime/invite-redemption-service.ts +181 -0
- package/src/runtime/invite-redemption-templates.ts +39 -0
- package/src/runtime/routes/call-routes.ts +2 -1
- package/src/runtime/routes/guardian-action-routes.ts +206 -0
- package/src/runtime/routes/guardian-approval-interception.ts +66 -74
- package/src/runtime/routes/inbound-message-handler.ts +568 -409
- package/src/runtime/routes/pairing-routes.ts +4 -0
- package/src/security/encrypted-store.ts +31 -17
- package/src/security/keychain.ts +176 -2
- package/src/security/secure-keys.ts +97 -0
- package/src/security/tool-approval-digest.ts +67 -0
- package/src/skills/remote-skill-policy.ts +131 -0
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/browser-manager.ts +46 -32
- package/src/tools/browser/browser-screencast.ts +2 -2
- package/src/tools/calls/call-start.ts +1 -1
- package/src/tools/executor.ts +22 -17
- package/src/tools/network/script-proxy/session-manager.ts +1 -5
- package/src/tools/skills/load.ts +22 -8
- package/src/tools/system/avatar-generator.ts +119 -0
- package/src/tools/system/navigate-settings.ts +65 -0
- package/src/tools/system/open-system-settings.ts +75 -0
- package/src/tools/system/voice-config.ts +121 -32
- package/src/tools/terminal/backends/native.ts +40 -19
- package/src/tools/terminal/backends/types.ts +3 -3
- package/src/tools/terminal/parser.ts +1 -1
- package/src/tools/terminal/sandbox-diagnostics.ts +6 -87
- package/src/tools/terminal/sandbox.ts +1 -12
- package/src/tools/terminal/shell.ts +3 -31
- package/src/tools/tool-approval-handler.ts +141 -3
- package/src/tools/tool-manifest.ts +6 -0
- package/src/tools/types.ts +6 -0
- package/src/util/diff.ts +36 -13
- package/Dockerfile.sandbox +0 -5
- package/src/__tests__/doordash-client.test.ts +0 -187
- package/src/__tests__/doordash-session.test.ts +0 -154
- package/src/__tests__/signup-e2e.test.ts +0 -354
- package/src/__tests__/terminal-sandbox-docker.test.ts +0 -1065
- package/src/__tests__/terminal-sandbox.integration.test.ts +0 -180
- package/src/cli/doordash.ts +0 -1057
- package/src/config/bundled-skills/doordash/SKILL.md +0 -163
- package/src/config/templates/LOOKS.md +0 -25
- package/src/doordash/cart-queries.ts +0 -787
- package/src/doordash/client.ts +0 -1016
- package/src/doordash/order-queries.ts +0 -85
- package/src/doordash/queries.ts +0 -13
- package/src/doordash/query-extractor.ts +0 -94
- package/src/doordash/search-queries.ts +0 -203
- package/src/doordash/session.ts +0 -84
- package/src/doordash/store-queries.ts +0 -246
- package/src/doordash/types.ts +0 -367
- package/src/tools/terminal/backends/docker.ts +0 -379
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Guardian action decision IPC types.
|
|
2
|
+
// Enables desktop clients to fetch pending guardian prompts and submit
|
|
3
|
+
// button decisions deterministically (without text parsing).
|
|
4
|
+
|
|
5
|
+
// === Client -> Server ===
|
|
6
|
+
|
|
7
|
+
export interface GuardianActionsPendingRequest {
|
|
8
|
+
type: 'guardian_actions_pending_request';
|
|
9
|
+
conversationId: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface GuardianActionDecision {
|
|
13
|
+
type: 'guardian_action_decision';
|
|
14
|
+
requestId: string;
|
|
15
|
+
action: string;
|
|
16
|
+
conversationId?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// === Server -> Client ===
|
|
20
|
+
|
|
21
|
+
export interface GuardianActionsPendingResponse {
|
|
22
|
+
type: 'guardian_actions_pending_response';
|
|
23
|
+
conversationId: string;
|
|
24
|
+
prompts: Array<{
|
|
25
|
+
requestId: string;
|
|
26
|
+
requestCode: string;
|
|
27
|
+
state: string;
|
|
28
|
+
questionText: string;
|
|
29
|
+
toolName: string | null;
|
|
30
|
+
actions: Array<{ action: string; label: string }>;
|
|
31
|
+
expiresAt: number;
|
|
32
|
+
conversationId: string;
|
|
33
|
+
callSessionId: string | null;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface GuardianActionDecisionResponse {
|
|
38
|
+
type: 'guardian_action_decision_response';
|
|
39
|
+
applied: boolean;
|
|
40
|
+
reason?: string;
|
|
41
|
+
requestId?: string;
|
|
42
|
+
userText?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// --- Domain-level union aliases (consumed by the barrel file) ---
|
|
46
|
+
|
|
47
|
+
export type _GuardianActionsClientMessages =
|
|
48
|
+
| GuardianActionsPendingRequest
|
|
49
|
+
| GuardianActionDecision;
|
|
50
|
+
|
|
51
|
+
export type _GuardianActionsServerMessages =
|
|
52
|
+
| GuardianActionsPendingResponse
|
|
53
|
+
| GuardianActionDecisionResponse;
|
|
@@ -156,6 +156,11 @@ export interface ConversationSearchRequest {
|
|
|
156
156
|
maxMessagesPerConversation?: number;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
export interface ReorderThreadsRequest {
|
|
160
|
+
type: 'reorder_threads';
|
|
161
|
+
updates: Array<{ sessionId: string; displayOrder: number | null; isPinned: boolean }>;
|
|
162
|
+
}
|
|
163
|
+
|
|
159
164
|
// === Server → Client ===
|
|
160
165
|
|
|
161
166
|
export interface ConversationSearchMatchingMessage {
|
|
@@ -213,7 +218,7 @@ export interface AssistantAttention {
|
|
|
213
218
|
|
|
214
219
|
export interface SessionListResponse {
|
|
215
220
|
type: 'session_list_response';
|
|
216
|
-
sessions: Array<{ id: string; title: string; createdAt?: number; updatedAt: number; threadType?: ThreadType; source?: string; channelBinding?: ChannelBinding; conversationOriginChannel?: ChannelId; conversationOriginInterface?: InterfaceId; assistantAttention?: AssistantAttention }>;
|
|
221
|
+
sessions: Array<{ id: string; title: string; createdAt?: number; updatedAt: number; threadType?: ThreadType; source?: string; channelBinding?: ChannelBinding; conversationOriginChannel?: ChannelId; conversationOriginInterface?: InterfaceId; assistantAttention?: AssistantAttention; displayOrder?: number; isPinned?: boolean }>;
|
|
217
222
|
/** Whether more sessions exist beyond the returned page. */
|
|
218
223
|
hasMore?: boolean;
|
|
219
224
|
}
|
|
@@ -392,7 +397,8 @@ export type _SessionsClientMessages =
|
|
|
392
397
|
| SessionRenameRequest
|
|
393
398
|
| SessionsClearRequest
|
|
394
399
|
| ConversationSearchRequest
|
|
395
|
-
| MessageContentRequest
|
|
400
|
+
| MessageContentRequest
|
|
401
|
+
| ReorderThreadsRequest;
|
|
396
402
|
|
|
397
403
|
export type _SessionsServerMessages =
|
|
398
404
|
| AuthResult
|
|
@@ -9,6 +9,13 @@ export interface VoiceConfigUpdateRequest {
|
|
|
9
9
|
activationKey: string;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/** Request from the client to generate a custom avatar via Gemini. */
|
|
13
|
+
export interface GenerateAvatarRequest {
|
|
14
|
+
type: 'generate_avatar';
|
|
15
|
+
/** Text description of the desired avatar appearance. */
|
|
16
|
+
description: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
12
19
|
// === Server → Client ===
|
|
13
20
|
|
|
14
21
|
/** Sent by the daemon to update a client-side setting (e.g. activation key). */
|
|
@@ -20,7 +27,23 @@ export interface ClientSettingsUpdate {
|
|
|
20
27
|
value: string;
|
|
21
28
|
}
|
|
22
29
|
|
|
30
|
+
/** Sent by the daemon after the avatar image has been regenerated and saved to disk. */
|
|
31
|
+
export interface AvatarUpdated {
|
|
32
|
+
type: 'avatar_updated';
|
|
33
|
+
/** Absolute path to the updated avatar image file. */
|
|
34
|
+
avatarPath: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Response to a generate_avatar request indicating success or failure. */
|
|
38
|
+
export interface GenerateAvatarResponse {
|
|
39
|
+
type: 'generate_avatar_response';
|
|
40
|
+
/** Whether the avatar was generated successfully. */
|
|
41
|
+
success: boolean;
|
|
42
|
+
/** Error message when success is false. */
|
|
43
|
+
error?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
23
46
|
// --- Domain-level union aliases (consumed by the barrel file) ---
|
|
24
47
|
|
|
25
|
-
export type _SettingsClientMessages = VoiceConfigUpdateRequest;
|
|
26
|
-
export type _SettingsServerMessages = ClientSettingsUpdate;
|
|
48
|
+
export type _SettingsClientMessages = VoiceConfigUpdateRequest | GenerateAvatarRequest;
|
|
49
|
+
export type _SettingsServerMessages = ClientSettingsUpdate | AvatarUpdated | GenerateAvatarResponse;
|
|
@@ -95,6 +95,7 @@ export interface SkillsListResponse {
|
|
|
95
95
|
updateAvailable: boolean;
|
|
96
96
|
userInvocable: boolean;
|
|
97
97
|
clawhub?: { author: string; stars: number; installs: number; reports: number; publishedAt: string };
|
|
98
|
+
provenance?: { kind: 'first-party' | 'third-party' | 'local'; provider?: string; originId?: string; sourceUrl?: string };
|
|
98
99
|
}>;
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"_ComputerUseClientMessages",
|
|
6
6
|
"_DiagnosticsClientMessages",
|
|
7
7
|
"_DocumentsClientMessages",
|
|
8
|
+
"_GuardianActionsClientMessages",
|
|
8
9
|
"_InboxClientMessages",
|
|
9
10
|
"_IntegrationsClientMessages",
|
|
10
11
|
"_MessagesClientMessages",
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
"_ComputerUseServerMessages",
|
|
29
30
|
"_DiagnosticsServerMessages",
|
|
30
31
|
"_DocumentsServerMessages",
|
|
32
|
+
"_GuardianActionsServerMessages",
|
|
31
33
|
"_InboxServerMessages",
|
|
32
34
|
"_IntegrationsServerMessages",
|
|
33
35
|
"_MemoryServerMessages",
|
|
@@ -86,7 +88,10 @@
|
|
|
86
88
|
"fork_shared_app",
|
|
87
89
|
"gallery_install",
|
|
88
90
|
"gallery_list",
|
|
91
|
+
"generate_avatar",
|
|
89
92
|
"get_signing_identity_response",
|
|
93
|
+
"guardian_action_decision",
|
|
94
|
+
"guardian_actions_pending_request",
|
|
90
95
|
"guardian_verification",
|
|
91
96
|
"heartbeat_checklist_read",
|
|
92
97
|
"heartbeat_checklist_write",
|
|
@@ -124,6 +129,7 @@
|
|
|
124
129
|
"reminder_cancel",
|
|
125
130
|
"reminders_list",
|
|
126
131
|
"remove_trust_rule",
|
|
132
|
+
"reorder_threads",
|
|
127
133
|
"ride_shotgun_start",
|
|
128
134
|
"ride_shotgun_stop",
|
|
129
135
|
"sandbox_set",
|
|
@@ -210,6 +216,7 @@
|
|
|
210
216
|
"assistant_text_delta",
|
|
211
217
|
"assistant_thinking_delta",
|
|
212
218
|
"auth_result",
|
|
219
|
+
"avatar_updated",
|
|
213
220
|
"browser_cdp_request",
|
|
214
221
|
"browser_frame",
|
|
215
222
|
"browser_handoff_request",
|
|
@@ -236,9 +243,12 @@
|
|
|
236
243
|
"fork_shared_app_response",
|
|
237
244
|
"gallery_install_response",
|
|
238
245
|
"gallery_list_response",
|
|
246
|
+
"generate_avatar_response",
|
|
239
247
|
"generation_cancelled",
|
|
240
248
|
"generation_handoff",
|
|
241
249
|
"get_signing_identity",
|
|
250
|
+
"guardian_action_decision_response",
|
|
251
|
+
"guardian_actions_pending_response",
|
|
242
252
|
"guardian_verification_response",
|
|
243
253
|
"heartbeat_alert",
|
|
244
254
|
"heartbeat_checklist_response",
|
|
@@ -18,6 +18,7 @@ export * from './ipc-contract/browser.js';
|
|
|
18
18
|
export * from './ipc-contract/computer-use.js';
|
|
19
19
|
export * from './ipc-contract/diagnostics.js';
|
|
20
20
|
export * from './ipc-contract/documents.js';
|
|
21
|
+
export * from './ipc-contract/guardian-actions.js';
|
|
21
22
|
export * from './ipc-contract/inbox.js';
|
|
22
23
|
export * from './ipc-contract/integrations.js';
|
|
23
24
|
export * from './ipc-contract/memory.js';
|
|
@@ -42,6 +43,7 @@ import type { _BrowserClientMessages, _BrowserServerMessages } from './ipc-contr
|
|
|
42
43
|
import type { _ComputerUseClientMessages, _ComputerUseServerMessages } from './ipc-contract/computer-use.js';
|
|
43
44
|
import type { _DiagnosticsClientMessages, _DiagnosticsServerMessages } from './ipc-contract/diagnostics.js';
|
|
44
45
|
import type { _DocumentsClientMessages, _DocumentsServerMessages } from './ipc-contract/documents.js';
|
|
46
|
+
import type { _GuardianActionsClientMessages, _GuardianActionsServerMessages } from './ipc-contract/guardian-actions.js';
|
|
45
47
|
import type { _InboxClientMessages, _InboxServerMessages } from './ipc-contract/inbox.js';
|
|
46
48
|
import type { _IntegrationsClientMessages, _IntegrationsServerMessages } from './ipc-contract/integrations.js';
|
|
47
49
|
import type { _MemoryServerMessages } from './ipc-contract/memory.js';
|
|
@@ -83,6 +85,7 @@ export type ClientMessage =
|
|
|
83
85
|
| _BrowserClientMessages
|
|
84
86
|
| _SubagentsClientMessages
|
|
85
87
|
| _DocumentsClientMessages
|
|
88
|
+
| _GuardianActionsClientMessages
|
|
86
89
|
| _WorkspaceClientMessages
|
|
87
90
|
| _SchedulesClientMessages
|
|
88
91
|
| _DiagnosticsClientMessages
|
|
@@ -107,6 +110,7 @@ export type ServerMessage =
|
|
|
107
110
|
| _BrowserServerMessages
|
|
108
111
|
| _SubagentsServerMessages
|
|
109
112
|
| _DocumentsServerMessages
|
|
113
|
+
| _GuardianActionsServerMessages
|
|
110
114
|
| _MemoryServerMessages
|
|
111
115
|
| _WorkspaceServerMessages
|
|
112
116
|
| _SchedulesServerMessages
|
package/src/daemon/lifecycle.ts
CHANGED
|
@@ -57,7 +57,7 @@ import type { ServerMessage } from './ipc-protocol.js';
|
|
|
57
57
|
import { initializeProvidersAndTools, registerMessagingProviders,registerWatcherProviders } from './providers-setup.js';
|
|
58
58
|
import { seedInterfaceFiles } from './seed-files.js';
|
|
59
59
|
import { DaemonServer } from './server.js';
|
|
60
|
-
import { setGuardianActionCopyGenerator, setGuardianFollowUpConversationGenerator } from './session-process.js';
|
|
60
|
+
import { setApprovalConversationGenerator, setGuardianActionCopyGenerator, setGuardianFollowUpConversationGenerator } from './session-process.js';
|
|
61
61
|
import { initSlashPairingContext } from './session-slash.js';
|
|
62
62
|
import { installShutdownHandlers } from './shutdown-handlers.js';
|
|
63
63
|
|
|
@@ -307,7 +307,11 @@ export async function runDaemon(): Promise<void> {
|
|
|
307
307
|
server.persistAndProcessMessage(conversationId, content, attachmentIds, options, sourceChannel, sourceInterface),
|
|
308
308
|
interfacesDir: getInterfacesDir(),
|
|
309
309
|
approvalCopyGenerator: createApprovalCopyGenerator(),
|
|
310
|
-
approvalConversationGenerator:
|
|
310
|
+
approvalConversationGenerator: (() => {
|
|
311
|
+
const gen = createApprovalConversationGenerator();
|
|
312
|
+
setApprovalConversationGenerator(gen);
|
|
313
|
+
return gen;
|
|
314
|
+
})(),
|
|
311
315
|
guardianActionCopyGenerator: (() => {
|
|
312
316
|
const gen = createGuardianActionCopyGenerator();
|
|
313
317
|
setGuardianActionCopyGenerator(gen);
|
package/src/daemon/main.ts
CHANGED
package/src/daemon/server.ts
CHANGED
|
@@ -795,6 +795,7 @@ export class DaemonServer {
|
|
|
795
795
|
const resolvedInterface = resolveTurnInterface(sourceInterface);
|
|
796
796
|
session.setAssistantId(options?.assistantId ?? 'self');
|
|
797
797
|
session.setGuardianContext(options?.guardianContext ?? null);
|
|
798
|
+
await session.ensureActorScopedHistory();
|
|
798
799
|
session.setChannelCapabilities(resolveChannelCapabilities(sourceChannel, sourceInterface));
|
|
799
800
|
session.setCommandIntent(options?.commandIntent ?? null);
|
|
800
801
|
session.setTurnChannelContext({
|
|
@@ -19,10 +19,38 @@ import { repairHistory } from './history-repair.js';
|
|
|
19
19
|
import type { SurfaceData,SurfaceType, UsageStats } from './ipc-protocol.js';
|
|
20
20
|
import { unregisterCallNotifiers,unregisterWatchNotifiers } from './session-notifiers.js';
|
|
21
21
|
import type { MessageQueue } from './session-queue-manager.js';
|
|
22
|
+
import type { GuardianRuntimeContext } from './session-runtime-assembly.js';
|
|
22
23
|
import { resetSkillToolProjection } from './session-skill-tools.js';
|
|
23
24
|
|
|
24
25
|
const log = getLogger('session-lifecycle');
|
|
25
26
|
|
|
27
|
+
type GuardianActorRole = GuardianRuntimeContext['actorRole'];
|
|
28
|
+
|
|
29
|
+
function parseProvenanceActorRole(metadata: string | null): GuardianActorRole | undefined {
|
|
30
|
+
if (!metadata) return undefined;
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(metadata) as { provenanceActorRole?: unknown };
|
|
33
|
+
const role = parsed?.provenanceActorRole;
|
|
34
|
+
if (role === 'guardian' || role === 'non-guardian' || role === 'unverified_channel') {
|
|
35
|
+
return role;
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
// Ignore malformed metadata and treat as unknown provenance.
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isUntrustedActorRole(role: GuardianActorRole | undefined): boolean {
|
|
44
|
+
return role === 'non-guardian' || role === 'unverified_channel';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function filterMessagesForUntrustedActor(messages: conversationStore.MessageRow[]): conversationStore.MessageRow[] {
|
|
48
|
+
return messages.filter((m) => {
|
|
49
|
+
const provenanceRole = parseProvenanceActorRole(m.metadata);
|
|
50
|
+
return provenanceRole === 'non-guardian' || provenanceRole === 'unverified_channel';
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
26
54
|
// ── Context Interfaces ───────────────────────────────────────────────
|
|
27
55
|
|
|
28
56
|
export interface LoadFromDbContext {
|
|
@@ -31,6 +59,8 @@ export interface LoadFromDbContext {
|
|
|
31
59
|
usageStats: UsageStats;
|
|
32
60
|
contextCompactedMessageCount: number;
|
|
33
61
|
contextCompactedAt: number | null;
|
|
62
|
+
guardianContext?: { actorRole: GuardianActorRole };
|
|
63
|
+
loadedHistoryActorRole?: GuardianActorRole;
|
|
34
64
|
}
|
|
35
65
|
|
|
36
66
|
export interface AbortContext {
|
|
@@ -59,15 +89,28 @@ export interface DisposeContext extends AbortContext {
|
|
|
59
89
|
// ── loadFromDb ───────────────────────────────────────────────────────
|
|
60
90
|
|
|
61
91
|
export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
62
|
-
const
|
|
92
|
+
const actorRole = ctx.guardianContext?.actorRole;
|
|
93
|
+
const allDbMessages = conversationStore.getMessages(ctx.conversationId);
|
|
94
|
+
const dbMessages = isUntrustedActorRole(actorRole)
|
|
95
|
+
? filterMessagesForUntrustedActor(allDbMessages)
|
|
96
|
+
: allDbMessages;
|
|
63
97
|
|
|
64
98
|
const conv = conversationStore.getConversation(ctx.conversationId);
|
|
65
|
-
const contextSummary =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
99
|
+
const contextSummary = !isUntrustedActorRole(actorRole)
|
|
100
|
+
? conv?.contextSummary?.trim() || null
|
|
101
|
+
: null;
|
|
102
|
+
if (isUntrustedActorRole(actorRole)) {
|
|
103
|
+
// Compacted summaries may include trusted/guardian-only details, so we
|
|
104
|
+
// disable summary-based context for untrusted actor views.
|
|
105
|
+
ctx.contextCompactedMessageCount = 0;
|
|
106
|
+
ctx.contextCompactedAt = null;
|
|
107
|
+
} else {
|
|
108
|
+
ctx.contextCompactedMessageCount = Math.max(
|
|
109
|
+
0,
|
|
110
|
+
Math.min(conv?.contextCompactedMessageCount ?? 0, dbMessages.length),
|
|
111
|
+
);
|
|
112
|
+
ctx.contextCompactedAt = conv?.contextCompactedAt ?? null;
|
|
113
|
+
}
|
|
71
114
|
|
|
72
115
|
const parsedMessages: Message[] = dbMessages
|
|
73
116
|
.slice(ctx.contextCompactedMessageCount)
|
|
@@ -102,6 +145,8 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
|
|
|
102
145
|
};
|
|
103
146
|
}
|
|
104
147
|
|
|
148
|
+
ctx.loadedHistoryActorRole = actorRole;
|
|
149
|
+
|
|
105
150
|
log.info({ conversationId: ctx.conversationId, count: ctx.messages.length }, 'Loaded messages from DB');
|
|
106
151
|
}
|
|
107
152
|
|
|
@@ -39,6 +39,16 @@ export interface MemoryPrepareContext {
|
|
|
39
39
|
isInteractive?: boolean;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Returns true when the latest user turn is an internal tool-result-only
|
|
44
|
+
* message (no user-authored text/image content).
|
|
45
|
+
*/
|
|
46
|
+
function isToolResultOnlyUserTurn(message: Message | undefined): boolean {
|
|
47
|
+
return message?.role === 'user'
|
|
48
|
+
&& message.content.length > 0
|
|
49
|
+
&& message.content.every((block) => block.type === 'tool_result');
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
/**
|
|
43
53
|
* Build memory recall, dynamic profile, and conflict gate evaluation
|
|
44
54
|
* for a single agent loop turn. Returns the augmented run messages and
|
|
@@ -86,6 +96,41 @@ export async function prepareMemoryContext(
|
|
|
86
96
|
};
|
|
87
97
|
}
|
|
88
98
|
|
|
99
|
+
// Internal tool-result turns (assistant tool loop) should not trigger
|
|
100
|
+
// memory retrieval/profile injection. Injecting memory here repeats the
|
|
101
|
+
// same long recall block on every tool step and dramatically inflates
|
|
102
|
+
// per-step prompt size/latency.
|
|
103
|
+
const latestMessage = ctx.messages[ctx.messages.length - 1];
|
|
104
|
+
if (isToolResultOnlyUserTurn(latestMessage)) {
|
|
105
|
+
return {
|
|
106
|
+
runMessages: ctx.messages,
|
|
107
|
+
recall: {
|
|
108
|
+
enabled: false,
|
|
109
|
+
degraded: false,
|
|
110
|
+
injectedText: '',
|
|
111
|
+
lexicalHits: 0,
|
|
112
|
+
semanticHits: 0,
|
|
113
|
+
recencyHits: 0,
|
|
114
|
+
entityHits: 0,
|
|
115
|
+
relationSeedEntityCount: 0,
|
|
116
|
+
relationTraversedEdgeCount: 0,
|
|
117
|
+
relationNeighborEntityCount: 0,
|
|
118
|
+
relationExpandedItemCount: 0,
|
|
119
|
+
earlyTerminated: false,
|
|
120
|
+
mergedCount: 0,
|
|
121
|
+
selectedCount: 0,
|
|
122
|
+
rerankApplied: false,
|
|
123
|
+
injectedTokens: 0,
|
|
124
|
+
latencyMs: 0,
|
|
125
|
+
topCandidates: [],
|
|
126
|
+
} as Awaited<ReturnType<typeof buildMemoryRecall>>,
|
|
127
|
+
dynamicProfile: { text: '' },
|
|
128
|
+
softConflictInstruction: null,
|
|
129
|
+
recallInjectionStrategy: 'prepend_user_block',
|
|
130
|
+
conflictClarification: null,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
89
134
|
const runtimeConfig = getConfig();
|
|
90
135
|
const memoryEnabled = runtimeConfig.memory?.enabled !== false;
|
|
91
136
|
|