@vellumai/assistant 0.12.3 → 0.12.4-dev.202609231715.8da971c
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/Dockerfile +7 -0
- package/README.md +12 -12
- package/docker/mousepad/90-vellum.gschema.override +4 -0
- package/node_modules/@vellumai/avatar-manifest/src/__tests__/notification-avatar.test.ts +48 -4
- package/node_modules/@vellumai/avatar-manifest/src/notification-avatar.ts +12 -8
- package/openapi.yaml +97 -4
- package/package.json +1 -1
- package/src/__tests__/approval-routes-http.test.ts +4 -2
- package/src/__tests__/call-routes-http.test.ts +4 -2
- package/src/__tests__/channel-readiness-discord.test.ts +8 -0
- package/src/__tests__/channel-readiness-slack-remote.test.ts +8 -0
- package/src/__tests__/config-loader-backfill.test.ts +1 -0
- package/src/__tests__/conversation-pairing.test.ts +10 -0
- package/src/__tests__/conversation-resurface-done.test.ts +289 -0
- package/src/__tests__/default-profile-catalog-fallback.test.ts +1 -0
- package/src/__tests__/gemini-provider.test.ts +31 -0
- package/src/__tests__/inference-profile-validation-jev.test.ts +17 -0
- package/src/__tests__/job-handler-registration-guard.test.ts +1 -0
- package/src/__tests__/llm-catalog-parity.test.ts +4 -0
- package/src/__tests__/llm-resolver-override-or-default.test.ts +43 -0
- package/src/__tests__/openai-responses-prompt-cache.test.ts +3 -1
- package/src/__tests__/platform-callback-registration.test.ts +46 -1
- package/src/__tests__/plugin-api-model-profiles.test.ts +7 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +3 -0
- package/src/__tests__/pricing.test.ts +33 -0
- package/src/__tests__/provider-error-scenarios.test.ts +46 -0
- package/src/__tests__/provider-platform-proxy-integration.test.ts +45 -15
- package/src/__tests__/retry-fallback-escalation.test.ts +22 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +4 -2
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +116 -66
- package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +4 -2
- package/src/__tests__/skill-load-inline-command.test.ts +35 -0
- package/src/__tests__/skill-load-tool.test.ts +42 -11
- package/src/__tests__/skill-tool-factory.test.ts +50 -2
- package/src/__tests__/steer-on-enqueue-question.test.ts +265 -34
- package/src/__tests__/validate-input.test.ts +73 -0
- package/src/__tests__/workspace-migration-159-rename-colliding-jev-profile-name.test.ts +197 -0
- package/src/api/ask-question-tool.ts +50 -0
- package/src/api/events/tool-result.ts +11 -0
- package/src/api/index.ts +7 -0
- package/src/api/requests/dictation.ts +2 -2
- package/src/api/responses/home.ts +27 -0
- package/src/avatar/notification-avatar.test.ts +42 -34
- package/src/avatar/notification-avatar.ts +1 -0
- package/src/calls/__tests__/call-controller.test.ts +18 -0
- package/src/calls/__tests__/voice-control-protocol.test.ts +6 -1
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +42 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +97 -4
- package/src/calls/__tests__/voice-triage-escalate.test.ts +69 -11
- package/src/calls/call-controller.ts +3 -1
- package/src/calls/voice-control-protocol.ts +9 -4
- package/src/calls/voice-escalation-judge.ts +7 -6
- package/src/calls/voice-leg-coordinator.ts +15 -4
- package/src/calls/voice-screen-annotation.ts +44 -0
- package/src/calls/voice-session-bridge.ts +50 -20
- package/src/calls/voice-triage-escalate.ts +61 -26
- package/src/cli/commands/__tests__/plugins.test.ts +29 -1
- package/src/cli/commands/channel-verification-sessions.help.ts +12 -2
- package/src/cli/commands/oauth/index.help.ts +8 -2
- package/src/cli/commands/oauth/request.test.ts +32 -0
- package/src/cli/commands/platform/index.help.ts +2 -1
- package/src/cli/commands/platform/index.ts +8 -2
- package/src/cli/commands/plugins.ts +16 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +29 -0
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +92 -2
- package/src/cli/lib/__tests__/plugin-catalog-local.test.ts +15 -0
- package/src/cli/lib/__tests__/plugin-catalog-platform.test.ts +66 -2
- package/src/cli/lib/__tests__/plugin-catalog-resolve.test.ts +21 -0
- package/src/cli/lib/__tests__/plugin-catalog-visibility.test.ts +65 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +43 -0
- package/src/cli/lib/__tests__/plugins-install-offline.test.ts +26 -0
- package/src/cli/lib/bundled-marketplace.json +4 -4
- package/src/cli/lib/inspect-plugin.ts +5 -0
- package/src/cli/lib/plugin-catalog-cache.ts +41 -4
- package/src/cli/lib/plugin-catalog-local.ts +9 -0
- package/src/cli/lib/plugin-catalog-platform.ts +48 -9
- package/src/cli/lib/plugin-catalog-visibility.ts +41 -0
- package/src/cli/lib/plugin-details.ts +10 -7
- package/src/cli/lib/search-plugins.ts +2 -0
- package/src/config/__tests__/default-profile-catalog.test.ts +61 -1
- package/src/config/__tests__/jev-managed-profile.test.ts +82 -0
- package/src/config/__tests__/platform-identity.test.ts +59 -0
- package/src/config/__tests__/sync-gated-profiles.test.ts +71 -0
- package/src/config/bundled-skills/screen-annotation/SKILL.md +6 -3
- package/src/config/call-site-defaults.ts +17 -11
- package/src/config/default-profile-catalog.ts +118 -19
- package/src/config/default-profile-names.ts +69 -0
- package/src/config/feature-flag-registry.json +25 -9
- package/src/config/inference-profile-validation.ts +7 -6
- package/src/config/llm-resolver.ts +16 -0
- package/src/config/platform-identity.ts +22 -5
- package/src/config/profile-text-generation.test.ts +9 -0
- package/src/config/schemas/call-site-catalog.ts +8 -1
- package/src/config/schemas/llm.ts +70 -9
- package/src/config/sidebar-done-gate.ts +27 -0
- package/src/config/sync-gated-profiles.ts +96 -44
- package/src/daemon/__tests__/auto-profile-router.test.ts +228 -0
- package/src/daemon/auto-profile-router.ts +220 -0
- package/src/daemon/conversation-agent-loop.ts +77 -4
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-turn-finalize.ts +12 -0
- package/src/daemon/dictation-text-processing.ts +4 -4
- package/src/daemon/handlers/__tests__/conversation-history-search.test.ts +61 -0
- package/src/daemon/handlers/config-channels.ts +3 -1
- package/src/daemon/handlers/conversation-history.ts +11 -1
- package/src/daemon/handlers/conversations.ts +118 -10
- package/src/daemon/pkb-reminder-builder.test.ts +10 -3
- package/src/daemon/pkb-reminder-builder.ts +1 -1
- package/src/desktop/desktop-browser-endpoint.ts +1 -0
- package/src/home/feed-types.ts +2 -0
- package/src/inbound/platform-callback-registration.ts +19 -6
- package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +49 -1
- package/src/ipc/routes/conversation-sync-ipc-routes.ts +38 -2
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +27 -0
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +37 -1
- package/src/live-voice/__tests__/live-voice-vad.test.ts +34 -2
- package/src/live-voice/__tests__/protocol.test.ts +22 -0
- package/src/live-voice/continuation-judge.ts +1 -1
- package/src/live-voice/live-voice-session.ts +17 -14
- package/src/live-voice/protocol.ts +16 -5
- package/src/messaging/providers/gmail/client.ts +4 -0
- package/src/notifications/README.md +11 -3
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +13 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +87 -3
- package/src/notifications/conversation-pairing.ts +23 -8
- package/src/notifications/home-feed-mirror.ts +39 -0
- package/src/notifications/home-feed-side-effect.ts +46 -19
- package/src/oauth/AGENTS.md +9 -1
- package/src/oauth/byo-connection.test.ts +28 -0
- package/src/permissions/question-prompter.ts +14 -4
- package/src/persistence/conversation-crud.ts +116 -3
- package/src/persistence/conversation-queries.ts +48 -3
- package/src/persistence/conversation-types.ts +6 -2
- package/src/persistence/embeddings/__tests__/embedding-local-lifecycle.test.ts +228 -32
- package/src/persistence/embeddings/embedding-backend-shutdown.test.ts +47 -0
- package/src/persistence/embeddings/embedding-backend.ts +23 -41
- package/src/persistence/embeddings/embedding-gemini.test.ts +17 -0
- package/src/persistence/embeddings/embedding-gemini.ts +3 -1
- package/src/persistence/embeddings/embedding-local.ts +72 -17
- package/src/persistence/embeddings/embedding-types.ts +0 -19
- package/src/persistence/jobs-store.ts +229 -0
- package/src/persistence/migrations/383-normalize-opencode-host-connections.ts +44 -0
- package/src/persistence/migrations/__tests__/383-normalize-opencode-host-connections.test.ts +102 -0
- package/src/persistence/steps.ts +12 -0
- package/src/platform/sync-avatar.test.ts +29 -0
- package/src/plugin-api/model-profiles.ts +5 -3
- package/src/plugins/defaults/memory/AGENTS.md +5 -3
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-skill-card.test.ts +2 -0
- package/src/plugins/defaults/memory/__tests__/skill-update-receipt-boundary-guard.test.ts +45 -0
- package/src/plugins/defaults/memory/__tests__/skill-update-receipt-job.test.ts +580 -0
- package/src/plugins/defaults/memory/graph/tools.ts +9 -5
- package/src/plugins/defaults/memory/hooks/conversation-deleted.ts +4 -0
- package/src/plugins/defaults/memory/job-handlers.ts +8 -2
- package/src/plugins/defaults/memory/memory-retrospective-skill-card.ts +5 -0
- package/src/plugins/defaults/memory/skill-update-receipt-job.ts +334 -0
- package/src/plugins/defaults/memory/substrate/skill-content.ts +1 -1
- package/src/plugins/defaults/memory/tools.test.ts +17 -0
- package/src/plugins/defaults/memory/v3/__tests__/render-injection.test.ts +3 -0
- package/src/providers/__tests__/connection-model-compat.test.ts +2 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +8 -0
- package/src/providers/anthropic/client.ts +2 -2
- package/src/providers/gemini/client.ts +17 -1
- package/src/providers/inference/auth.ts +25 -0
- package/src/providers/jev/ask.test.ts +66 -0
- package/src/{calls/typesafe-noul.ts → providers/jev/ask.ts} +75 -36
- package/src/providers/malformed-tool-call.ts +55 -0
- package/src/providers/model-catalog.ts +257 -4
- package/src/providers/openai/__tests__/chat-completions-malformed-tool-call.test.ts +105 -0
- package/src/providers/openai/chat-completions-provider.ts +30 -0
- package/src/providers/openai/codex-models.ts +2 -0
- package/src/providers/platform-proxy/constants.ts +5 -0
- package/src/providers/retry.ts +68 -36
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/vellum-model-routing.test.ts +1 -0
- package/src/runtime/__tests__/agent-wake-archived-gate.test.ts +90 -0
- package/src/runtime/__tests__/question-resolution.test.ts +32 -0
- package/src/runtime/agent-wake.ts +9 -2
- package/src/runtime/auth/__tests__/middleware.test.ts +138 -0
- package/src/runtime/auth/middleware.ts +15 -11
- package/src/runtime/middleware/auth.ts +7 -1
- package/src/runtime/pending-interactions.ts +8 -8
- package/src/runtime/question-resolution.ts +54 -8
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +146 -0
- package/src/runtime/routes/__tests__/dictation-processing.test.ts +174 -0
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +74 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +60 -0
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +16 -1
- package/src/runtime/routes/__tests__/oauth-proxy-routes.test.ts +61 -3
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +8 -0
- package/src/runtime/routes/conversation-list-routes.ts +16 -14
- package/src/runtime/routes/conversation-query-routes.ts +4 -0
- package/src/runtime/routes/conversation-routes.ts +4 -2
- package/src/runtime/routes/diagnostics-routes.ts +66 -229
- package/src/runtime/routes/global-search-routes.ts +22 -7
- package/src/runtime/routes/inference-provider-connection-routes.ts +25 -8
- package/src/runtime/routes/llm-call-sites-routes.ts +19 -10
- package/src/runtime/routes/oauth-proxy-passthrough.test.ts +32 -0
- package/src/runtime/routes/platform-routes.ts +6 -1
- package/src/runtime/routes/plugins-routes.ts +5 -2
- package/src/runtime/sync/documents-sidecar-publish.test.ts +50 -4
- package/src/runtime/sync/resource-sync-events.ts +11 -0
- package/src/runtime/sync/worker-daemon-notify.test.ts +30 -0
- package/src/runtime/sync/worker-daemon-notify.ts +44 -0
- package/src/runtime/verification-outbound-actions.ts +2 -2
- package/src/skills/validate-input.ts +75 -11
- package/src/telegram/__tests__/webhook-health.test.ts +8 -0
- package/src/tools/ask-question/ask-question-tool.test.ts +38 -0
- package/src/tools/ask-question/ask-question-tool.ts +12 -1
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +28 -1
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +34 -0
- package/src/tools/network/__tests__/web-fetch-tinyfish.test.ts +35 -1
- package/src/tools/network/__tests__/web-search.test.ts +96 -0
- package/src/tools/network/web-fetch.ts +30 -9
- package/src/tools/network/web-search.ts +235 -4
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/format-input-schema.ts +15 -0
- package/src/tools/skills/load.ts +15 -43
- package/src/tools/skills/scaffold-managed.ts +86 -71
- package/src/tools/skills/skill-tool-factory.ts +2 -1
- package/src/tools/workflows/manage-workflows.ts +4 -2
- package/src/util/oauth-request-body.test.ts +5 -1
- package/src/util/worker-pipe.test.ts +146 -0
- package/src/util/worker-pipe.ts +49 -0
- package/src/workspace/migrations/158-repoint-opencode-host-provider-fragments.ts +163 -0
- package/src/workspace/migrations/159-rename-colliding-jev-profile-name.ts +344 -0
- package/src/workspace/migrations/__tests__/158-repoint-opencode-host-provider-fragments.test.ts +188 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +0 -107
|
@@ -8,6 +8,7 @@ import { isCodexSubscriptionModel } from "../providers/openai/codex-models.js";
|
|
|
8
8
|
import type { ModelIntent } from "../providers/types.js";
|
|
9
9
|
import { getManagedUpstream } from "../providers/vellum-model-routing.js";
|
|
10
10
|
import {
|
|
11
|
+
AUTO_PROFILE_KEY,
|
|
11
12
|
BACKUP_PROFILE_KEYS,
|
|
12
13
|
type BackupProfileKey,
|
|
13
14
|
DEFAULT_PROFILE_KEYS,
|
|
@@ -15,12 +16,15 @@ import {
|
|
|
15
16
|
type DefaultProfileKey,
|
|
16
17
|
type DefaultProfileProvider,
|
|
17
18
|
FALLBACK_PROFILE_BY_KEY,
|
|
18
|
-
isBackupProfileKey,
|
|
19
19
|
isDefaultProfileKey,
|
|
20
20
|
isDefaultProfileProvider,
|
|
21
|
+
isFlagGatedProfileKey,
|
|
22
|
+
isManagedOnlyProfileKey,
|
|
23
|
+
JEV_MANAGED_PROFILE_KEY,
|
|
21
24
|
OS_BETA_PROFILE_KEY,
|
|
22
25
|
} from "./default-profile-names.js";
|
|
23
26
|
import { resolveDefaultConnectionName } from "./default-provider-resolution.js";
|
|
27
|
+
import { profileSupportsTextGeneration } from "./profile-text-generation.js";
|
|
24
28
|
import {
|
|
25
29
|
backupProfilesResolveUnderDefaultProvider,
|
|
26
30
|
DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS,
|
|
@@ -385,18 +389,60 @@ export const PROFILE_IMPLS: Record<
|
|
|
385
389
|
Record<DefaultProfileProvider, DefaultProfileTemplate>
|
|
386
390
|
>;
|
|
387
391
|
|
|
392
|
+
/**
|
|
393
|
+
* The managed Jev profile: TypeSafe's System One decision model through the
|
|
394
|
+
* platform proxy. Managed column only, because the platform is the only
|
|
395
|
+
* route the catalog offers for it here, and never a conversation profile,
|
|
396
|
+
* because `jev-latest` returns structured answers rather than chat text
|
|
397
|
+
* (`supportsText: false` on the `typesafe` catalog entry). Its budget is
|
|
398
|
+
* TypeSafe's published request limit rather than the default context window.
|
|
399
|
+
*/
|
|
400
|
+
export const JEV_MANAGED_PROFILE_TEMPLATE: DefaultProfileTemplate = {
|
|
401
|
+
model: "jev-latest",
|
|
402
|
+
provider: "vellum",
|
|
403
|
+
source: "managed",
|
|
404
|
+
label: "Jev",
|
|
405
|
+
description:
|
|
406
|
+
"TypeSafe decision model for yes/no verdicts, for the voice judges and memory selection",
|
|
407
|
+
maxTokens: 4096,
|
|
408
|
+
thinking: { enabled: false, streamThinking: false },
|
|
409
|
+
contextWindow: { maxInputTokens: 32_000 },
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* The Auto profile: the managed Balanced body under its own label, so that
|
|
414
|
+
* anything dispatching the name directly runs Balanced. The per-message
|
|
415
|
+
* choice among the defaults happens in the agent loop, not here (see
|
|
416
|
+
* `AUTO_PROFILE_KEY`). No `fallbackProfile`: the code-owned fallback mapping
|
|
417
|
+
* is keyed by default profile, and a direct dispatch of this name is already
|
|
418
|
+
* the fallback path. Flag-gated like `os-beta`: NOT in
|
|
419
|
+
* `MANAGED_PROFILE_TEMPLATES`, so the unconditional boot seed never creates
|
|
420
|
+
* it; the flag-gated profile reconcile materializes it while the
|
|
421
|
+
* `auto-profile` feature flag is on.
|
|
422
|
+
*/
|
|
423
|
+
export const AUTO_PROFILE_TEMPLATE: DefaultProfileTemplate = (() => {
|
|
424
|
+
const { fallbackProfile: _fallbackProfile, ...balanced } =
|
|
425
|
+
VELLUM_PROFILE_IMPLS.balanced;
|
|
426
|
+
return {
|
|
427
|
+
...balanced,
|
|
428
|
+
label: "Auto",
|
|
429
|
+
description: "Picks the profile that fits each message, in beta",
|
|
430
|
+
};
|
|
431
|
+
})();
|
|
432
|
+
|
|
388
433
|
/**
|
|
389
434
|
* Managed profiles, i.e. the `vellum` column keyed by profile name, plus the
|
|
390
|
-
* managed backup profiles. Backups come after the
|
|
391
|
-
* places them after the primaries in the seeded
|
|
392
|
-
* inserts missing managed keys in this record's
|
|
393
|
-
* user-facing defaults only: an internal profile is
|
|
394
|
-
* listed or ordered.
|
|
435
|
+
* managed backup profiles and the managed Jev profile. Backups come after the
|
|
436
|
+
* primaries, which is what places them after the primaries in the seeded
|
|
437
|
+
* `profileOrder`: the seeder inserts missing managed keys in this record's
|
|
438
|
+
* order. Keyed by the user-facing defaults only: an internal profile is
|
|
439
|
+
* code-resolved and never listed or ordered.
|
|
395
440
|
*/
|
|
396
441
|
export const MANAGED_PROFILE_TEMPLATES: Record<string, DefaultProfileTemplate> =
|
|
397
442
|
Object.fromEntries([
|
|
398
443
|
...DEFAULT_PROFILE_KEYS.map((key) => [key, PROFILE_IMPLS[key].vellum]),
|
|
399
444
|
...BACKUP_PROFILE_KEYS.map((key) => [key, BACKUP_PROFILE_IMPLS[key]]),
|
|
445
|
+
[JEV_MANAGED_PROFILE_KEY, JEV_MANAGED_PROFILE_TEMPLATE],
|
|
400
446
|
]);
|
|
401
447
|
|
|
402
448
|
/**
|
|
@@ -484,6 +530,9 @@ export const OS_BETA_PROFILE_TEMPLATE: DefaultProfileTemplate = {
|
|
|
484
530
|
export const CODE_OWNED_PROFILE_NAMES = new Set<string>([
|
|
485
531
|
"latency-optimized",
|
|
486
532
|
...BACKUP_PROFILE_KEYS,
|
|
533
|
+
// A shadow could repoint the judges at a chat model, which answers a
|
|
534
|
+
// yes/no question with prose the verdict parser cannot read.
|
|
535
|
+
JEV_MANAGED_PROFILE_KEY,
|
|
487
536
|
]);
|
|
488
537
|
|
|
489
538
|
// All managed profiles, including the flag-gated os-beta, are invariant:
|
|
@@ -494,6 +543,8 @@ export const CODE_OWNED_PROFILE_NAMES = new Set<string>([
|
|
|
494
543
|
export const INVARIANT_PROFILE_NAMES = new Set<string>([
|
|
495
544
|
...DEFAULT_PROFILE_KEYS,
|
|
496
545
|
...BACKUP_PROFILE_KEYS,
|
|
546
|
+
JEV_MANAGED_PROFILE_KEY,
|
|
547
|
+
AUTO_PROFILE_KEY,
|
|
497
548
|
OS_BETA_PROFILE_KEY,
|
|
498
549
|
]);
|
|
499
550
|
|
|
@@ -507,6 +558,8 @@ export const INVARIANT_PROFILE_NAMES = new Set<string>([
|
|
|
507
558
|
export const MANAGED_PROFILE_NAMES = new Set<string>([
|
|
508
559
|
...DEFAULT_PROFILE_KEYS,
|
|
509
560
|
...BACKUP_PROFILE_KEYS,
|
|
561
|
+
JEV_MANAGED_PROFILE_KEY,
|
|
562
|
+
AUTO_PROFILE_KEY,
|
|
510
563
|
OS_BETA_PROFILE_KEY,
|
|
511
564
|
]);
|
|
512
565
|
|
|
@@ -590,6 +643,19 @@ for (const key of BACKUP_PROFILE_KEYS) {
|
|
|
590
643
|
}
|
|
591
644
|
}
|
|
592
645
|
|
|
646
|
+
// The managed Jev profile pins a model the platform proxy must front, and the
|
|
647
|
+
// judges depend on it being the non-text TypeSafe model rather than a chat
|
|
648
|
+
// model that happens to share the id.
|
|
649
|
+
if (
|
|
650
|
+
getManagedUpstream(JEV_MANAGED_PROFILE_TEMPLATE.model ?? "") !== "typesafe"
|
|
651
|
+
) {
|
|
652
|
+
throw new Error(
|
|
653
|
+
`JEV_MANAGED_PROFILE_TEMPLATE references model "${JEV_MANAGED_PROFILE_TEMPLATE.model ?? ""}" ` +
|
|
654
|
+
`which the managed route does not serve through typesafe. ` +
|
|
655
|
+
`Update model-catalog.ts, platform-proxy/constants.ts, or default-profile-catalog.ts.`,
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
|
|
593
659
|
// Provider choices without a named column materialize from the shared BYOK
|
|
594
660
|
// templates; verify each one's resolved model lands in the catalog.
|
|
595
661
|
for (const provider of DEFAULT_PROVIDER_CHOICES) {
|
|
@@ -621,6 +687,14 @@ function buildDefaultProfileEntries(): Record<string, ProfileEntry> {
|
|
|
621
687
|
const impl = BACKUP_PROFILE_IMPLS[key];
|
|
622
688
|
entries[key] = materializeProfile(impl, impl.provider);
|
|
623
689
|
}
|
|
690
|
+
entries[JEV_MANAGED_PROFILE_KEY] = materializeProfile(
|
|
691
|
+
JEV_MANAGED_PROFILE_TEMPLATE,
|
|
692
|
+
JEV_MANAGED_PROFILE_TEMPLATE.provider,
|
|
693
|
+
);
|
|
694
|
+
entries[AUTO_PROFILE_KEY] = materializeProfile(
|
|
695
|
+
AUTO_PROFILE_TEMPLATE,
|
|
696
|
+
AUTO_PROFILE_TEMPLATE.provider,
|
|
697
|
+
);
|
|
624
698
|
entries[OS_BETA_PROFILE_KEY] = materializeProfile(
|
|
625
699
|
OS_BETA_PROFILE_TEMPLATE,
|
|
626
700
|
OS_BETA_PROFILE_TEMPLATE.provider,
|
|
@@ -697,12 +771,13 @@ function resolveAgainstBody(
|
|
|
697
771
|
if (body == null) {
|
|
698
772
|
// A managed stub is the workspace's slot for a code-owned profile, never
|
|
699
773
|
// a profile of its own, so with no body behind it there is nothing to
|
|
700
|
-
// resolve. Only a
|
|
701
|
-
// default keys always have a body), and it
|
|
702
|
-
//
|
|
703
|
-
// profile with no provider or model and let a
|
|
704
|
-
// valid, which is precisely what `LLMSchema` rejects
|
|
705
|
-
|
|
774
|
+
// resolve. Only a managed-only name (a backup, the Jev profile) reaches
|
|
775
|
+
// this branch with a stub (the default keys always have a body), and it
|
|
776
|
+
// reaches it on the columns where those profiles do not exist. Resolving
|
|
777
|
+
// to the stub would list a profile with no provider or model and let a
|
|
778
|
+
// reference to it look valid, which is precisely what `LLMSchema` rejects
|
|
779
|
+
// on those columns.
|
|
780
|
+
if (isManagedOnlyProfileKey(name) && workspace?.source === "managed") {
|
|
706
781
|
return undefined;
|
|
707
782
|
}
|
|
708
783
|
return workspace;
|
|
@@ -711,7 +786,7 @@ function resolveAgainstBody(
|
|
|
711
786
|
return { ...body };
|
|
712
787
|
}
|
|
713
788
|
if (workspace == null) {
|
|
714
|
-
return name
|
|
789
|
+
return isFlagGatedProfileKey(name) ? undefined : { ...body };
|
|
715
790
|
}
|
|
716
791
|
if (workspace.source !== "managed") {
|
|
717
792
|
return workspace;
|
|
@@ -787,14 +862,14 @@ function defaultProfileBodyForProvider(
|
|
|
787
862
|
defaultProvider: DefaultProviderConfig | null,
|
|
788
863
|
): ProfileEntry | undefined {
|
|
789
864
|
if (!isDefaultProfileKey(name)) {
|
|
790
|
-
// Backup profiles
|
|
791
|
-
// under a BYOK or chatgpt default provider the
|
|
792
|
-
// `fallbackProfile` pointers, and
|
|
793
|
-
//
|
|
865
|
+
// Backup profiles and the managed Jev profile exist on the managed
|
|
866
|
+
// (`vellum`) column only: under a BYOK or chatgpt default provider the
|
|
867
|
+
// primaries carry no `fallbackProfile` pointers, and neither may
|
|
868
|
+
// materialize, since the install may hold no credential for their
|
|
794
869
|
// provider. A null defaultProvider predates `llm.defaultProvider` and
|
|
795
|
-
// resolves to the managed column, so it keeps
|
|
870
|
+
// resolves to the managed column, so it keeps them.
|
|
796
871
|
if (
|
|
797
|
-
|
|
872
|
+
isManagedOnlyProfileKey(name) &&
|
|
798
873
|
!backupProfilesResolveUnderDefaultProvider(defaultProvider)
|
|
799
874
|
) {
|
|
800
875
|
return undefined;
|
|
@@ -923,3 +998,27 @@ export function getUserSelectableProfilesForProvider(
|
|
|
923
998
|
}
|
|
924
999
|
return selectable;
|
|
925
1000
|
}
|
|
1001
|
+
|
|
1002
|
+
/**
|
|
1003
|
+
* The profiles a conversation can run on: the user-selectable view minus any
|
|
1004
|
+
* profile whose model returns structured answers rather than chat text (the
|
|
1005
|
+
* managed Jev profile). Every surface that picks or validates a conversation
|
|
1006
|
+
* profile (the `/model` command, a per-conversation pin, the plugin and
|
|
1007
|
+
* workflow listings) reads this view; the call-site override pickers keep
|
|
1008
|
+
* the wider selectable view, since the verdict sites are what Jev is for.
|
|
1009
|
+
*/
|
|
1010
|
+
export function getConversationProfilesForProvider(
|
|
1011
|
+
workspaceProfiles: Record<string, ProfileEntry> | undefined,
|
|
1012
|
+
defaultProvider: DefaultProviderConfig | null,
|
|
1013
|
+
): Record<string, ProfileEntry> {
|
|
1014
|
+
const selectable = getUserSelectableProfilesForProvider(
|
|
1015
|
+
workspaceProfiles,
|
|
1016
|
+
defaultProvider,
|
|
1017
|
+
);
|
|
1018
|
+
for (const [name, entry] of Object.entries(selectable)) {
|
|
1019
|
+
if (!profileSupportsTextGeneration(entry, selectable)) {
|
|
1020
|
+
delete selectable[name];
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
return selectable;
|
|
1024
|
+
}
|
|
@@ -67,6 +67,61 @@ export function isBackupProfileKey(value: string): value is BackupProfileKey {
|
|
|
67
67
|
return (BACKUP_PROFILE_KEYS as readonly string[]).includes(value);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Managed profile for the TypeSafe decision model (Jev). Deliberately NOT
|
|
72
|
+
* part of `DEFAULT_PROFILE_KEYS`: it has no BYOK column, because the
|
|
73
|
+
* platform serves Jev only through the managed route, and its model returns
|
|
74
|
+
* structured answers rather than chat text, so it can never be the active
|
|
75
|
+
* or conversation profile. It exists as a pin target for the call sites
|
|
76
|
+
* that consume a yes/no verdict (the voice judges, the memory selector).
|
|
77
|
+
*/
|
|
78
|
+
export const JEV_MANAGED_PROFILE_KEY = "jev-managed";
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Managed profile that picks one of the default profiles per message: the
|
|
82
|
+
* agent loop asks Jev which default fits the user's latest message and runs
|
|
83
|
+
* the turn on that profile (`daemon/auto-profile-router.ts`). Its own body
|
|
84
|
+
* is the managed Balanced body, so any path that dispatches the name
|
|
85
|
+
* directly, or a turn on which the router is unavailable, runs Balanced.
|
|
86
|
+
* Managed column only, because the router depends on the managed Jev route,
|
|
87
|
+
* and flag-gated: it exists only while the `auto-profile` feature flag has
|
|
88
|
+
* reconciled it into the workspace (see `sync-gated-profiles.ts`).
|
|
89
|
+
* Deliberately NOT part of `DEFAULT_PROFILE_KEYS`: it is a selection over
|
|
90
|
+
* those keys, not a fifth intent.
|
|
91
|
+
*/
|
|
92
|
+
export const AUTO_PROFILE_KEY = "auto";
|
|
93
|
+
export const AUTO_PROFILE_FEATURE_FLAG_KEY = "auto-profile";
|
|
94
|
+
|
|
95
|
+
/** The call site the automatic profile router asks Jev through. */
|
|
96
|
+
export const AUTO_PROFILE_ROUTER_CALL_SITE = "autoProfileRouter";
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The call sites that consume a structured verdict and so may be pinned to
|
|
100
|
+
* the Jev profile. Every other site expects chat text or a tool call, which
|
|
101
|
+
* the decision model never produces.
|
|
102
|
+
*/
|
|
103
|
+
export const JEV_MANAGED_PROFILE_CALL_SITES = [
|
|
104
|
+
"voiceEscalationJudge",
|
|
105
|
+
"voiceContinuationJudge",
|
|
106
|
+
"memoryV3SelectL2",
|
|
107
|
+
AUTO_PROFILE_ROUTER_CALL_SITE,
|
|
108
|
+
] as const;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Keys whose profile exists on the managed (`vellum`) column only: the
|
|
112
|
+
* backups, the Jev profile, and the Auto profile. Under a BYOK or ChatGPT
|
|
113
|
+
* default provider these names have no body to resolve to.
|
|
114
|
+
*/
|
|
115
|
+
export const MANAGED_ONLY_PROFILE_KEYS = [
|
|
116
|
+
...BACKUP_PROFILE_KEYS,
|
|
117
|
+
JEV_MANAGED_PROFILE_KEY,
|
|
118
|
+
AUTO_PROFILE_KEY,
|
|
119
|
+
] as const;
|
|
120
|
+
|
|
121
|
+
export function isManagedOnlyProfileKey(value: string): boolean {
|
|
122
|
+
return (MANAGED_ONLY_PROFILE_KEYS as readonly string[]).includes(value);
|
|
123
|
+
}
|
|
124
|
+
|
|
70
125
|
/**
|
|
71
126
|
* Flag-gated default profile: only available while the `os-beta` feature
|
|
72
127
|
* flag has reconciled it into the workspace (see `sync-gated-profiles.ts`).
|
|
@@ -76,6 +131,20 @@ export function isBackupProfileKey(value: string): value is BackupProfileKey {
|
|
|
76
131
|
*/
|
|
77
132
|
export const OS_BETA_PROFILE_KEY = "os-beta";
|
|
78
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Managed profiles that resolve only while a workspace entry exists, because
|
|
136
|
+
* a feature flag reconciles that entry in and out. Never always-valid
|
|
137
|
+
* reference targets: a reference to one is valid only with the entry present.
|
|
138
|
+
*/
|
|
139
|
+
export const FLAG_GATED_PROFILE_KEYS = [
|
|
140
|
+
OS_BETA_PROFILE_KEY,
|
|
141
|
+
AUTO_PROFILE_KEY,
|
|
142
|
+
] as const;
|
|
143
|
+
|
|
144
|
+
export function isFlagGatedProfileKey(value: string): boolean {
|
|
145
|
+
return (FLAG_GATED_PROFILE_KEYS as readonly string[]).includes(value);
|
|
146
|
+
}
|
|
147
|
+
|
|
79
148
|
/**
|
|
80
149
|
* The named columns of the intent × provider matrix. `vellum` is the
|
|
81
150
|
* platform-managed column (routed through the single `vellum` connection to
|
|
@@ -170,14 +170,6 @@
|
|
|
170
170
|
"description": "Enable Anthropic fast mode for Opus models (4.6, 4.7, 4.8), delivering up to 2.5x higher output tokens per second at premium pricing",
|
|
171
171
|
"defaultEnabled": false
|
|
172
172
|
},
|
|
173
|
-
{
|
|
174
|
-
"id": "teleport",
|
|
175
|
-
"scope": "client",
|
|
176
|
-
"key": "teleport",
|
|
177
|
-
"label": "Teleport",
|
|
178
|
-
"description": "Enable the local-to-platform teleport UI in General settings. Platform-to-local teleport is GA and not gated by this flag",
|
|
179
|
-
"defaultEnabled": false
|
|
180
|
-
},
|
|
181
173
|
{
|
|
182
174
|
"id": "apple-container",
|
|
183
175
|
"scope": "client",
|
|
@@ -346,6 +338,14 @@
|
|
|
346
338
|
"description": "Show the Add Server action on the MCP settings page. The MCP page itself remains visible; this flag gates only creating new Model Context Protocol server connections.",
|
|
347
339
|
"defaultEnabled": false
|
|
348
340
|
},
|
|
341
|
+
{
|
|
342
|
+
"id": "mcp-catalog-qa-integrations",
|
|
343
|
+
"scope": "assistant",
|
|
344
|
+
"key": "mcp-catalog-qa-integrations",
|
|
345
|
+
"label": "MCP Catalog QA Integrations",
|
|
346
|
+
"description": "Show Gamma, Guru, Intercom, Ramp, Semrush, and Typeform in the installable plugin catalog while their OAuth flows are validated. When off, catalog search, detail, and install-by-name cannot resolve them. Existing installed connections remain available.",
|
|
347
|
+
"defaultEnabled": false
|
|
348
|
+
},
|
|
349
349
|
{
|
|
350
350
|
"id": "os-beta",
|
|
351
351
|
"scope": "assistant",
|
|
@@ -354,6 +354,14 @@
|
|
|
354
354
|
"description": "Enable the OS Beta model profile (MiniMax M3 / Together) in the assistant's model profile selection.",
|
|
355
355
|
"defaultEnabled": false
|
|
356
356
|
},
|
|
357
|
+
{
|
|
358
|
+
"id": "auto-profile",
|
|
359
|
+
"scope": "assistant",
|
|
360
|
+
"key": "auto-profile",
|
|
361
|
+
"label": "Auto Profile",
|
|
362
|
+
"description": "Enable the Auto model profile, which asks Jev which default profile should answer each message.",
|
|
363
|
+
"defaultEnabled": false
|
|
364
|
+
},
|
|
357
365
|
{
|
|
358
366
|
"id": "new-thread-suggestions",
|
|
359
367
|
"scope": "client",
|
|
@@ -557,7 +565,15 @@
|
|
|
557
565
|
"scope": "client",
|
|
558
566
|
"key": "assistant-inbox",
|
|
559
567
|
"label": "Assistant Inbox",
|
|
560
|
-
"description": "Shows an Assistant Inbox entry above Preferences in the web sidebar and the /assistant/inbox page it opens: a mailbox for the assistant's managed vellum.me address (received and sent, with a reading pane), the inline email setup card for entitled orgs with no address yet, and an upgrade card for orgs without the managed_email entitlement. Off hides the entry
|
|
568
|
+
"description": "Shows an Assistant Inbox entry above Preferences in the web sidebar and the /assistant/inbox page it opens: a mailbox for the assistant's managed vellum.me address (received and sent, with a reading pane), the inline email setup card for entitled orgs with no address yet, and an upgrade card for orgs without the managed_email entitlement. With it on, email setup happens only there: the billing wizard hands off to the inbox instead of its own domain step, the billing page's finish-setup nudge gives way to the inbox's rail entry, and the Channels page's Email section points there instead of registering an address itself. Off hides the entry, redirects the route to chat, and keeps the older setup surfaces.",
|
|
569
|
+
"defaultEnabled": false
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
"id": "sidebar-done",
|
|
573
|
+
"scope": "both",
|
|
574
|
+
"key": "sidebar-done",
|
|
575
|
+
"label": "Sidebar Done",
|
|
576
|
+
"description": "Turns archiving a chat into marking it done: the sidebar row carries a Done check instead of the overflow menu, an All chats page lists the full history, and done chats stay findable in search by default. Off keeps today's Archive wording, the overflow menu, and search that hides archived rows unless the query asks for them.",
|
|
561
577
|
"defaultEnabled": false
|
|
562
578
|
}
|
|
563
579
|
]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getConversationProfilesForProvider } from "./default-profile-catalog.js";
|
|
2
2
|
import { getConfigReadOnly } from "./loader.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -6,17 +6,18 @@ import { getConfigReadOnly } from "./loader.js";
|
|
|
6
6
|
* (code-defined defaults + workspace `llm.profiles`). Returns a user-facing
|
|
7
7
|
* error message when the key is empty or unknown, or `null` when valid.
|
|
8
8
|
*
|
|
9
|
-
* Resolved through the `llm.defaultProvider`-aware
|
|
10
|
-
*
|
|
11
|
-
* routes remain available to automatic
|
|
12
|
-
*
|
|
9
|
+
* Resolved through the `llm.defaultProvider`-aware conversation view, since
|
|
10
|
+
* every caller (schedules, subagent spawns, per-conversation pins) runs chat
|
|
11
|
+
* turns on the result. Managed backup routes remain available to automatic
|
|
12
|
+
* fallback resolution, and the managed Jev profile to the verdict call
|
|
13
|
+
* sites, but neither is reported as a selectable profile here.
|
|
13
14
|
*/
|
|
14
15
|
export function validateInferenceProfileKey(profile: string): string | null {
|
|
15
16
|
if (!profile.trim()) {
|
|
16
17
|
return "inferenceProfile must be a non-empty string";
|
|
17
18
|
}
|
|
18
19
|
const llm = getConfigReadOnly().llm;
|
|
19
|
-
const profiles =
|
|
20
|
+
const profiles = getConversationProfilesForProvider(
|
|
20
21
|
llm?.profiles,
|
|
21
22
|
llm?.defaultProvider ?? null,
|
|
22
23
|
);
|
|
@@ -627,6 +627,22 @@ export function resolveDefaultProfileKey(
|
|
|
627
627
|
return selectWinningProfile(callSite, llm, {}).profileName ?? undefined;
|
|
628
628
|
}
|
|
629
629
|
|
|
630
|
+
/**
|
|
631
|
+
* Returns the code-owned profile tier for catalog display when that tier is
|
|
632
|
+
* available through the workspace's default provider. Workspace call-site
|
|
633
|
+
* pins do not affect this value. A managed-only tier on a BYOK install returns
|
|
634
|
+
* undefined so clients do not report a profile that cannot run there.
|
|
635
|
+
*/
|
|
636
|
+
export function resolveShippedDefaultProfileKey(
|
|
637
|
+
callSite: LLMCallSite,
|
|
638
|
+
llm: z.infer<typeof LLMSchema>,
|
|
639
|
+
): string | undefined {
|
|
640
|
+
const intent = CALL_SITE_DEFAULTS[callSite]?.profile ?? "balanced";
|
|
641
|
+
return usableDefaultIntent(intent, llm, {}, () => undefined) == null
|
|
642
|
+
? undefined
|
|
643
|
+
: intent;
|
|
644
|
+
}
|
|
645
|
+
|
|
630
646
|
/**
|
|
631
647
|
* Returns the profile key that `resolveCallSiteConfig` treats as the winning
|
|
632
648
|
* (highest-precedence) profile for a turn — the profile whose fragment supplies
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* that endpoint into the in-memory overrides. Resolution reads those
|
|
7
7
|
* overrides (and `PLATFORM_ORGANIZATION_ID` / `PLATFORM_USER_ID` when set).
|
|
8
8
|
* When the in-memory assistant id is empty, the next resolve retries
|
|
9
|
-
* validate (single-flight, with a cooldown after a failed attempt
|
|
9
|
+
* validate (single-flight, with a cooldown after a failed attempt that holds
|
|
10
|
+
* only while the same API key and base URL are stored).
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
import { credentialKey } from "../security/credential-key.js";
|
|
@@ -121,10 +122,19 @@ async function readAssistantApiKey(): Promise<string> {
|
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
let ensureInFlight: Promise<void> | null = null;
|
|
125
|
+
// The cooldown is bound to the credentials that failed: the same key against
|
|
126
|
+
// the same base URL is not re-sent for ENSURE_COOLDOWN_MS, while a change to
|
|
127
|
+
// either is validated on the next resolve.
|
|
128
|
+
let failedFingerprint: string | null = null;
|
|
124
129
|
let nextEnsureAttemptAt = 0;
|
|
125
130
|
|
|
131
|
+
function identityFingerprint(apiKey: string, baseUrl: string): string {
|
|
132
|
+
return `${baseUrl}\0${apiKey}`;
|
|
133
|
+
}
|
|
134
|
+
|
|
126
135
|
export function _resetPlatformIdentityEnsureForTests(): void {
|
|
127
136
|
ensureInFlight = null;
|
|
137
|
+
failedFingerprint = null;
|
|
128
138
|
nextEnsureAttemptAt = 0;
|
|
129
139
|
}
|
|
130
140
|
|
|
@@ -132,16 +142,14 @@ export function _resetPlatformIdentityEnsureForTests(): void {
|
|
|
132
142
|
* Load in-memory platform ids from validate when they are missing.
|
|
133
143
|
*
|
|
134
144
|
* No-ops when the assistant id is already set, when auth prerequisites are
|
|
135
|
-
* missing, or when
|
|
145
|
+
* missing, or when the stored API key and base URL are the ones a failed
|
|
146
|
+
* attempt used and that attempt is still inside the cooldown window.
|
|
136
147
|
* Concurrent callers share one in-flight request.
|
|
137
148
|
*/
|
|
138
149
|
export async function ensurePlatformIdentityIds(): Promise<void> {
|
|
139
150
|
if (getPlatformAssistantId()?.trim()) {
|
|
140
151
|
return;
|
|
141
152
|
}
|
|
142
|
-
if (Date.now() < nextEnsureAttemptAt) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
153
|
if (!ensureInFlight) {
|
|
146
154
|
ensureInFlight = (async () => {
|
|
147
155
|
try {
|
|
@@ -150,12 +158,21 @@ export async function ensurePlatformIdentityIds(): Promise<void> {
|
|
|
150
158
|
if (!apiKey || !baseUrl) {
|
|
151
159
|
return;
|
|
152
160
|
}
|
|
161
|
+
const fingerprint = identityFingerprint(apiKey, baseUrl);
|
|
162
|
+
if (
|
|
163
|
+
fingerprint === failedFingerprint &&
|
|
164
|
+
Date.now() < nextEnsureAttemptAt
|
|
165
|
+
) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
153
168
|
const ids = await fetchPlatformIdentityIds(baseUrl, apiKey);
|
|
154
169
|
if (!ids) {
|
|
170
|
+
failedFingerprint = fingerprint;
|
|
155
171
|
nextEnsureAttemptAt = Date.now() + ENSURE_COOLDOWN_MS;
|
|
156
172
|
return;
|
|
157
173
|
}
|
|
158
174
|
applyPlatformIdentityIds(ids);
|
|
175
|
+
failedFingerprint = null;
|
|
159
176
|
nextEnsureAttemptAt = 0;
|
|
160
177
|
log.info("Loaded platform identity from platform validate");
|
|
161
178
|
} finally {
|
|
@@ -15,6 +15,15 @@ describe("profileSupportsTextGeneration", () => {
|
|
|
15
15
|
).toBe(false);
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
+
test("false for the managed Jev profile shape", () => {
|
|
19
|
+
expect(
|
|
20
|
+
profileSupportsTextGeneration(
|
|
21
|
+
{ provider: "vellum", model: "jev-latest" },
|
|
22
|
+
{},
|
|
23
|
+
),
|
|
24
|
+
).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
|
|
18
27
|
test("true for a chat model and for unlisted custom ids", () => {
|
|
19
28
|
expect(
|
|
20
29
|
profileSupportsTextGeneration(
|
|
@@ -307,7 +307,7 @@ const CATALOG_RECORD: CatalogRecord = {
|
|
|
307
307
|
id: "voiceEscalationJudge",
|
|
308
308
|
displayName: "Voice Escalation Judge",
|
|
309
309
|
description:
|
|
310
|
-
"Second opinion on the voice front door's escalate decision.
|
|
310
|
+
"Second opinion on the voice front door's escalate decision. Uses managed Jev when Vellum-managed inference is available, or an explicitly configured TypeSafe profile; a confident 'needs tools' verdict hands the turn to the escalated leg.",
|
|
311
311
|
domain: "agentLoop",
|
|
312
312
|
},
|
|
313
313
|
voiceContinuationJudge: {
|
|
@@ -317,6 +317,13 @@ const CATALOG_RECORD: CatalogRecord = {
|
|
|
317
317
|
"Decides from the caller's interruption whether a barged-in request should keep running in the background. Runs only when pinned to a TypeSafe profile.",
|
|
318
318
|
domain: "agentLoop",
|
|
319
319
|
},
|
|
320
|
+
autoProfileRouter: {
|
|
321
|
+
id: "autoProfileRouter",
|
|
322
|
+
displayName: "Auto Profile Router",
|
|
323
|
+
description:
|
|
324
|
+
"Picks which default profile answers a message when the conversation runs on the Auto profile. Asks managed Jev one choice question over the latest message; when unavailable the turn runs on Balanced.",
|
|
325
|
+
domain: "agentLoop",
|
|
326
|
+
},
|
|
320
327
|
voiceContinuationLabel: {
|
|
321
328
|
id: "voiceContinuationLabel",
|
|
322
329
|
displayName: "Voice Continuation Label",
|