@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
|
@@ -27,7 +27,10 @@ import {
|
|
|
27
27
|
type InstalledPluginInfo,
|
|
28
28
|
readInstalledPlugin,
|
|
29
29
|
} from "./list-installed-plugins.js";
|
|
30
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
arePlatformFeaturesEnabled,
|
|
32
|
+
readBundledLocalPluginCatalog,
|
|
33
|
+
} from "./plugin-catalog-local.js";
|
|
31
34
|
import { DEFAULT_PLUGIN_REF } from "./plugin-constants.js";
|
|
32
35
|
import {
|
|
33
36
|
compareFingerprint,
|
|
@@ -338,17 +341,21 @@ export async function inspectPlugin(
|
|
|
338
341
|
let remote: PluginRemoteInfo | null = null;
|
|
339
342
|
let remoteError: string | null = null;
|
|
340
343
|
const installedLocalSource = local?.source?.kind === "local";
|
|
344
|
+
const useBundledLocalCatalog =
|
|
345
|
+
installedLocalSource || (!installed && !arePlatformFeaturesEnabled());
|
|
341
346
|
try {
|
|
342
|
-
if (
|
|
347
|
+
if (useBundledLocalCatalog) {
|
|
343
348
|
const catalog = deps.localCatalog ?? readBundledLocalPluginCatalog();
|
|
344
349
|
const match = catalog.matches.find(
|
|
345
350
|
(candidate) =>
|
|
346
351
|
candidate.name === name &&
|
|
347
352
|
candidate.source.kind === "local" &&
|
|
348
|
-
|
|
353
|
+
(!installedLocalSource ||
|
|
354
|
+
candidate.source.path === local.source?.path),
|
|
349
355
|
);
|
|
350
356
|
remote = match ? readLocalPackageRemote(match, catalog.ref) : null;
|
|
351
|
-
}
|
|
357
|
+
}
|
|
358
|
+
if (!remote && !installedLocalSource) {
|
|
352
359
|
const entries = await fetchMarketplaceEntries(
|
|
353
360
|
{ fetch: deps.fetch },
|
|
354
361
|
{ ref: marketplaceRef },
|
|
@@ -412,6 +412,24 @@ export async function upgradePlugin(
|
|
|
412
412
|
};
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
+
const usesMergeStrategy =
|
|
416
|
+
strategy === "ours" || strategy === "theirs" || strategy === "assistant";
|
|
417
|
+
const canOverwriteCleanBundledInstall =
|
|
418
|
+
remote.kind === "local" &&
|
|
419
|
+
strategy === "theirs" &&
|
|
420
|
+
local.localChanges?.clean === true;
|
|
421
|
+
|
|
422
|
+
if (
|
|
423
|
+
remote.kind === "local" &&
|
|
424
|
+
usesMergeStrategy &&
|
|
425
|
+
!canOverwriteCleanBundledInstall
|
|
426
|
+
) {
|
|
427
|
+
throw new PluginMergeBaselineError(
|
|
428
|
+
name,
|
|
429
|
+
"bundled packages do not retain the previous package version needed for a three-way merge",
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
415
433
|
if (dryRun) {
|
|
416
434
|
return {
|
|
417
435
|
name,
|
|
@@ -433,17 +451,7 @@ export async function upgradePlugin(
|
|
|
433
451
|
// `ours`/`theirs`/`assistant` carry local edits forward via a three-way
|
|
434
452
|
// merge; the default `overwrite` discards them and re-installs the pin
|
|
435
453
|
// wholesale.
|
|
436
|
-
if (
|
|
437
|
-
strategy === "ours" ||
|
|
438
|
-
strategy === "theirs" ||
|
|
439
|
-
strategy === "assistant"
|
|
440
|
-
) {
|
|
441
|
-
if (remote.kind === "local") {
|
|
442
|
-
throw new PluginMergeBaselineError(
|
|
443
|
-
name,
|
|
444
|
-
"bundled packages do not retain the previous package version needed for a three-way merge",
|
|
445
|
-
);
|
|
446
|
-
}
|
|
454
|
+
if (usesMergeStrategy && remote.kind !== "local") {
|
|
447
455
|
const [remoteOwner, remoteRepo] = remote.repo.split("/");
|
|
448
456
|
return mergeUpgrade(
|
|
449
457
|
{
|
package/src/cli/output.ts
CHANGED
|
@@ -11,20 +11,34 @@ export function shouldOutputJson(cmd: Command): boolean {
|
|
|
11
11
|
return false;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Write a JSON payload to stdout. `onFlushed` runs once the bytes have left
|
|
16
|
+
* the process, for a command that must exit itself and would otherwise cut
|
|
17
|
+
* a piped payload short.
|
|
18
|
+
*/
|
|
19
|
+
export function writeOutput(
|
|
20
|
+
cmd: Command,
|
|
21
|
+
payload: unknown,
|
|
22
|
+
onFlushed?: () => void,
|
|
23
|
+
): void {
|
|
15
24
|
const compact = shouldOutputJson(cmd);
|
|
16
25
|
process.stdout.write(
|
|
17
26
|
compact
|
|
18
27
|
? JSON.stringify(payload) + "\n"
|
|
19
28
|
: JSON.stringify(payload, null, 2) + "\n",
|
|
29
|
+
onFlushed,
|
|
20
30
|
);
|
|
21
31
|
}
|
|
22
32
|
|
|
23
33
|
/** Format-aware error output: JSON envelope with --json, stderr otherwise. */
|
|
24
|
-
export function writeError(
|
|
34
|
+
export function writeError(
|
|
35
|
+
cmd: Command,
|
|
36
|
+
message: string,
|
|
37
|
+
onFlushed?: () => void,
|
|
38
|
+
): void {
|
|
25
39
|
if (shouldOutputJson(cmd)) {
|
|
26
|
-
writeOutput(cmd, { ok: false, error: message });
|
|
40
|
+
writeOutput(cmd, { ok: false, error: message }, onFlushed);
|
|
27
41
|
} else {
|
|
28
|
-
process.stderr.write(`Error: ${message}\n
|
|
42
|
+
process.stderr.write(`Error: ${message}\n`, onFlushed);
|
|
29
43
|
}
|
|
30
44
|
}
|
|
@@ -72,6 +72,10 @@ describe("LLMSchema.defaultProvider", () => {
|
|
|
72
72
|
).toThrow();
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
+
test("rejects a structured-decision catalog provider", () => {
|
|
76
|
+
expect(() => DefaultProviderSchema.parse({ provider: "jev" })).toThrow();
|
|
77
|
+
});
|
|
78
|
+
|
|
75
79
|
test("rejects an empty connectionName", () => {
|
|
76
80
|
expect(() =>
|
|
77
81
|
DefaultProviderSchema.parse({
|
|
@@ -249,18 +249,18 @@ If any required capability is missing:
|
|
|
249
249
|
|
|
250
250
|
Scheduled messages run without user interaction, in a conversation nobody has open. If the task produces output the user should see (a digest, summary, report, or a check whose answer is "nothing changed"), the scheduled message **must** end with an explicit instruction to deliver it. Without one, the output lives in a conversation log the user never opens.
|
|
251
251
|
|
|
252
|
-
Write the delivery step into the `message` when you create the schedule
|
|
252
|
+
Write the delivery step into the `message` when you create the schedule, not as a vague "let me know", but as the actual call, with a real title:
|
|
253
253
|
|
|
254
|
-
> "…then send the summary with `assistant notifications send --title \"Inbox digest\" --message \"<the summary>\"`."
|
|
254
|
+
> "…then send the summary with `assistant notifications send --source-channel scheduler --title \"Inbox digest\" --message \"<the summary>\"`."
|
|
255
255
|
|
|
256
256
|
A schedule whose message has no delivery step is not finished. Before calling `schedule_create` in `execute` mode, read your own message back and check that it says where the output goes.
|
|
257
257
|
|
|
258
|
-
There is a safety net, and it is not a substitute for the above. When an execute-mode run finishes with user-facing output and nothing delivered it, the assistant sends a notification carrying the run's final reply, so a schedule can no longer run and leave no trace. `messaging_send` counts as a delivery only when the call reported success, and `assistant notifications send` once the notification pipeline has taken it: a send the channel refused, or one that never reported at all, leaves the run eligible for the net, so the failure reaches you instead of vanishing into a conversation nobody has open. A Slack `chat.postMessage` never counts, because
|
|
258
|
+
There is a safety net, and it is not a substitute for the above. When an execute-mode run finishes with user-facing output and nothing delivered it, the assistant sends a notification carrying the run's final reply, so a schedule can no longer run and leave no trace. `messaging_send` counts as a delivery only when the call reported success, and `assistant notifications send` once the notification pipeline has taken it: a send the channel refused, or one that never reported at all, leaves the run eligible for the net, so the failure reaches you instead of vanishing into a conversation nobody has open. A Slack `chat.postMessage` never counts, because the net recognizes only the recorded routes; a run that posts Block Kit that way also gets the net's notification. It fires on the raw reply, whatever the run happened to end on, at whatever length. An authored delivery step gets a title and body you chose, sent at the moment you chose. Rely on the net and you get the machine's guess instead.
|
|
259
259
|
|
|
260
|
-
Choose the right delivery tool based on the
|
|
260
|
+
Choose the right delivery tool based on the destination:
|
|
261
261
|
|
|
262
|
-
- **
|
|
263
|
-
- **
|
|
262
|
+
- **A specific chat or mailbox** (a named Slack, Telegram, or Discord conversation, or an email draft): Use `messaging_send` with the target platform and conversation ID. It reaches Gmail or Outlook as a draft, and posts to a Slack, Telegram, or Discord chat through that channel's own transport, where the post is recorded and can be found again afterwards. Reach for `chat.postMessage` through `assistant oauth request` only for a Block Kit shape `messaging_send` cannot carry, with the provider the **slack** skill says to pass for posting on this workspace (`slack_channel` when the bot is set up; where only the `slack` integration exists, the skill says to tell the user before posting as them), never through `curl` or a revealed token. Either way the full content posts directly.
|
|
263
|
+
- **The user's notification surfaces** (Vellum inbox, Telegram, platform push): Use `assistant notifications send` via `bash`. Pass `--source-channel scheduler` and the complete authored body as `--message`. The pipeline keeps that body. Do not summarize the report before sending.
|
|
264
264
|
|
|
265
265
|
Example schedule message for a Slack digest:
|
|
266
266
|
|
package/src/config/loader.ts
CHANGED
|
@@ -58,14 +58,6 @@ type ConfigFileSignature =
|
|
|
58
58
|
exists: false;
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
function getConfigPath(): string {
|
|
62
|
-
return getWorkspaceConfigPath();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function ensureMigratedDataDir(): void {
|
|
66
|
-
ensureDataDir();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
61
|
function readConfigFileSignature(configPath: string): ConfigFileSignature {
|
|
70
62
|
const stats = safeStatSync(configPath);
|
|
71
63
|
if (!stats) {
|
|
@@ -104,7 +96,7 @@ function getCachedConfigIfFresh(): AssistantConfig | null {
|
|
|
104
96
|
return null;
|
|
105
97
|
}
|
|
106
98
|
|
|
107
|
-
const currentSignature = readConfigFileSignature(
|
|
99
|
+
const currentSignature = readConfigFileSignature(getWorkspaceConfigPath());
|
|
108
100
|
if (configFileSignaturesEqual(cachedFileSignature, currentSignature)) {
|
|
109
101
|
return cached;
|
|
110
102
|
}
|
|
@@ -1002,7 +994,7 @@ export function mergeDefaultWorkspaceConfig(): DefaultWorkspaceConfigMergeResult
|
|
|
1002
994
|
Object.prototype.hasOwnProperty.call(llmDefaults, "activeProfile"),
|
|
1003
995
|
};
|
|
1004
996
|
|
|
1005
|
-
const configPath =
|
|
997
|
+
const configPath = getWorkspaceConfigPath();
|
|
1006
998
|
let existing: Record<string, unknown> = {};
|
|
1007
999
|
if (existsSync(configPath)) {
|
|
1008
1000
|
try {
|
|
@@ -1070,8 +1062,8 @@ export function loadConfig(): AssistantConfig {
|
|
|
1070
1062
|
loading = true;
|
|
1071
1063
|
|
|
1072
1064
|
try {
|
|
1073
|
-
|
|
1074
|
-
const configPath =
|
|
1065
|
+
ensureDataDir();
|
|
1066
|
+
const configPath = getWorkspaceConfigPath();
|
|
1075
1067
|
|
|
1076
1068
|
let fileConfig: Record<string, unknown> = {};
|
|
1077
1069
|
let configFileExisted = true;
|
|
@@ -1259,7 +1251,7 @@ export function getConfigReadOnly(): AssistantConfig {
|
|
|
1259
1251
|
return freshCached;
|
|
1260
1252
|
}
|
|
1261
1253
|
|
|
1262
|
-
const configPath =
|
|
1254
|
+
const configPath = getWorkspaceConfigPath();
|
|
1263
1255
|
let fileConfig: Record<string, unknown> = {};
|
|
1264
1256
|
if (existsSync(configPath)) {
|
|
1265
1257
|
try {
|
|
@@ -1312,8 +1304,8 @@ export function withSuppressedConfigDiskWritesSync<T>(fn: () => T): T {
|
|
|
1312
1304
|
* type without runtime shape-checking — the boundary check happens here.
|
|
1313
1305
|
*/
|
|
1314
1306
|
export function loadRawConfig(): Record<string, unknown> {
|
|
1315
|
-
|
|
1316
|
-
const configPath =
|
|
1307
|
+
ensureDataDir();
|
|
1308
|
+
const configPath = getWorkspaceConfigPath();
|
|
1317
1309
|
if (!existsSync(configPath)) {
|
|
1318
1310
|
return {};
|
|
1319
1311
|
}
|
|
@@ -1372,8 +1364,8 @@ function describeJsonShape(value: unknown): string {
|
|
|
1372
1364
|
}
|
|
1373
1365
|
|
|
1374
1366
|
export function saveRawConfig(config: Record<string, unknown>): void {
|
|
1375
|
-
|
|
1376
|
-
const configPath =
|
|
1367
|
+
ensureDataDir();
|
|
1368
|
+
const configPath = getWorkspaceConfigPath();
|
|
1377
1369
|
|
|
1378
1370
|
// Strip legacy apiKeys — provider keys belong in secure storage, not plaintext config
|
|
1379
1371
|
delete config.apiKeys;
|
|
@@ -136,7 +136,7 @@ export function _resetPlatformIdentityEnsureForTests(): void {
|
|
|
136
136
|
* Concurrent callers share one in-flight request.
|
|
137
137
|
*/
|
|
138
138
|
export async function ensurePlatformIdentityIds(): Promise<void> {
|
|
139
|
-
if (getPlatformAssistantId()
|
|
139
|
+
if (getPlatformAssistantId()?.trim()) {
|
|
140
140
|
return;
|
|
141
141
|
}
|
|
142
142
|
if (Date.now() < nextEnsureAttemptAt) {
|
|
@@ -146,7 +146,7 @@ export async function ensurePlatformIdentityIds(): Promise<void> {
|
|
|
146
146
|
ensureInFlight = (async () => {
|
|
147
147
|
try {
|
|
148
148
|
const apiKey = await readAssistantApiKey();
|
|
149
|
-
const baseUrl = getPlatformBaseUrl();
|
|
149
|
+
const baseUrl = (getPlatformBaseUrl() ?? "").replace(/\/+$/, "");
|
|
150
150
|
if (!apiKey || !baseUrl) {
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
@@ -167,12 +167,12 @@ export async function ensurePlatformIdentityIds(): Promise<void> {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
export async function resolvePlatformAssistantId(): Promise<string> {
|
|
170
|
-
const existing = getPlatformAssistantId()
|
|
170
|
+
const existing = getPlatformAssistantId()?.trim() ?? "";
|
|
171
171
|
if (existing) {
|
|
172
172
|
return existing;
|
|
173
173
|
}
|
|
174
174
|
await ensurePlatformIdentityIds();
|
|
175
|
-
return getPlatformAssistantId()
|
|
175
|
+
return getPlatformAssistantId()?.trim() ?? "";
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
export async function resolvePlatformAssistantIdOrNull(): Promise<
|
|
@@ -183,19 +183,19 @@ export async function resolvePlatformAssistantIdOrNull(): Promise<
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
export async function resolvePlatformOrganizationId(): Promise<string> {
|
|
186
|
-
const existing = getPlatformOrganizationId()
|
|
186
|
+
const existing = getPlatformOrganizationId()?.trim() ?? "";
|
|
187
187
|
if (existing) {
|
|
188
188
|
return existing;
|
|
189
189
|
}
|
|
190
190
|
await ensurePlatformIdentityIds();
|
|
191
|
-
return getPlatformOrganizationId()
|
|
191
|
+
return getPlatformOrganizationId()?.trim() ?? "";
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
export async function resolvePlatformUserId(): Promise<string> {
|
|
195
|
-
const existing = getPlatformUserId()
|
|
195
|
+
const existing = getPlatformUserId()?.trim() ?? "";
|
|
196
196
|
if (existing) {
|
|
197
197
|
return existing;
|
|
198
198
|
}
|
|
199
199
|
await ensurePlatformIdentityIds();
|
|
200
|
-
return getPlatformUserId()
|
|
200
|
+
return getPlatformUserId()?.trim() ?? "";
|
|
201
201
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
nonTextConversationProfileMessage,
|
|
5
|
+
profileSupportsTextGeneration,
|
|
6
|
+
} from "./profile-text-generation.js";
|
|
7
|
+
|
|
8
|
+
describe("profileSupportsTextGeneration", () => {
|
|
9
|
+
test("false for a structured-decision catalog model", () => {
|
|
10
|
+
expect(
|
|
11
|
+
profileSupportsTextGeneration(
|
|
12
|
+
{ provider: "jev", model: "jev-latest" },
|
|
13
|
+
{},
|
|
14
|
+
),
|
|
15
|
+
).toBe(false);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("true for a chat model and for unlisted custom ids", () => {
|
|
19
|
+
expect(
|
|
20
|
+
profileSupportsTextGeneration(
|
|
21
|
+
{ provider: "anthropic", model: "claude-opus-4-8" },
|
|
22
|
+
{},
|
|
23
|
+
),
|
|
24
|
+
).toBe(true);
|
|
25
|
+
expect(
|
|
26
|
+
profileSupportsTextGeneration(
|
|
27
|
+
{ provider: "openai-compatible", model: "local-mixtral" },
|
|
28
|
+
{},
|
|
29
|
+
),
|
|
30
|
+
).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("a mix is false when any arm is non-text", () => {
|
|
34
|
+
expect(
|
|
35
|
+
profileSupportsTextGeneration(
|
|
36
|
+
{ mix: [{ profile: "jev" }, { profile: "balanced" }] },
|
|
37
|
+
{
|
|
38
|
+
jev: { provider: "jev", model: "jev-latest" },
|
|
39
|
+
balanced: { provider: "anthropic", model: "claude-opus-4-8" },
|
|
40
|
+
},
|
|
41
|
+
),
|
|
42
|
+
).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("names the profile in the conversation-model error", () => {
|
|
46
|
+
expect(nonTextConversationProfileMessage("jev")).toContain("jev");
|
|
47
|
+
expect(nonTextConversationProfileMessage("jev")).toContain(
|
|
48
|
+
"structured answers rather than chat text",
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { catalogModelSupportsText } from "../providers/model-catalog.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Whether a profile can back the conversation model (active profile or a
|
|
5
|
+
* per-conversation pin). Mix arms are judged individually: a mix that can
|
|
6
|
+
* land on a non-text model is not a conversation profile.
|
|
7
|
+
*
|
|
8
|
+
* Missing arms and unlisted models default to true so other validators
|
|
9
|
+
* (existence, availability) own those failures.
|
|
10
|
+
*/
|
|
11
|
+
export function profileSupportsTextGeneration(
|
|
12
|
+
entry: {
|
|
13
|
+
provider?: unknown;
|
|
14
|
+
model?: unknown;
|
|
15
|
+
mix?: unknown;
|
|
16
|
+
},
|
|
17
|
+
siblings: Record<string, unknown>,
|
|
18
|
+
): boolean {
|
|
19
|
+
const mix = entry.mix;
|
|
20
|
+
if (Array.isArray(mix) && mix.length > 0) {
|
|
21
|
+
return mix.every((arm) => {
|
|
22
|
+
const name =
|
|
23
|
+
arm !== null &&
|
|
24
|
+
typeof arm === "object" &&
|
|
25
|
+
"profile" in arm &&
|
|
26
|
+
typeof arm.profile === "string"
|
|
27
|
+
? arm.profile
|
|
28
|
+
: undefined;
|
|
29
|
+
if (name === undefined) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
const target = siblings[name];
|
|
33
|
+
if (target === null || typeof target !== "object") {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
const nested = target as { provider?: unknown; model?: unknown };
|
|
37
|
+
return catalogModelSupportsText(
|
|
38
|
+
typeof nested.provider === "string" ? nested.provider : undefined,
|
|
39
|
+
typeof nested.model === "string" ? nested.model : undefined,
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return catalogModelSupportsText(
|
|
44
|
+
typeof entry.provider === "string" ? entry.provider : undefined,
|
|
45
|
+
typeof entry.model === "string" ? entry.model : undefined,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function nonTextConversationProfileMessage(profileName: string): string {
|
|
50
|
+
return `Profile "${profileName}" uses a model that returns structured answers rather than chat text, so it cannot be the conversation model.`;
|
|
51
|
+
}
|
|
@@ -45,6 +45,7 @@ describe("MemoryV3ConfigSchema", () => {
|
|
|
45
45
|
bm25NormK: null,
|
|
46
46
|
bypassForCore: false,
|
|
47
47
|
},
|
|
48
|
+
poolLog: { captureInput: false },
|
|
48
49
|
});
|
|
49
50
|
});
|
|
50
51
|
|
|
@@ -204,6 +205,17 @@ describe("MemoryV3ConfigSchema", () => {
|
|
|
204
205
|
).toThrow();
|
|
205
206
|
});
|
|
206
207
|
|
|
208
|
+
test("poolLog.captureInput defaults false, accepts true, rejects non-booleans", () => {
|
|
209
|
+
expect(MemoryV3ConfigSchema.parse({}).poolLog.captureInput).toBe(false);
|
|
210
|
+
expect(
|
|
211
|
+
MemoryV3ConfigSchema.parse({ poolLog: { captureInput: true } }).poolLog
|
|
212
|
+
.captureInput,
|
|
213
|
+
).toBe(true);
|
|
214
|
+
expect(() =>
|
|
215
|
+
MemoryV3ConfigSchema.parse({ poolLog: { captureInput: "yes" } }),
|
|
216
|
+
).toThrow();
|
|
217
|
+
});
|
|
218
|
+
|
|
207
219
|
test("gate.topK rejects zero and non-integers", () => {
|
|
208
220
|
expect(() => MemoryV3ConfigSchema.parse({ gate: { topK: 0 } })).toThrow();
|
|
209
221
|
expect(() => MemoryV3ConfigSchema.parse({ gate: { topK: 2.5 } })).toThrow();
|
|
@@ -4,7 +4,10 @@ import {
|
|
|
4
4
|
PROVIDERS_REQUIRING_BASE_URL_AND_MODELS,
|
|
5
5
|
ROUTING_IDENTITY_PROVIDERS,
|
|
6
6
|
} from "../../providers/inference/auth.js";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
catalogModelSupportsText,
|
|
9
|
+
PROVIDER_CATALOG,
|
|
10
|
+
} from "../../providers/model-catalog.js";
|
|
8
11
|
import { isCodexSubscriptionModel } from "../../providers/openai/codex-models.js";
|
|
9
12
|
import {
|
|
10
13
|
getManagedUpstream,
|
|
@@ -59,6 +62,7 @@ export const KNOWN_LLM_PROVIDERS = [
|
|
|
59
62
|
"opencode",
|
|
60
63
|
"baseten",
|
|
61
64
|
"poolside",
|
|
65
|
+
"jev",
|
|
62
66
|
// Routing identities: "vellum" = the platform-managed route (upstream
|
|
63
67
|
// derived from the model at dispatch) and the catalog owner of
|
|
64
68
|
// Vellum-hosted GPU models; "chatgpt" = the subscription route to OpenAI.
|
|
@@ -99,7 +103,8 @@ export const DEFAULT_PROVIDER_CHOICES: readonly LLMProvider[] = [
|
|
|
99
103
|
(entry) =>
|
|
100
104
|
entry.setupMode === "api-key" &&
|
|
101
105
|
!PROVIDERS_REQUIRING_BASE_URL_AND_MODELS.has(entry.id) &&
|
|
102
|
-
entry.defaultModel !== ""
|
|
106
|
+
entry.defaultModel !== "" &&
|
|
107
|
+
catalogModelSupportsText(entry.id, entry.defaultModel),
|
|
103
108
|
)
|
|
104
109
|
.map((entry) => entry.id)
|
|
105
110
|
// A catalog provider outside the known provider set cannot be
|
|
@@ -17,7 +17,11 @@ export const PLUGIN_MCP_RISK_LEVEL = "low" as const;
|
|
|
17
17
|
/** Per-server cap on tools registered from one MCP server. */
|
|
18
18
|
export const MCP_MAX_TOOLS_PER_SERVER = 20;
|
|
19
19
|
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Cap on tools registered across every MCP server. Selection is a
|
|
22
|
+
* deterministic round-robin by server id (see `mcp/tool-caps.ts`), so a
|
|
23
|
+
* later server is not emptied just because earlier ones filled the budget.
|
|
24
|
+
*/
|
|
21
25
|
export const MCP_GLOBAL_MAX_TOOLS = 50;
|
|
22
26
|
|
|
23
27
|
export type McpRiskLevel =
|
|
@@ -352,6 +352,17 @@ export const MemoryV3GateSchema = z
|
|
|
352
352
|
"Memory v3 per-turn injection gate tuning (thresholds; the gate runs when `enabled` is on).",
|
|
353
353
|
);
|
|
354
354
|
|
|
355
|
+
const MemoryV3PoolLogSchema = z
|
|
356
|
+
.object({
|
|
357
|
+
captureInput: z
|
|
358
|
+
.boolean({ error: "memory.v3.poolLog.captureInput must be a boolean" })
|
|
359
|
+
.default(false)
|
|
360
|
+
.describe(
|
|
361
|
+
"Persist the selector's exact input beside each turn's pool audit: the rendered text of every pooled candidate, content-addressed in `memory_v3_pool_texts`, and the turn's context strings in `memory_v3_pool_inputs`, for offline selector evaluation and training data. Off by default; the pool audit itself (`memory_v3_pools`) is always written.",
|
|
362
|
+
),
|
|
363
|
+
})
|
|
364
|
+
.describe("Memory v3 selector pool audit options.");
|
|
365
|
+
|
|
355
366
|
// Persisted config files can carry unsupported tuning keys this object does
|
|
356
367
|
// not declare; zod's default unknown-key stripping accepts and drops them, so
|
|
357
368
|
// such a config keeps parsing. Do not make this object `.strict()`.
|
|
@@ -434,6 +445,7 @@ export const MemoryV3ConfigSchema = z
|
|
|
434
445
|
entity: MemoryV3EntitySchema.default(MemoryV3EntitySchema.parse({})),
|
|
435
446
|
rareTerm: MemoryV3RareTermSchema.default(MemoryV3RareTermSchema.parse({})),
|
|
436
447
|
gate: MemoryV3GateSchema.default(MemoryV3GateSchema.parse({})),
|
|
448
|
+
poolLog: MemoryV3PoolLogSchema.default(MemoryV3PoolLogSchema.parse({})),
|
|
437
449
|
})
|
|
438
450
|
.describe("Memory v3 — section-grain lane retrieval");
|
|
439
451
|
|
|
@@ -49,8 +49,8 @@ interface CesStartupResult {
|
|
|
49
49
|
* handles to the in-flight initialization — callers don't need to await this
|
|
50
50
|
* for startup to continue.
|
|
51
51
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
52
|
+
* CES serves a multi-connection Unix socket, so this is called at the
|
|
53
|
+
* process level and child processes may open their own connections.
|
|
54
54
|
*/
|
|
55
55
|
function startCesProcess(config: AssistantConfig): CesStartupResult {
|
|
56
56
|
const pm = createCesProcessManager({ assistantConfig: config });
|