@vellumai/assistant 0.12.2 → 0.12.3-staging.1
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 +2 -0
- package/AGENTS.md +1 -1
- package/docs/architecture/integrations.md +7 -0
- package/docs/architecture/memory.md +17 -2
- package/docs/credential-execution-service.md +1 -1
- package/docs/desktop-browser-cli.md +7 -3
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
- package/node_modules/@vellumai/environments/src/shell.test.ts +21 -0
- package/node_modules/@vellumai/environments/src/shell.ts +24 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -2
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
- package/openapi.yaml +54 -5
- package/package.json +1 -1
- package/scripts/smoke-desktop-browser-cli.ts +1 -0
- package/scripts/sync-llm-catalog.ts +3 -0
- package/scripts/voice-ttft-spike.ts +2 -2
- package/src/__tests__/agent-loop.test.ts +259 -0
- package/src/__tests__/agent-wake-delegation-prompt.test.ts +64 -2
- package/src/__tests__/anthropic-provider.test.ts +55 -0
- package/src/__tests__/approval-interception-trust-gates.test.ts +40 -0
- package/src/__tests__/attachments-store.test.ts +22 -3
- package/src/__tests__/channel-approval.test.ts +9 -14
- package/src/__tests__/channel-reply-delivery.test.ts +56 -0
- package/src/__tests__/chat-credential-redaction.test.ts +23 -0
- package/src/__tests__/computer-use-screenshot-attachments.test.ts +411 -0
- package/src/__tests__/computer-use-screenshot-selection.test.ts +50 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop.test.ts +257 -6
- package/src/__tests__/conversation-attachments.test.ts +106 -0
- package/src/__tests__/conversation-fork-crud.test.ts +191 -0
- package/src/__tests__/conversation-rendered-delegation-state.test.ts +276 -0
- package/src/__tests__/credential-execution-client.test.ts +70 -53
- package/src/__tests__/db-conversation-tool-surface.test.ts +221 -0
- package/src/__tests__/events-tail-route.test.ts +33 -0
- package/src/__tests__/history-repair.test.ts +53 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +26 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +85 -1
- package/src/__tests__/llm-catalog-parity.test.ts +27 -4
- package/src/__tests__/oauth-apps-routes.test.ts +1 -0
- package/src/__tests__/oauth-commands-routes.test.ts +114 -101
- package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +1 -0
- package/src/__tests__/oauth-providers-routes.test.ts +2 -0
- package/src/__tests__/persist-media-references.test.ts +50 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +0 -1
- package/src/__tests__/run-conversation-turn-persistence.test.ts +138 -1
- package/src/__tests__/schedule-routes.test.ts +20 -0
- package/src/__tests__/scheduler-result-notification.test.ts +23 -4
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/secret-routes-platform-proxy.test.ts +86 -31
- package/src/__tests__/secret-routes-scrub.test.ts +22 -27
- package/src/__tests__/secret-scanner.test.ts +20 -0
- package/src/__tests__/secure-keys-managed-failover.test.ts +8 -0
- package/src/__tests__/secure-keys.test.ts +7 -3
- package/src/__tests__/server-tool-pairing.test.ts +107 -0
- package/src/__tests__/skills.test.ts +5 -4
- package/src/__tests__/subagent-tool-gate-mode.test.ts +226 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/tool-result-follow-up.test.ts +99 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +63 -0
- package/src/__tests__/unicode.test.ts +36 -0
- package/src/agent/loop.ts +37 -12
- package/src/agent/tool-result-follow-up.ts +70 -0
- package/src/api/attachment-provenance.test.ts +68 -0
- package/src/api/computer-use-tool.test.ts +55 -0
- package/src/api/computer-use-tool.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +3 -0
- package/src/api/events/desktop-activity-changed.ts +10 -0
- package/src/api/events/question-request.ts +1 -0
- package/src/api/index.ts +11 -0
- package/src/api/responses/conversation-message.ts +3 -0
- package/src/approvals/approval-primitive.ts +5 -2
- package/src/approvals/scoped-approval-grants.ts +6 -2
- package/src/browser/virtual-desktop-target.ts +1 -2
- package/src/cli/commands/__tests__/cli-test-harness.ts +21 -3
- package/src/cli/commands/__tests__/plugins.test.ts +20 -1
- package/src/cli/commands/__tests__/schedules.test.ts +14 -0
- package/src/cli/commands/bash.help.ts +4 -3
- package/src/cli/commands/browser.help.ts +5 -1
- package/src/cli/commands/credentials.help.ts +3 -3
- package/src/cli/commands/oauth/index.help.ts +10 -0
- package/src/cli/commands/oauth/providers.ts +12 -0
- package/src/cli/commands/oauth/request.test.ts +179 -2
- package/src/cli/commands/oauth/request.ts +41 -10
- package/src/cli/commands/plugins.ts +12 -5
- package/src/cli/commands/schedules.ts +2 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +41 -0
- package/src/cli/lib/__tests__/local-plugin-upgrade.test.ts +133 -51
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +8 -2
- package/src/cli/lib/bundled-marketplace.json +855 -0
- package/src/cli/lib/bundled-plugin-packages.json +783 -1
- package/src/cli/lib/inspect-plugin.ts +11 -4
- package/src/cli/lib/upgrade-plugin.ts +19 -11
- package/src/cli/output.ts +18 -4
- package/src/config/__tests__/default-provider.test.ts +4 -0
- package/src/config/bundled-skills/schedule/SKILL.md +6 -6
- package/src/config/loader.ts +9 -17
- package/src/config/platform-identity.ts +8 -8
- package/src/config/profile-text-generation.test.ts +51 -0
- package/src/config/profile-text-generation.ts +51 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +12 -0
- package/src/config/schemas/llm.ts +7 -2
- package/src/config/schemas/mcp.ts +5 -1
- package/src/config/schemas/memory-v3.ts +12 -0
- package/src/credential-execution/ces-runtime.ts +2 -2
- package/src/credential-execution/executable-discovery.ts +36 -134
- package/src/credential-execution/process-manager.test.ts +20 -24
- package/src/credential-execution/process-manager.ts +24 -19
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +43 -0
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +36 -0
- package/src/daemon/assistant-attachments.ts +20 -12
- package/src/daemon/chat-credential-redaction.ts +16 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +74 -3
- package/src/daemon/conversation-agent-loop.ts +12 -0
- package/src/daemon/conversation-attachments.ts +93 -12
- package/src/daemon/conversation-tool-setup.ts +71 -3
- package/src/daemon/conversation-turn-finalize.ts +26 -13
- package/src/daemon/conversation.ts +72 -17
- package/src/daemon/daemon-control.ts +3 -7
- package/src/daemon/lifecycle.ts +4 -4
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/message-types/shared.ts +1 -0
- package/src/daemon/orphan-reaper.ts +4 -3
- package/src/daemon/persist-media-references.ts +20 -3
- package/src/daemon/tool-setup-types.ts +6 -0
- package/src/daemon/wake-conversation-ops.ts +50 -15
- package/src/desktop/desktop-automation-lease.test.ts +230 -0
- package/src/desktop/desktop-automation-lease.ts +90 -6
- package/src/desktop/desktop-help.ts +15 -0
- package/src/desktop/desktop-stream-bridge.test.ts +65 -10
- package/src/desktop/desktop-stream-bridge.ts +3 -3
- package/src/desktop/desktop-wallpaper-renderer.ts +132 -0
- package/src/desktop/desktop-wallpaper-worker.ts +17 -0
- package/src/desktop/desktop-wallpaper.test.ts +48 -7
- package/src/desktop/desktop-wallpaper.ts +34 -102
- package/src/desktop/virtual-desktop-feature.ts +1 -1
- package/src/mcp/__tests__/manager-tool-caps.test.ts +111 -0
- package/src/mcp/__tests__/startup.test.ts +30 -7
- package/src/mcp/__tests__/tool-caps.test.ts +107 -0
- package/src/mcp/manager.ts +168 -101
- package/src/mcp/startup.ts +33 -13
- package/src/mcp/tool-caps.ts +176 -0
- package/src/messaging/provider-message-metadata.ts +3 -3
- package/src/notifications/__tests__/copy-composer.test.ts +70 -0
- package/src/notifications/copy-composer.ts +11 -3
- package/src/notifications/schedule-result-producer.ts +4 -6
- package/src/oauth/AGENTS.md +2 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +36 -1
- package/src/oauth/identity-verifier.ts +24 -0
- package/src/oauth/oauth-store.ts +11 -1
- package/src/oauth/provider-serializer.ts +1 -0
- package/src/oauth/seed-providers.ts +12 -0
- package/src/permissions/confirmation-guardian-request.test.ts +16 -0
- package/src/permissions/confirmation-guardian-request.ts +2 -3
- package/src/permissions/question-prompter.test.ts +31 -0
- package/src/permissions/question-prompter.ts +2 -0
- package/src/persistence/attachments-store.ts +84 -44
- package/src/persistence/conversation-crud.ts +111 -20
- package/src/persistence/conversation-plugin-facade.ts +30 -0
- package/src/persistence/conversation-tool-surface.ts +135 -0
- package/src/persistence/conversation-types.test.ts +32 -0
- package/src/persistence/conversation-types.ts +26 -4
- package/src/persistence/migrations/378-create-conversation-tool-surfaces.test.ts +78 -0
- package/src/persistence/migrations/378-create-conversation-tool-surfaces.ts +29 -0
- package/src/persistence/migrations/379-oauth-providers-response-ok-field.test.ts +92 -0
- package/src/persistence/migrations/379-oauth-providers-response-ok-field.ts +32 -0
- package/src/persistence/migrations/380-conversation-tool-surfaces-delegate-independent-tasks.test.ts +90 -0
- package/src/persistence/migrations/380-conversation-tool-surfaces-delegate-independent-tasks.ts +34 -0
- package/src/persistence/schema/conversation-tool-surfaces.ts +32 -0
- package/src/persistence/schema/index.ts +1 -0
- package/src/persistence/schema/oauth.ts +1 -0
- package/src/persistence/steps.ts +24 -3
- package/src/plugin-api/conversation-turn.ts +31 -7
- package/src/plugin-api/index.ts +11 -1
- package/src/plugin-api/plugin-channel-turn-trust.test.ts +133 -0
- package/src/plugin-api/plugin-channel-turn-trust.ts +71 -0
- package/src/plugins/defaults/memory/AGENTS.md +39 -5
- package/src/plugins/defaults/memory/__tests__/buffer-file.test.ts +365 -0
- package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +43 -0
- package/src/plugins/defaults/memory/__tests__/conversation-memory-purge.test.ts +1 -0
- package/src/plugins/defaults/memory/__tests__/db-memory-attach.test.ts +2 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/buffer-appender.ts +17 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +74 -0
- package/src/plugins/defaults/memory/__tests__/memory-run-evidence.test.ts +161 -0
- package/src/plugins/defaults/memory/__tests__/relocated-memory-test-rows.ts +10 -0
- package/src/plugins/defaults/memory/buffer-file.ts +354 -0
- package/src/plugins/defaults/memory/buffer-format.ts +40 -0
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +1 -2
- package/src/plugins/defaults/memory/context-search/format.ts +2 -1
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +2 -1
- package/src/plugins/defaults/memory/context-search/sources/workspace.ts +2 -1
- package/src/plugins/defaults/memory/conversation-memory-purge.ts +4 -0
- package/src/plugins/defaults/memory/graph/capability-seed.ts +1 -2
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +1 -42
- package/src/plugins/defaults/memory/host-utils.ts +0 -10
- package/src/plugins/defaults/memory/injectors.ts +4 -3
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +72 -183
- package/src/plugins/defaults/memory/memory-run-evidence.ts +213 -0
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +1 -1
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +407 -99
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +10 -0
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +107 -7
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +307 -86
- package/src/plugins/defaults/memory/substrate/consolidation-tool-surface.ts +34 -0
- package/src/plugins/defaults/memory/substrate/page-index.ts +2 -1
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +89 -49
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +1 -1
- package/src/plugins/defaults/memory/tools.ts +1 -1
- package/src/plugins/defaults/memory/v1/graph/consolidation.ts +2 -2
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +2 -1
- package/src/plugins/defaults/memory/v1/graph/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +5 -0
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +5 -2
- package/src/plugins/defaults/memory/v2/reranker.ts +2 -1
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +81 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +87 -0
- package/src/plugins/defaults/memory/v3/__tests__/plugin-schema.test.ts +12 -0
- package/src/plugins/defaults/memory/v3/__tests__/pool-log-store.test.ts +183 -4
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +103 -2
- package/src/plugins/defaults/memory/v3/card.ts +2 -1
- package/src/plugins/defaults/memory/v3/injector.ts +212 -178
- package/src/plugins/defaults/memory/v3/orchestrate.ts +112 -25
- package/src/plugins/defaults/memory/v3/plugin-schema.ts +54 -4
- package/src/plugins/defaults/memory/v3/pool-log-store.ts +253 -1
- package/src/plugins/defaults/memory/v3/pool-select.test.ts +35 -2
- package/src/plugins/defaults/memory/v3/pool-select.ts +31 -19
- package/src/plugins/defaults/memory/v3/sections.ts +2 -1
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +41 -14
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +4 -1
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +1 -46
- package/src/prompts/__tests__/parallel-tasks-section.test.ts +25 -0
- package/src/prompts/delegation-gate.ts +57 -0
- package/src/prompts/system-prompt.ts +14 -32
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/jev/client.test.ts +260 -0
- package/src/providers/jev/client.ts +518 -0
- package/src/providers/model-catalog.ts +58 -3
- package/src/providers/server-tool-pairing.ts +16 -7
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +94 -1
- package/src/runtime/agent-wake.ts +31 -4
- package/src/runtime/guardian-action-service.ts +2 -17
- package/src/runtime/guardian-reply-router.ts +1 -8
- package/src/runtime/http-server.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +89 -0
- package/src/runtime/migrations/vbundle-import-policy.ts +33 -11
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +24 -2
- package/src/runtime/routes/channel-route-shared.ts +1 -9
- package/src/runtime/routes/conversation-routes.ts +29 -4
- package/src/runtime/routes/desktop-setup-routes.test.ts +2 -2
- package/src/runtime/routes/desktop-setup-routes.ts +8 -5
- package/src/runtime/routes/guardian-approval-interception.ts +24 -0
- package/src/runtime/routes/inbound-message-handler.ts +2 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +1 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +7 -4
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -1
- package/src/runtime/routes/inference-profiles-routes.ts +9 -0
- package/src/runtime/routes/oauth-commands-routes.ts +57 -54
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/oauth-request-hints.test.ts +246 -0
- package/src/runtime/routes/oauth-request-hints.ts +149 -0
- package/src/runtime/routes/schedule-routes.ts +2 -0
- package/src/runtime/routes/secret-routes.ts +99 -119
- package/src/schedule/__tests__/worker-mcp-bootstrap.test.ts +107 -0
- package/src/schedule/__tests__/worker-mcp-readiness.test.ts +173 -0
- package/src/schedule/__tests__/worker-mcp-tools.test.ts +13 -47
- package/src/schedule/run-script.ts +2 -2
- package/src/schedule/scheduler.ts +47 -11
- package/src/schedule/tool-surface-readiness.ts +65 -0
- package/src/schedule/worker-mcp.ts +85 -0
- package/src/schedule/worker.ts +9 -31
- package/src/security/secure-keys.ts +60 -48
- package/src/tools/ask-question/ask-question-tool.test.ts +167 -5
- package/src/tools/ask-question/ask-question-tool.ts +119 -23
- package/src/tools/browser/browser-execution.ts +7 -1
- package/src/tools/host-terminal/host-shell.ts +12 -6
- package/src/tools/shared/filesystem/file-ops-service.ts +1 -31
- package/src/tools/shared/shell-output.test.ts +10 -0
- package/src/tools/shared/shell-output.ts +14 -2
- package/src/tools/skills/sandbox-runner.ts +13 -2
- package/src/tools/skills/scaffold-managed.ts +2 -1
- package/src/tools/terminal/__tests__/safe-env.test.ts +33 -4
- package/src/tools/terminal/__tests__/sanitized-bash.test.ts +0 -14
- package/src/tools/terminal/safe-env.ts +35 -24
- package/src/tools/terminal/sanitized-bash.ts +15 -2
- package/src/tools/terminal/shell-launch.test.ts +162 -0
- package/src/tools/terminal/shell.test.ts +29 -0
- package/src/tools/terminal/shell.ts +13 -7
- package/src/util/browser-human-verification.ts +14 -0
- package/src/util/host-process.test.ts +17 -1
- package/src/util/host-process.ts +24 -0
- package/src/util/unicode.ts +29 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { buildSanitizedEnv } from "../tools/terminal/safe-env.js";
|
|
2
2
|
import {
|
|
3
3
|
buildShellInvocation,
|
|
4
|
+
buildShellSpawnFlags,
|
|
4
5
|
terminateProcessTree,
|
|
5
6
|
} from "../util/host-process.js";
|
|
6
7
|
import { getLogger } from "../util/logger.js";
|
|
@@ -64,10 +65,9 @@ export async function runScript(
|
|
|
64
65
|
const shell = buildShellInvocation(command);
|
|
65
66
|
const proc = Bun.spawn([shell.command, ...shell.args], {
|
|
66
67
|
cwd,
|
|
67
|
-
|
|
68
|
+
...buildShellSpawnFlags(),
|
|
68
69
|
stdout: "pipe",
|
|
69
70
|
stderr: "pipe",
|
|
70
|
-
windowsHide: true,
|
|
71
71
|
env: {
|
|
72
72
|
...buildSanitizedEnv(),
|
|
73
73
|
// __SCHEDULE_ID lets a saved command find its own dir; __SCHEDULE_RUN_ID
|
|
@@ -58,6 +58,13 @@ import {
|
|
|
58
58
|
scheduleRetry,
|
|
59
59
|
setScheduleRunConversationId,
|
|
60
60
|
} from "./schedule-store.js";
|
|
61
|
+
import {
|
|
62
|
+
getScheduleToolSurfaceSnapshot,
|
|
63
|
+
getScheduleToolSurfaceState,
|
|
64
|
+
isScheduleToolSurfaceReady,
|
|
65
|
+
MCP_NOT_READY_DEFER_MS,
|
|
66
|
+
scheduleModeNeedsToolSurface,
|
|
67
|
+
} from "./tool-surface-readiness.js";
|
|
61
68
|
import { buildWakeScheduleOptions } from "./wake-schedule-options.js";
|
|
62
69
|
import {
|
|
63
70
|
isScheduleWorkerAdministrativelyStopped,
|
|
@@ -703,6 +710,32 @@ export async function runDueSchedulesOnce(
|
|
|
703
710
|
continue;
|
|
704
711
|
}
|
|
705
712
|
|
|
713
|
+
if (
|
|
714
|
+
scheduleModeNeedsToolSurface(job.mode) &&
|
|
715
|
+
!isScheduleToolSurfaceReady()
|
|
716
|
+
) {
|
|
717
|
+
log.info(
|
|
718
|
+
{
|
|
719
|
+
jobId: job.id,
|
|
720
|
+
name: job.name,
|
|
721
|
+
mode: job.mode,
|
|
722
|
+
toolSurfaceState: getScheduleToolSurfaceState(),
|
|
723
|
+
...getScheduleToolSurfaceSnapshot(),
|
|
724
|
+
},
|
|
725
|
+
"Deferring tool-backed schedule until the MCP tool surface is ready",
|
|
726
|
+
);
|
|
727
|
+
try {
|
|
728
|
+
await deferClaimedSchedule(job.id, Date.now() + MCP_NOT_READY_DEFER_MS);
|
|
729
|
+
} catch (err) {
|
|
730
|
+
log.warn(
|
|
731
|
+
{ err, jobId: job.id },
|
|
732
|
+
"Failed to defer claimed schedule while MCP tool surface is not ready",
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
result.skipped += 1;
|
|
736
|
+
continue;
|
|
737
|
+
}
|
|
738
|
+
|
|
706
739
|
const isOneShot = job.expression == null;
|
|
707
740
|
|
|
708
741
|
// ── Notify mode (one-shot or recurring) ─────────────────────────
|
|
@@ -1149,19 +1182,22 @@ export async function runDueSchedulesOnce(
|
|
|
1149
1182
|
// that before the run is called done and its one result is produced.
|
|
1150
1183
|
await awaitDelegatedWork(conversationId, runStartedAt, log);
|
|
1151
1184
|
await completeScheduleRun(runId, { status: "ok" });
|
|
1152
|
-
//
|
|
1153
|
-
//
|
|
1154
|
-
//
|
|
1185
|
+
// Automatic completion notification for successful execute-mode runs.
|
|
1186
|
+
// Quiet schedules skip this fallback so a clean tick stays silent.
|
|
1187
|
+
// Explicit in-run delivery (e.g. `assistant notifications send`) is
|
|
1188
|
+
// unaffected because it never goes through this producer.
|
|
1155
1189
|
// Awaited rather than fired and forgotten: the schedule worker can exit
|
|
1156
1190
|
// once the tick's loop drains, and a detached emit would race that exit.
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1191
|
+
if (!job.quiet) {
|
|
1192
|
+
await emitScheduleResultNotification({
|
|
1193
|
+
scheduleId: job.id,
|
|
1194
|
+
scheduleName: job.name,
|
|
1195
|
+
conversationId,
|
|
1196
|
+
runId,
|
|
1197
|
+
runStartedAt,
|
|
1198
|
+
rlog: log,
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1165
1201
|
if (isOneShot) {
|
|
1166
1202
|
await completeOneShot(job.id);
|
|
1167
1203
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-local readiness of the MCP tool surface this process hosts.
|
|
3
|
+
*
|
|
4
|
+
* MCP tools reach the registry only after every configured server has been
|
|
5
|
+
* attempted. Until that pass settles, an execute/wake/workflow schedule that
|
|
6
|
+
* fires would record success while `mcp__*` calls fail as unknown tools.
|
|
7
|
+
* Notify and script schedules do not use that surface and keep firing.
|
|
8
|
+
*
|
|
9
|
+
* Default is ready so callers that never bootstrap MCP (existing scheduler
|
|
10
|
+
* tests, the daemon's unused tick) are not blocked. The schedule worker
|
|
11
|
+
* marks starting/reloading around its own connect.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
EMPTY_MCP_STARTUP_SNAPSHOT,
|
|
16
|
+
type McpStartupSnapshot,
|
|
17
|
+
} from "../mcp/tool-caps.js";
|
|
18
|
+
import type { ScheduleMode } from "./schedule-store.js";
|
|
19
|
+
|
|
20
|
+
export type ScheduleToolSurfaceState = "ready" | "starting" | "reloading";
|
|
21
|
+
|
|
22
|
+
/** How far a claimed tool-backed schedule is pushed back while MCP is not ready. */
|
|
23
|
+
export const MCP_NOT_READY_DEFER_MS = 5_000;
|
|
24
|
+
|
|
25
|
+
let state: ScheduleToolSurfaceState = "ready";
|
|
26
|
+
let snapshot: McpStartupSnapshot = EMPTY_MCP_STARTUP_SNAPSHOT;
|
|
27
|
+
|
|
28
|
+
export function scheduleModeNeedsToolSurface(mode: ScheduleMode): boolean {
|
|
29
|
+
return mode === "execute" || mode === "wake" || mode === "workflow";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isScheduleToolSurfaceReady(): boolean {
|
|
33
|
+
return state === "ready";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function getScheduleToolSurfaceState(): ScheduleToolSurfaceState {
|
|
37
|
+
return state;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function getScheduleToolSurfaceSnapshot(): McpStartupSnapshot {
|
|
41
|
+
return snapshot;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function markScheduleToolSurfaceStarting(
|
|
45
|
+
configuredServerCount = 0,
|
|
46
|
+
): void {
|
|
47
|
+
state = "starting";
|
|
48
|
+
snapshot = { ...EMPTY_MCP_STARTUP_SNAPSHOT, configuredServerCount };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function markScheduleToolSurfaceReloading(): void {
|
|
52
|
+
state = "reloading";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function markScheduleToolSurfaceReady(
|
|
56
|
+
next: McpStartupSnapshot = EMPTY_MCP_STARTUP_SNAPSHOT,
|
|
57
|
+
): void {
|
|
58
|
+
state = "ready";
|
|
59
|
+
snapshot = next;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function resetScheduleToolSurfaceReadinessForTests(): void {
|
|
63
|
+
state = "ready";
|
|
64
|
+
snapshot = EMPTY_MCP_STARTUP_SNAPSHOT;
|
|
65
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schedule-worker MCP bootstrap and reload.
|
|
3
|
+
*
|
|
4
|
+
* The worker hosts execute/wake/workflow turns in its own process, so it
|
|
5
|
+
* has to connect MCP servers itself. Tool-backed schedules must not fire
|
|
6
|
+
* until that pass has settled: a 20s grace lets notify/script start, and
|
|
7
|
+
* the readiness latch defers the rest until registration finishes or
|
|
8
|
+
* fails closed.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
restartConfiguredMcpServers,
|
|
13
|
+
startConfiguredMcpServers,
|
|
14
|
+
} from "../mcp/startup.js";
|
|
15
|
+
import {
|
|
16
|
+
EMPTY_MCP_STARTUP_SNAPSHOT,
|
|
17
|
+
type McpStartupSnapshot,
|
|
18
|
+
} from "../mcp/tool-caps.js";
|
|
19
|
+
import { getLogger } from "../util/logger.js";
|
|
20
|
+
import {
|
|
21
|
+
markScheduleToolSurfaceReady,
|
|
22
|
+
markScheduleToolSurfaceReloading,
|
|
23
|
+
markScheduleToolSurfaceStarting,
|
|
24
|
+
} from "./tool-surface-readiness.js";
|
|
25
|
+
|
|
26
|
+
export { MCP_NOT_READY_DEFER_MS } from "./tool-surface-readiness.js";
|
|
27
|
+
|
|
28
|
+
const log = getLogger("schedule-worker-mcp");
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* How long startup waits before arming notify/script ticks.
|
|
32
|
+
*
|
|
33
|
+
* Connecting is worth waiting for. It is not worth waiting for without
|
|
34
|
+
* limit: each server may take 30s to connect and 30s to list tools. Past
|
|
35
|
+
* this deadline those ticks start. Tool-backed schedules stay deferred
|
|
36
|
+
* until {@link markScheduleToolSurfaceReady}.
|
|
37
|
+
*/
|
|
38
|
+
export const MCP_STARTUP_GRACE_MS = 20_000;
|
|
39
|
+
|
|
40
|
+
export async function bootstrapScheduleWorkerMcp(options?: {
|
|
41
|
+
start?: () => Promise<McpStartupSnapshot>;
|
|
42
|
+
graceMs?: number;
|
|
43
|
+
}): Promise<void> {
|
|
44
|
+
const start = options?.start ?? startConfiguredMcpServers;
|
|
45
|
+
const graceMs = options?.graceMs ?? MCP_STARTUP_GRACE_MS;
|
|
46
|
+
markScheduleToolSurfaceStarting();
|
|
47
|
+
const startup = start()
|
|
48
|
+
.then((snapshot) => {
|
|
49
|
+
markScheduleToolSurfaceReady(snapshot);
|
|
50
|
+
log.info(snapshot, "MCP tool surface ready in schedule worker");
|
|
51
|
+
return snapshot;
|
|
52
|
+
})
|
|
53
|
+
.catch((err: unknown) => {
|
|
54
|
+
markScheduleToolSurfaceReady(EMPTY_MCP_STARTUP_SNAPSHOT);
|
|
55
|
+
log.error(
|
|
56
|
+
{ err },
|
|
57
|
+
"MCP tool surface failed in schedule worker; continuing without MCP tools",
|
|
58
|
+
);
|
|
59
|
+
return EMPTY_MCP_STARTUP_SNAPSHOT;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await Promise.race([
|
|
63
|
+
startup,
|
|
64
|
+
new Promise<void>((resolve) => {
|
|
65
|
+
setTimeout(resolve, graceMs).unref();
|
|
66
|
+
}),
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export async function reloadScheduleWorkerMcp(options?: {
|
|
71
|
+
restart?: () => Promise<McpStartupSnapshot>;
|
|
72
|
+
}): Promise<McpStartupSnapshot> {
|
|
73
|
+
const restart = options?.restart ?? restartConfiguredMcpServers;
|
|
74
|
+
markScheduleToolSurfaceReloading();
|
|
75
|
+
try {
|
|
76
|
+
const snapshot = await restart();
|
|
77
|
+
markScheduleToolSurfaceReady(snapshot);
|
|
78
|
+
log.info(snapshot, "MCP servers reloaded in schedule worker");
|
|
79
|
+
return snapshot;
|
|
80
|
+
} catch (err) {
|
|
81
|
+
markScheduleToolSurfaceReady(EMPTY_MCP_STARTUP_SNAPSHOT);
|
|
82
|
+
log.warn({ err }, "MCP reload failed in schedule worker");
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
}
|
package/src/schedule/worker.ts
CHANGED
|
@@ -22,10 +22,6 @@ import { rehydratePlatformCredentials } from "../config/platform-rehydration.js"
|
|
|
22
22
|
import { startConversationEvictor } from "../daemon/conversation-evictor.js";
|
|
23
23
|
import { stopMcpServerManager } from "../mcp/manager.js";
|
|
24
24
|
import { MCP_RELOAD_SIGNAL_FILE } from "../mcp/reload-signal.js";
|
|
25
|
-
import {
|
|
26
|
-
restartConfiguredMcpServers,
|
|
27
|
-
startConfiguredMcpServers,
|
|
28
|
-
} from "../mcp/startup.js";
|
|
29
25
|
import { resetDb } from "../persistence/db-connection.js";
|
|
30
26
|
import { registerWorkerPluginSurface } from "../plugins/worker-plugin-surface.js";
|
|
31
27
|
import { disableStreamSeqStamping } from "../runtime/assistant-stream-state.js";
|
|
@@ -37,6 +33,10 @@ import {
|
|
|
37
33
|
startWorkerPidFileGuard,
|
|
38
34
|
} from "../util/worker-process.js";
|
|
39
35
|
import { runDueSchedulesOnce } from "./scheduler.js";
|
|
36
|
+
import {
|
|
37
|
+
bootstrapScheduleWorkerMcp,
|
|
38
|
+
reloadScheduleWorkerMcp,
|
|
39
|
+
} from "./worker-mcp.js";
|
|
40
40
|
|
|
41
41
|
const log = getLogger("schedule-worker-process");
|
|
42
42
|
|
|
@@ -46,19 +46,6 @@ const TICK_INTERVAL_MS = 15_000;
|
|
|
46
46
|
/** How often this process re-reads flag overrides from the gateway. */
|
|
47
47
|
const FLAG_REFRESH_INTERVAL_MS = 60_000;
|
|
48
48
|
|
|
49
|
-
/**
|
|
50
|
-
* How long startup waits for MCP servers before arming the tick.
|
|
51
|
-
*
|
|
52
|
-
* Connecting is worth waiting for: a schedule that fires first would fail its
|
|
53
|
-
* `mcp__*` calls as unknown tools. It is not worth waiting for without limit.
|
|
54
|
-
* `McpServerManager.start()` walks servers one at a time and allows each 30s to
|
|
55
|
-
* connect and 30s more to list its tools, so a handful of unreachable ones can
|
|
56
|
-
* hold the first tick for minutes, including the notify and script schedules
|
|
57
|
-
* that never touch MCP. Past this deadline the connect continues in the
|
|
58
|
-
* background and the tick starts without it.
|
|
59
|
-
*/
|
|
60
|
-
const MCP_STARTUP_GRACE_MS = 20_000;
|
|
61
|
-
|
|
62
49
|
/**
|
|
63
50
|
* Rebuild this process's MCP connections whenever the daemon reports a reload.
|
|
64
51
|
*
|
|
@@ -85,10 +72,7 @@ function watchForMcpReload(): void {
|
|
|
85
72
|
restartQueued = true;
|
|
86
73
|
return;
|
|
87
74
|
}
|
|
88
|
-
restarting =
|
|
89
|
-
.then((toolCount) => {
|
|
90
|
-
log.info({ toolCount }, "MCP servers reloaded in schedule worker");
|
|
91
|
-
})
|
|
75
|
+
restarting = reloadScheduleWorkerMcp()
|
|
92
76
|
.catch((err: unknown) => {
|
|
93
77
|
log.warn({ err }, "MCP reload failed in schedule worker");
|
|
94
78
|
})
|
|
@@ -193,16 +177,10 @@ async function main(): Promise<void> {
|
|
|
193
177
|
// keeps this process independent of the daemon's event loop, which is the
|
|
194
178
|
// reason it is a separate process at all.
|
|
195
179
|
//
|
|
196
|
-
// Bounded by MCP_STARTUP_GRACE_MS
|
|
197
|
-
//
|
|
198
|
-
|
|
199
|
-
await
|
|
200
|
-
mcpStartup,
|
|
201
|
-
// Unref'd so a connect that beats the deadline leaves nothing pending.
|
|
202
|
-
new Promise((resolve) => {
|
|
203
|
-
setTimeout(resolve, MCP_STARTUP_GRACE_MS).unref();
|
|
204
|
-
}),
|
|
205
|
-
]);
|
|
180
|
+
// Bounded by MCP_STARTUP_GRACE_MS so notify/script can fire. Execute, wake,
|
|
181
|
+
// and workflow schedules stay deferred until the connect settles and the
|
|
182
|
+
// tool surface is marked ready.
|
|
183
|
+
await bootstrapScheduleWorkerMcp();
|
|
206
184
|
|
|
207
185
|
// React to an MCP reload in the daemon. The server set belongs to the config
|
|
208
186
|
// and the daemon owns the watcher that notices it change; this process holds
|
|
@@ -3,22 +3,24 @@
|
|
|
3
3
|
* adapters.
|
|
4
4
|
*
|
|
5
5
|
* Backend selection (`resolveBackendAsync`) is the single async decision point:
|
|
6
|
-
* 1. CES RPC (primary)
|
|
6
|
+
* 1. CES RPC (primary) - injected via `setCesClient()`: delegates credential
|
|
7
7
|
* operations to the CES process over Unix socket RPC. This is the default
|
|
8
|
-
* path for the
|
|
9
|
-
* processes that lazily connect
|
|
10
|
-
* 2. CES
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
8
|
+
* path for the assistant (which calls startCes() at boot) and for
|
|
9
|
+
* child processes that lazily connect to the CES socket (see below).
|
|
10
|
+
* 2. Lazy CES RPC connect - non-assistant processes (workers, CLI
|
|
11
|
+
* subprocesses) that never call startCes(). On first credential
|
|
12
|
+
* resolution they discover the CES bootstrap socket
|
|
13
|
+
* (`CES_BOOTSTRAP_SOCKET_DIR`) and cache
|
|
14
|
+
* the connection.
|
|
15
|
+
* 3. CES HTTP - containerized failover when IPC is unavailable
|
|
16
|
+
* (`IS_CONTAINERIZED` + `CES_CREDENTIAL_URL`). Used if the assistant's
|
|
17
|
+
* bootstrap RPC transport is down, or if a process with HTTP env could
|
|
18
|
+
* not open the socket.
|
|
19
|
+
* 4. Encrypted file store (fallback) - used when CES is unavailable locally.
|
|
18
20
|
*
|
|
19
21
|
* All operations (reads, writes, lists, deletes) go to exactly one backend.
|
|
20
22
|
* There are no cross-store fallbacks or merges. The only transport failover is
|
|
21
|
-
* CES RPC
|
|
23
|
+
* CES RPC to CES HTTP in managed mode; both backends target the same CES
|
|
22
24
|
* sidecar and credential data.
|
|
23
25
|
*/
|
|
24
26
|
|
|
@@ -36,6 +38,7 @@ import {
|
|
|
36
38
|
type CesClient,
|
|
37
39
|
createCesClient,
|
|
38
40
|
} from "../credential-execution/client.js";
|
|
41
|
+
import { discoverCes } from "../credential-execution/executable-discovery.js";
|
|
39
42
|
import {
|
|
40
43
|
CesUnavailableError,
|
|
41
44
|
createCesProcessManager,
|
|
@@ -84,11 +87,11 @@ let _resolvePromise: Promise<CredentialBackend> | undefined;
|
|
|
84
87
|
/**
|
|
85
88
|
* In-flight lazy CES connection promise for non-daemon processes.
|
|
86
89
|
*
|
|
87
|
-
* Workers and CLI subprocesses
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
90
|
+
* Workers and CLI subprocesses never call startCes(). When they hit
|
|
91
|
+
* resolveBackendAsync() with no _cesClient and no _cesReconnect
|
|
92
|
+
* (daemon-only), this promise memoizes a direct CES connection attempt so
|
|
93
|
+
* concurrent credential reads in the same process share a single
|
|
94
|
+
* connect+handshake rather than racing.
|
|
92
95
|
*/
|
|
93
96
|
let _lazyConnectPromise: Promise<CesClient | undefined> | undefined;
|
|
94
97
|
|
|
@@ -203,14 +206,15 @@ function getEncryptedStoreBackend(): CredentialBackend {
|
|
|
203
206
|
* Resolve the primary credential backend for this process (async).
|
|
204
207
|
*
|
|
205
208
|
* Priority:
|
|
206
|
-
* 1. CES RPC client
|
|
207
|
-
* 2.
|
|
208
|
-
* 3.
|
|
209
|
+
* 1. CES RPC client: primary path in every environment.
|
|
210
|
+
* 2. Lazy CES RPC connect: child processes discover the CES socket.
|
|
211
|
+
* 3. Containerized + CES_CREDENTIAL_URL: CES HTTP, only if IPC is down.
|
|
212
|
+
* 4. Encrypted file store: local fallback when CES is unavailable.
|
|
209
213
|
*
|
|
210
214
|
* Once resolved, the backend is cached. If it becomes unavailable (e.g. the
|
|
211
215
|
* CES transport dies), we attempt to reconnect via `_cesReconnect` rather
|
|
212
216
|
* than falling back to a different backend. In managed cloud mode CES is the
|
|
213
|
-
* primary credential source
|
|
217
|
+
* primary credential source. Falling back to the encrypted file store would
|
|
214
218
|
* silently serve stale or empty data.
|
|
215
219
|
*
|
|
216
220
|
* In managed mode, if the CES bootstrap RPC transport dies, we first fail
|
|
@@ -413,10 +417,12 @@ export async function attemptCesReconnection(
|
|
|
413
417
|
/**
|
|
414
418
|
* Lazily connect to a CES sibling socket from a non-daemon process.
|
|
415
419
|
*
|
|
416
|
-
* Workers and CLI subprocesses
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
+
* Workers and CLI subprocesses never call startCes(). This function
|
|
421
|
+
* establishes a direct CES connection on first credential resolution,
|
|
422
|
+
* memoizing the in-flight promise so concurrent callers share a single
|
|
423
|
+
* connect+handshake. Discovery uses the shared CES bootstrap socket; a
|
|
424
|
+
* missing socket fails immediately so callers can fall through without
|
|
425
|
+
* polling.
|
|
420
426
|
*
|
|
421
427
|
* On success, the client is injected via setCesClient() so subsequent
|
|
422
428
|
* resolveBackendAsync() calls take the fast CES RPC path (step 1). A
|
|
@@ -433,6 +439,14 @@ async function tryLazyCesConnect(): Promise<CesClient | undefined> {
|
|
|
433
439
|
|
|
434
440
|
_lazyConnectPromise = (async () => {
|
|
435
441
|
try {
|
|
442
|
+
const discovery = discoverCes();
|
|
443
|
+
if (discovery.mode === "unavailable") {
|
|
444
|
+
log.info(
|
|
445
|
+
{ reason: discovery.reason },
|
|
446
|
+
"CES socket not reachable for lazy connect, falling back to encrypted file store",
|
|
447
|
+
);
|
|
448
|
+
return undefined;
|
|
449
|
+
}
|
|
436
450
|
const pm = createCesProcessManager({});
|
|
437
451
|
const transport = await pm.start();
|
|
438
452
|
const client = createCesClient(transport);
|
|
@@ -498,7 +512,7 @@ async function tryLazyCesConnect(): Promise<CesClient | undefined> {
|
|
|
498
512
|
}
|
|
499
513
|
|
|
500
514
|
async function doResolveBackend(): Promise<CredentialBackend> {
|
|
501
|
-
// 1. CES RPC
|
|
515
|
+
// 1. CES RPC. Primary credential backend in every environment.
|
|
502
516
|
if (_cesClient) {
|
|
503
517
|
const cesRpc = new CesRpcCredentialBackend(_cesClient);
|
|
504
518
|
if (cesRpc.isAvailable()) {
|
|
@@ -511,7 +525,24 @@ async function doResolveBackend(): Promise<CredentialBackend> {
|
|
|
511
525
|
);
|
|
512
526
|
}
|
|
513
527
|
|
|
514
|
-
// 2. CES
|
|
528
|
+
// 2. Lazy CES RPC connect. Child processes never call startCes(). When
|
|
529
|
+
// the assistant's setCesReconnect() is NOT registered, attempt a
|
|
530
|
+
// direct connection to the CES bootstrap socket. On success, inject
|
|
531
|
+
// the client via setCesClient()
|
|
532
|
+
// and re-resolve through the CES RPC path. On failure, fall through.
|
|
533
|
+
if (!_cesClient && !_cesReconnect) {
|
|
534
|
+
const lazyClient = await tryLazyCesConnect();
|
|
535
|
+
if (lazyClient) {
|
|
536
|
+
const cesRpc = new CesRpcCredentialBackend(lazyClient);
|
|
537
|
+
if (cesRpc.isAvailable()) {
|
|
538
|
+
_resolvedBackend = cesRpc;
|
|
539
|
+
log.info("Resolved credential backend: ces-rpc (lazy connect)");
|
|
540
|
+
return cesRpc;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// 3. CES HTTP. Managed failover when IPC is unavailable.
|
|
515
546
|
if (getIsContainerized() && process.env.CES_CREDENTIAL_URL) {
|
|
516
547
|
const ces = createCesCredentialBackend();
|
|
517
548
|
if (ces.isAvailable()) {
|
|
@@ -525,26 +556,7 @@ async function doResolveBackend(): Promise<CredentialBackend> {
|
|
|
525
556
|
);
|
|
526
557
|
}
|
|
527
558
|
|
|
528
|
-
//
|
|
529
|
-
// subprocesses) inherit CES_LOCAL_SOCKET but never call startCes().
|
|
530
|
-
// When the daemon's setCesReconnect() is NOT registered, attempt a
|
|
531
|
-
// direct connection to the CES sibling socket. On success, inject
|
|
532
|
-
// the client via setCesClient() and re-resolve through the CES RPC
|
|
533
|
-
// path. On failure, fall through to the encrypted file store.
|
|
534
|
-
if (!_cesClient && !_cesReconnect && process.env.CES_LOCAL_SOCKET) {
|
|
535
|
-
const lazyClient = await tryLazyCesConnect();
|
|
536
|
-
if (lazyClient) {
|
|
537
|
-
const cesRpc = new CesRpcCredentialBackend(lazyClient);
|
|
538
|
-
if (cesRpc.isAvailable()) {
|
|
539
|
-
_resolvedBackend = cesRpc;
|
|
540
|
-
log.info("Resolved credential backend: ces-rpc (lazy connect)");
|
|
541
|
-
return cesRpc;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
// Lazy connect failed; fall through.
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// 3. On a containerized pod the local encrypted store does not exist and CES
|
|
559
|
+
// 4. On a containerized pod the local encrypted store does not exist and CES
|
|
548
560
|
// owns credentials. Never resolve to the encrypted store here; it would
|
|
549
561
|
// report a provisioned credential as absent. Return an unreachable backend
|
|
550
562
|
// (presence indeterminate, which callers retry) WITHOUT caching it, so the
|
|
@@ -556,7 +568,7 @@ async function doResolveBackend(): Promise<CredentialBackend> {
|
|
|
556
568
|
return createUnavailableBackend();
|
|
557
569
|
}
|
|
558
570
|
|
|
559
|
-
//
|
|
571
|
+
// 5. Encrypted file store: the legitimate backend for local / self-hosted
|
|
560
572
|
// mode when CES is unavailable.
|
|
561
573
|
_resolvedBackend = getEncryptedStoreBackend();
|
|
562
574
|
log.info("Resolved credential backend: encrypted-store (local mode)");
|