@vellumai/assistant 0.11.3 → 0.11.4-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/ARCHITECTURE.md +11 -6
- package/docs/architecture/memory.md +11 -0
- package/docs/architecture/turn-actor.md +70 -0
- package/docs/flux-turn-detection-spike.md +243 -0
- package/docs/stt-provider-onboarding.md +3 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +34 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +2 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/openapi.yaml +140 -38
- package/package.json +1 -1
- package/scripts/voice-ttft-spike.ts +3 -3
- package/src/__tests__/app-compiler.test.ts +38 -3
- package/src/__tests__/attachments-store.test.ts +21 -12
- package/src/__tests__/byok-default-profile-ensure.test.ts +2 -0
- package/src/__tests__/call-setup-flow-name-capture.test.ts +0 -1
- package/src/__tests__/call-site-routing-provider.test.ts +1 -1
- package/src/__tests__/channel-availability-routes.test.ts +14 -1
- package/src/__tests__/channel-capabilities-dedupe.test.ts +214 -0
- package/src/__tests__/channel-delivery-store.test.ts +14 -14
- package/src/__tests__/config-loader-backfill.test.ts +3 -3
- package/src/__tests__/config-schema.test.ts +25 -10
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +8 -11
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +8 -11
- package/src/__tests__/conversation-agent-loop.test.ts +28 -20
- package/src/__tests__/conversation-attention-store.test.ts +63 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -4
- package/src/__tests__/conversation-fork-crud.test.ts +69 -0
- package/src/__tests__/conversation-fork-referential.test.ts +67 -0
- package/src/__tests__/conversation-fork-retrospective.test.ts +24 -0
- package/src/__tests__/conversation-notifiers-provenance.test.ts +59 -0
- package/src/__tests__/conversation-queue.test.ts +55 -4
- package/src/__tests__/conversation-runtime-assembly.test.ts +134 -102
- package/src/__tests__/conversation-runtime-workspace.test.ts +14 -10
- package/src/__tests__/credential-prompt-route.test.ts +7 -10
- package/src/__tests__/custom-profile-ensure.test.ts +5 -1
- package/src/__tests__/discord-access-request-privacy.test.ts +5 -1
- package/src/__tests__/discord-requester-notice-privacy.test.ts +3 -3
- package/src/__tests__/document-append-idempotency.test.ts +233 -0
- package/src/__tests__/edit-propagation.test.ts +0 -7
- package/src/__tests__/helpers/mock-actor-context.ts +49 -0
- package/src/__tests__/helpers/mock-conversation.ts +13 -1
- package/src/__tests__/injector-chain.test.ts +63 -41
- package/src/__tests__/injector-disk-pressure.test.ts +11 -23
- package/src/__tests__/llm-context-resolution.test.ts +73 -1
- package/src/__tests__/llm-schema.test.ts +5 -2
- package/src/__tests__/mcp-list-plugin-servers.test.ts +250 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +6 -5
- package/src/__tests__/messages-read-boundary-guard.test.ts +134 -0
- package/src/__tests__/mtime-cache.test.ts +1 -1
- package/src/__tests__/non-member-access-request.test.ts +0 -20
- package/src/__tests__/outbound-slack-persistence.test.ts +40 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -0
- package/src/__tests__/plugin-secret-pattern-contribution.test.ts +1 -1
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +14 -7
- package/src/__tests__/provider-commit-message-generator.test.ts +20 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +434 -105
- package/src/__tests__/scoped-approval-grants.test.ts +11 -6
- package/src/__tests__/secret-ingress-channel.test.ts +0 -1
- package/src/__tests__/skills.test.ts +32 -0
- package/src/__tests__/slack-edit-ordering-characterization.test.ts +0 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +31 -19
- package/src/__tests__/subagent-spawn-and-await.test.ts +14 -10
- package/src/__tests__/turn-events-store.test.ts +43 -0
- package/src/__tests__/user-plugin-loader.test.ts +1 -1
- package/src/__tests__/visible-app-context.test.ts +16 -9
- package/src/__tests__/worker-entrypoint-guards.test.ts +54 -0
- package/src/__tests__/worker-plugin-surface.test.ts +77 -0
- package/src/__tests__/workspace-migration-142-consolidate-voice-front-door.test.ts +158 -0
- package/src/__tests__/workspace-migration-143-repair-deprecated-codex-model-id.test.ts +133 -0
- package/src/__tests__/workspace-migration-144-convert-stranded-subscription-openai-profiles.test.ts +316 -0
- package/src/__tests__/workspace-migration-145-collapse-profile-bindings-to-entries.test.ts +325 -0
- package/src/acp/__tests__/acp-claude-oauth.test.ts +10 -2
- package/src/acp/__tests__/auth-required.test.ts +161 -0
- package/src/acp/acp-claude-oauth.ts +19 -2
- package/src/acp/agent-process.test.ts +100 -0
- package/src/acp/agent-process.ts +29 -26
- package/src/acp/auth-required.ts +102 -0
- package/src/acp/session-manager.test.ts +119 -0
- package/src/acp/session-manager.ts +68 -2
- package/src/api/events/acp-auth-required.ts +55 -0
- package/src/api/index.ts +7 -0
- package/src/apps/app-store.ts +3 -0
- package/src/bundler/package-resolver.ts +2 -30
- package/src/calls/__tests__/voice-session-bridge.test.ts +173 -1
- package/src/calls/__tests__/voice-triage-escalate.test.ts +94 -0
- package/src/calls/call-controller.ts +9 -2
- package/src/calls/call-setup-flow.ts +0 -1
- package/src/calls/media-stream-stt-session.ts +15 -0
- package/src/calls/voice-session-bridge.ts +71 -16
- package/src/calls/voice-triage-escalate.ts +104 -2
- package/src/channels/__tests__/plugin-channel-declarations.test.ts +161 -0
- package/src/channels/config.ts +13 -0
- package/src/channels/plugin-channel-declarations.ts +108 -0
- package/src/channels/types.ts +30 -0
- package/src/cli/AGENTS.md +5 -2
- package/src/cli/commands/credentials.help.ts +2 -2
- package/src/cli/commands/inference-providers.ts +1 -1
- package/src/cli/commands/mcp.help.ts +13 -4
- package/src/cli/commands/mcp.ts +9 -0
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +128 -5
- package/src/cli/commands/memory/index.help.ts +43 -1
- package/src/cli/commands/memory/memory-v3.ts +64 -0
- package/src/cli/commands/stt.help.ts +27 -2
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +39 -0
- package/src/cli/lib/bundled-marketplace.json +13 -0
- package/src/cli/lib/upgrade-plugin.ts +42 -0
- package/src/config/__tests__/default-profile-catalog.test.ts +34 -2
- package/src/config/__tests__/default-provider.test.ts +6 -1
- package/src/config/__tests__/profile-materialization.test.ts +75 -19
- package/src/config/bundled-skills/acp/SKILL.md +6 -7
- package/src/config/bundled-skills/document-editor/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +14 -4
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +22 -1
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +9 -2
- package/src/config/call-site-defaults.ts +4 -5
- package/src/config/default-profile-catalog.ts +82 -11
- package/src/config/default-profile-names.ts +4 -1
- package/src/config/default-provider-resolution.ts +4 -0
- package/src/config/llm-context-resolution.ts +11 -3
- package/src/config/llm-resolver.ts +28 -1
- package/src/config/profile-materialization.ts +70 -22
- package/src/config/schemas/__tests__/live-voice.test.ts +107 -4
- package/src/config/schemas/call-site-catalog.ts +4 -4
- package/src/config/schemas/live-voice.ts +57 -23
- package/src/config/schemas/llm.ts +59 -32
- package/src/config/schemas/mcp.ts +23 -0
- package/src/config/schemas/plugin-updates.ts +6 -2
- package/src/config/schemas/stt.ts +1 -0
- package/src/context/outbound-sanitize.ts +96 -1
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +82 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +15 -10
- package/src/daemon/conversation-agent-loop.ts +17 -6
- package/src/daemon/conversation-messaging.ts +5 -1
- package/src/daemon/conversation-notifiers.ts +9 -1
- package/src/daemon/conversation-process.ts +9 -6
- package/src/daemon/conversation-runtime-assembly.ts +3 -4
- package/src/daemon/conversation-tool-setup.ts +1 -2
- package/src/daemon/conversation.ts +48 -0
- package/src/daemon/mcp-reload-service.ts +36 -6
- package/src/daemon/process-message.ts +13 -3
- package/src/daemon/providers-setup.ts +6 -3
- package/src/daemon/trust-context-types.ts +29 -0
- package/src/daemon/wake-conversation-ops.ts +3 -2
- package/src/documents/document-store.ts +138 -5
- package/src/hooks/hook-loader.ts +3 -3
- package/src/hooks/registry.ts +50 -6
- package/src/inbound/__tests__/oauth-callback-url.test.ts +83 -0
- package/src/inbound/oauth-callback-url.ts +61 -0
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +1 -104
- package/src/live-voice/__tests__/live-voice-events.test.ts +7 -8
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +932 -0
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +115 -8
- package/src/live-voice/__tests__/live-voice-photo.test.ts +100 -0
- package/src/live-voice/__tests__/live-voice-progress.test.ts +60 -194
- package/src/live-voice/__tests__/live-voice-stt.test.ts +14 -0
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +29 -0
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +0 -483
- package/src/live-voice/__tests__/live-voice-vad.test.ts +0 -16
- package/src/live-voice/__tests__/progress-narration.test.ts +214 -0
- package/src/live-voice/live-voice-archive.ts +2 -0
- package/src/live-voice/live-voice-metrics.ts +57 -32
- package/src/live-voice/live-voice-photo.ts +1 -2
- package/src/live-voice/live-voice-session.ts +535 -314
- package/src/live-voice/progress-narration.ts +277 -0
- package/src/live-voice/protocol.ts +21 -1
- package/src/mcp/__tests__/effective-config.test.ts +238 -0
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
- package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +200 -0
- package/src/mcp/__tests__/mcp-oauth-provider.test.ts +9 -9
- package/src/mcp/__tests__/plugin-server-credential-isolation.test.ts +95 -0
- package/src/mcp/client.ts +16 -11
- package/src/mcp/effective-config.ts +113 -0
- package/src/mcp/manager.ts +11 -6
- package/src/mcp/mcp-auth-orchestrator.ts +13 -22
- package/src/mcp/mcp-oauth-provider.ts +205 -240
- package/src/monitoring/__tests__/plugin-auto-update.test.ts +166 -3
- package/src/monitoring/plugin-auto-update.ts +128 -24
- package/src/notifications/signal.ts +1 -0
- package/src/permissions/confirmation-guardian-request.test.ts +15 -11
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/question-guardian-request.test.ts +14 -6
- package/src/permissions/question-guardian-request.ts +1 -2
- package/src/persistence/attachments-store.ts +8 -1
- package/src/persistence/bookmark-crud.ts +3 -7
- package/src/persistence/conversation-attention-store.ts +16 -45
- package/src/persistence/conversation-crud.ts +33 -4
- package/src/persistence/conversation-lineage.ts +9 -0
- package/src/persistence/conversation-queries.ts +108 -41
- package/src/persistence/delivery-crud.ts +38 -29
- package/src/persistence/external-conversation-store.ts +32 -4
- package/src/persistence/llm-request-log-store.ts +4 -10
- package/src/persistence/llm-usage-store.ts +8 -3
- package/src/persistence/message-reads.test.ts +197 -0
- package/src/persistence/message-reads.ts +211 -0
- package/src/persistence/migrations/366-chatgpt-subscription-row-identity.test.ts +120 -0
- package/src/persistence/migrations/366-chatgpt-subscription-row-identity.ts +62 -0
- package/src/persistence/real-user-turn-filter.ts +27 -3
- package/src/persistence/steps.ts +9 -0
- package/src/plugin-api/__tests__/oauth-callback-url-export.test.ts +29 -0
- package/src/plugin-api/conversation-turn.ts +168 -5
- package/src/plugin-api/index.ts +21 -5
- package/src/plugins/__tests__/mcp-servers.test.ts +371 -0
- package/src/plugins/defaults/memory/AGENTS.md +4 -0
- package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +204 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +72 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +4 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +4 -1
- package/src/plugins/defaults/memory/buffer-format.ts +165 -0
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +6 -0
- package/src/plugins/defaults/memory/graph/image-ref-utils.ts +3 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +1 -30
- package/src/plugins/defaults/memory/graph-topology/pending-buffer.test.ts +34 -0
- package/src/plugins/defaults/memory/graph-topology/pending-buffer.ts +8 -12
- package/src/plugins/defaults/memory/hooks/post-compact.ts +1 -4
- package/src/plugins/defaults/memory/indexer.ts +3 -1
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +19 -7
- package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +281 -0
- package/src/plugins/defaults/memory/src/memory-v3-routes.ts +207 -0
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +33 -0
- package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +199 -2
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +25 -18
- package/src/plugins/defaults/memory/substrate/skill-content.ts +8 -1
- package/src/plugins/defaults/memory/substrate/static-context.ts +160 -4
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +2 -4
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +3 -1
- package/src/plugins/defaults/memory/v3/prune.ts +2 -0
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +2 -0
- package/src/plugins/defaults/memory/worker.ts +6 -3
- package/src/plugins/external-plugin-loader.ts +47 -0
- package/src/plugins/mcp-servers.ts +361 -0
- package/src/plugins/mtime-cache.ts +23 -49
- package/src/plugins/worker-plugin-surface.ts +33 -0
- package/src/providers/__tests__/connection-model-compat.test.ts +1 -1
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +214 -2
- package/src/providers/__tests__/preflight-resolved-config.test.ts +57 -0
- package/src/providers/__tests__/retry-callsite.test.ts +5 -2
- package/src/providers/call-site-routing.ts +30 -3
- package/src/providers/connection-resolution.ts +194 -11
- package/src/providers/inference/auth.ts +6 -0
- package/src/providers/inference/connection-availability.ts +24 -2
- package/src/providers/inference/connections.ts +2 -0
- package/src/providers/model-intents.ts +26 -6
- package/src/providers/openai/codex-models.ts +2 -1
- package/src/providers/provider-send-message.ts +32 -3
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +433 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +620 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +34 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +285 -6
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +395 -0
- package/src/providers/speech-to-text/deepgram-flux-realtime.ts +719 -0
- package/src/providers/speech-to-text/provider-catalog.ts +99 -8
- package/src/providers/speech-to-text/resolve.ts +25 -2
- package/src/routes/worker.ts +17 -5
- package/src/runtime/access-request-helper.ts +9 -12
- package/src/runtime/agent-wake.ts +3 -3
- package/src/runtime/pre-first-message-gate.ts +4 -0
- package/src/runtime/routes/__tests__/acp-claude-auth-routes.test.ts +12 -4
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +219 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +52 -0
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +61 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +44 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +102 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +44 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +25 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +62 -1
- package/src/runtime/routes/channel-availability-routes.ts +32 -14
- package/src/runtime/routes/channel-route-shared.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +6 -6
- package/src/runtime/routes/conversation-list-routes.ts +112 -1
- package/src/runtime/routes/conversation-query-routes.ts +40 -27
- package/src/runtime/routes/credential-prompt-routes.ts +4 -7
- package/src/runtime/routes/default-provider-routes.ts +15 -0
- package/src/runtime/routes/inbound-message-handler.ts +17 -41
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -9
- package/src/runtime/routes/inbound-stages/admission-policy.ts +1 -17
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +1 -3
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -4
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +11 -20
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +2 -3
- package/src/runtime/routes/inference-profiles-routes.ts +20 -11
- package/src/runtime/routes/inference-provider-connection-routes.ts +77 -15
- package/src/runtime/routes/log-export-routes.ts +3 -0
- package/src/runtime/routes/mcp-auth-routes.ts +148 -57
- package/src/runtime/routes/plugins-routes.ts +21 -3
- package/src/runtime/routes/stt-routes.ts +31 -25
- package/src/runtime/routes/surface-conversation-resolver.ts +3 -0
- package/src/runtime/routes/user-route-dispatcher.ts +39 -14
- package/src/runtime/routes/user-route-import.ts +108 -0
- package/src/schedule/worker.ts +6 -0
- package/src/security/oauth2.ts +6 -22
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +22 -0
- package/src/stt/__tests__/types.test.ts +94 -0
- package/src/stt/daemon-batch-transcriber.ts +10 -0
- package/src/stt/stt-stream-session.ts +8 -4
- package/src/stt/types.ts +103 -0
- package/src/subagent/manager.ts +1 -3
- package/src/subagent/types.ts +7 -6
- package/src/tools/acp/spawn.test.ts +97 -0
- package/src/tools/acp/spawn.ts +32 -0
- package/src/tools/document/document-tool.ts +12 -3
- package/src/tools/registry.ts +2 -1
- package/src/tools/workflows/run-workflow.ts +1 -2
- package/src/tts/__tests__/reasoning-tag-filter.test.ts +63 -0
- package/src/tts/reasoning-tag-filter.ts +110 -0
- package/src/workspace/byok-default-profile-ensure.ts +61 -18
- package/src/workspace/custom-profile-ensure.ts +4 -24
- package/src/workspace/migrations/142-consolidate-voice-front-door.ts +70 -0
- package/src/workspace/migrations/143-repair-deprecated-codex-model-id.ts +134 -0
- package/src/workspace/migrations/144-convert-stranded-subscription-openai-profiles.ts +265 -0
- package/src/workspace/migrations/145-collapse-profile-bindings-to-entries.ts +328 -0
- package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +0 -10
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/provider-commit-message-generator.ts +7 -5
- package/src/live-voice/__tests__/front-decision.test.ts +0 -645
- package/src/live-voice/front-decision.ts +0 -476
|
@@ -101,7 +101,6 @@ import {
|
|
|
101
101
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
102
102
|
import { deliverChannelReply } from "../gateway-client.js";
|
|
103
103
|
import { trustContextFromVerdict } from "../trust-verdict-consumer.js";
|
|
104
|
-
import { canonicalChannelAssistantId } from "./channel-route-shared.js";
|
|
105
104
|
import { BadRequestError } from "./errors.js";
|
|
106
105
|
import { handleApprovalInterception } from "./guardian-approval-interception.js";
|
|
107
106
|
import {
|
|
@@ -371,16 +370,6 @@ export async function handleChannelInbound({
|
|
|
371
370
|
throw new BadRequestError("content or attachmentIds is required");
|
|
372
371
|
}
|
|
373
372
|
|
|
374
|
-
// Canonicalize the assistant ID so all DB-facing operations use the
|
|
375
|
-
// consistent 'self' key regardless of what the gateway sent.
|
|
376
|
-
const canonicalAssistantId = canonicalChannelAssistantId(assistantId);
|
|
377
|
-
if (canonicalAssistantId !== assistantId) {
|
|
378
|
-
log.debug(
|
|
379
|
-
{ raw: assistantId, canonical: canonicalAssistantId },
|
|
380
|
-
"Canonicalized channel assistant ID",
|
|
381
|
-
);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
373
|
// Coerce actorExternalId to a string at the boundary — the field
|
|
385
374
|
// comes from unvalidated JSON and may be a number, object, or other
|
|
386
375
|
// non-string type. Non-string truthy values would throw inside
|
|
@@ -438,7 +427,6 @@ export async function handleChannelInbound({
|
|
|
438
427
|
sourceInterface,
|
|
439
428
|
conversationExternalId,
|
|
440
429
|
externalMessageId,
|
|
441
|
-
canonicalAssistantId,
|
|
442
430
|
rawSenderId,
|
|
443
431
|
canonicalSenderId,
|
|
444
432
|
actorDisplayName: body.actorDisplayName,
|
|
@@ -486,7 +474,6 @@ export async function handleChannelInbound({
|
|
|
486
474
|
rawSenderId,
|
|
487
475
|
sourceChannel,
|
|
488
476
|
conversationExternalId,
|
|
489
|
-
canonicalAssistantId,
|
|
490
477
|
trimmedContent,
|
|
491
478
|
sourceMetadata: body.sourceMetadata,
|
|
492
479
|
actorDisplayName: body.actorDisplayName,
|
|
@@ -709,7 +696,6 @@ export async function handleChannelInbound({
|
|
|
709
696
|
externalMessageId,
|
|
710
697
|
sourceMessageId,
|
|
711
698
|
sourceThreadId: channelThreadId,
|
|
712
|
-
canonicalAssistantId,
|
|
713
699
|
assistantId,
|
|
714
700
|
content,
|
|
715
701
|
channelId: resolvedMember?.channelId,
|
|
@@ -723,28 +709,24 @@ export async function handleChannelInbound({
|
|
|
723
709
|
externalMessageId,
|
|
724
710
|
{
|
|
725
711
|
sourceMessageId,
|
|
726
|
-
assistantId: canonicalAssistantId,
|
|
727
712
|
sourceThreadId: channelThreadId,
|
|
728
713
|
},
|
|
729
714
|
);
|
|
730
715
|
|
|
731
716
|
const replyCallbackUrl = body.replyCallbackUrl;
|
|
732
717
|
|
|
733
|
-
// external_conversation_bindings is assistant-agnostic
|
|
734
|
-
//
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
username: body.actorUsername ?? null,
|
|
746
|
-
});
|
|
747
|
-
}
|
|
718
|
+
// `external_conversation_bindings` is assistant-agnostic: one row per chat,
|
|
719
|
+
// whichever caller writes it.
|
|
720
|
+
upsertBinding({
|
|
721
|
+
conversationId: result.conversationId,
|
|
722
|
+
sourceChannel,
|
|
723
|
+
externalChatId: conversationExternalId,
|
|
724
|
+
externalChatName: slackChannelName,
|
|
725
|
+
externalThreadId: channelThreadId ?? null,
|
|
726
|
+
externalUserId: canonicalSenderId ?? rawSenderId ?? null,
|
|
727
|
+
displayName: body.actorDisplayName ?? null,
|
|
728
|
+
username: body.actorUsername ?? null,
|
|
729
|
+
});
|
|
748
730
|
|
|
749
731
|
// ── Actor role resolution ──
|
|
750
732
|
// Built from the gateway-stamped trust verdict (ACL + identity). An absent
|
|
@@ -844,7 +826,6 @@ export async function handleChannelInbound({
|
|
|
844
826
|
if (isCallbackInteraction) {
|
|
845
827
|
if (floorSenderId) {
|
|
846
828
|
handshakeInProgress = await isApprovalHandshakeInProgress({
|
|
847
|
-
canonicalAssistantId,
|
|
848
829
|
sourceChannel,
|
|
849
830
|
actorExternalId: floorSenderId,
|
|
850
831
|
});
|
|
@@ -852,7 +833,6 @@ export async function handleChannelInbound({
|
|
|
852
833
|
} else {
|
|
853
834
|
try {
|
|
854
835
|
const accessResult = await notifyGuardianOfAccessRequest({
|
|
855
|
-
canonicalAssistantId,
|
|
856
836
|
sourceChannel,
|
|
857
837
|
conversationExternalId,
|
|
858
838
|
actorExternalId: floorSenderId,
|
|
@@ -925,7 +905,7 @@ export async function handleChannelInbound({
|
|
|
925
905
|
const replyPayload: Parameters<typeof deliverChannelReply>[1] = {
|
|
926
906
|
chatId: conversationExternalId,
|
|
927
907
|
text: replyText,
|
|
928
|
-
assistantId:
|
|
908
|
+
assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
|
|
929
909
|
};
|
|
930
910
|
if (sourceChannel === "slack" && (canonicalSenderId ?? rawSenderId)) {
|
|
931
911
|
replyPayload.ephemeral = true;
|
|
@@ -987,7 +967,7 @@ export async function handleChannelInbound({
|
|
|
987
967
|
const replyPayload: Parameters<typeof deliverChannelReply>[1] = {
|
|
988
968
|
chatId: conversationExternalId,
|
|
989
969
|
text: DISK_PRESSURE_REMOTE_BLOCK_REPLY,
|
|
990
|
-
assistantId:
|
|
970
|
+
assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
|
|
991
971
|
};
|
|
992
972
|
if (sourceChannel === "slack" && (canonicalSenderId ?? rawSenderId)) {
|
|
993
973
|
replyPayload.ephemeral = true;
|
|
@@ -1059,7 +1039,6 @@ export async function handleChannelInbound({
|
|
|
1059
1039
|
isDuplicate: result.duplicate,
|
|
1060
1040
|
commandIntent,
|
|
1061
1041
|
rawSenderId,
|
|
1062
|
-
canonicalAssistantId,
|
|
1063
1042
|
sourceChannel,
|
|
1064
1043
|
conversationExternalId,
|
|
1065
1044
|
eventId: result.eventId,
|
|
@@ -1081,7 +1060,6 @@ export async function handleChannelInbound({
|
|
|
1081
1060
|
callbackData: body.callbackData,
|
|
1082
1061
|
rawSenderId,
|
|
1083
1062
|
canonicalSenderId,
|
|
1084
|
-
canonicalAssistantId,
|
|
1085
1063
|
sourceChannel,
|
|
1086
1064
|
conversationExternalId,
|
|
1087
1065
|
conversationId: result.conversationId,
|
|
@@ -1123,7 +1101,7 @@ export async function handleChannelInbound({
|
|
|
1123
1101
|
actorExternalId: canonicalSenderId ?? rawSenderId,
|
|
1124
1102
|
replyCallbackUrl,
|
|
1125
1103
|
trustCtx,
|
|
1126
|
-
assistantId:
|
|
1104
|
+
assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
|
|
1127
1105
|
approvalCopyGenerator,
|
|
1128
1106
|
approvalConversationGenerator,
|
|
1129
1107
|
approvalMessageTs,
|
|
@@ -1219,7 +1197,7 @@ export async function handleChannelInbound({
|
|
|
1219
1197
|
chatId: conversationExternalId,
|
|
1220
1198
|
text: "This approval request has been resolved.",
|
|
1221
1199
|
messageTs: approvalMessageTs,
|
|
1222
|
-
assistantId:
|
|
1200
|
+
assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
|
|
1223
1201
|
}).catch((err) => {
|
|
1224
1202
|
log.error(
|
|
1225
1203
|
{ err, conversationId: result.conversationId },
|
|
@@ -1255,7 +1233,6 @@ export async function handleChannelInbound({
|
|
|
1255
1233
|
actorUsername: body.actorUsername,
|
|
1256
1234
|
trustCtx,
|
|
1257
1235
|
replyCallbackUrl,
|
|
1258
|
-
canonicalAssistantId,
|
|
1259
1236
|
});
|
|
1260
1237
|
|
|
1261
1238
|
if (ingressResult.blocked) {
|
|
@@ -1296,7 +1273,6 @@ export async function handleChannelInbound({
|
|
|
1296
1273
|
const admittedSenderId = canonicalSenderId ?? rawSenderId;
|
|
1297
1274
|
if (admittedSenderId) {
|
|
1298
1275
|
void maybeNotifyGuardianOfAdmittedContact({
|
|
1299
|
-
canonicalAssistantId,
|
|
1300
1276
|
sourceChannel,
|
|
1301
1277
|
conversationExternalId,
|
|
1302
1278
|
actorExternalId: admittedSenderId,
|
|
@@ -1497,7 +1473,7 @@ export async function handleChannelInbound({
|
|
|
1497
1473
|
commandIntent,
|
|
1498
1474
|
sourceLanguageCode,
|
|
1499
1475
|
replyCallbackUrl,
|
|
1500
|
-
assistantId:
|
|
1476
|
+
assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
|
|
1501
1477
|
approvalCopyGenerator,
|
|
1502
1478
|
chatType: sourceChatType,
|
|
1503
1479
|
clientTimezone: inboundClientTimezone,
|
|
@@ -90,7 +90,6 @@ export interface AclEnforcementParams {
|
|
|
90
90
|
rawSenderId: string | undefined;
|
|
91
91
|
sourceChannel: ChannelId;
|
|
92
92
|
conversationExternalId: string;
|
|
93
|
-
canonicalAssistantId: string;
|
|
94
93
|
trimmedContent: string;
|
|
95
94
|
sourceMetadata: SourceMetadata | undefined;
|
|
96
95
|
actorDisplayName: string | undefined;
|
|
@@ -190,7 +189,6 @@ export async function enforceIngressAcl(
|
|
|
190
189
|
rawSenderId,
|
|
191
190
|
sourceChannel,
|
|
192
191
|
conversationExternalId,
|
|
193
|
-
canonicalAssistantId,
|
|
194
192
|
trimmedContent,
|
|
195
193
|
sourceMetadata,
|
|
196
194
|
actorDisplayName,
|
|
@@ -426,7 +424,6 @@ export async function enforceIngressAcl(
|
|
|
426
424
|
// Still notify the guardian about the access attempt
|
|
427
425
|
try {
|
|
428
426
|
await notifyGuardianOfAccessRequest({
|
|
429
|
-
canonicalAssistantId,
|
|
430
427
|
sourceChannel,
|
|
431
428
|
conversationExternalId,
|
|
432
429
|
actorExternalId: canonicalSenderId ?? rawSenderId,
|
|
@@ -509,7 +506,6 @@ export async function enforceIngressAcl(
|
|
|
509
506
|
if (emailVerifyResult.initiated) {
|
|
510
507
|
try {
|
|
511
508
|
await notifyGuardianOfAccessRequest({
|
|
512
|
-
canonicalAssistantId,
|
|
513
509
|
sourceChannel,
|
|
514
510
|
conversationExternalId,
|
|
515
511
|
actorExternalId: canonicalSenderId ?? rawSenderId,
|
|
@@ -554,14 +550,12 @@ export async function enforceIngressAcl(
|
|
|
554
550
|
let handshakeInProgress = false;
|
|
555
551
|
if (isCallbackInteraction) {
|
|
556
552
|
handshakeInProgress = await isApprovalHandshakeInProgress({
|
|
557
|
-
canonicalAssistantId,
|
|
558
553
|
sourceChannel,
|
|
559
554
|
actorExternalId: (canonicalSenderId ?? rawSenderId)!,
|
|
560
555
|
});
|
|
561
556
|
} else {
|
|
562
557
|
try {
|
|
563
558
|
const accessResult = await notifyGuardianOfAccessRequest({
|
|
564
|
-
canonicalAssistantId,
|
|
565
559
|
sourceChannel,
|
|
566
560
|
conversationExternalId,
|
|
567
561
|
actorExternalId: canonicalSenderId ?? rawSenderId,
|
|
@@ -730,7 +724,6 @@ export async function enforceIngressAcl(
|
|
|
730
724
|
if (slackVerifyResult.initiated) {
|
|
731
725
|
try {
|
|
732
726
|
await notifyGuardianOfAccessRequest({
|
|
733
|
-
canonicalAssistantId,
|
|
734
727
|
sourceChannel,
|
|
735
728
|
conversationExternalId,
|
|
736
729
|
actorExternalId: canonicalSenderId ?? rawSenderId,
|
|
@@ -803,14 +796,12 @@ export async function enforceIngressAcl(
|
|
|
803
796
|
if (!terminallyKeptOut) {
|
|
804
797
|
if (isCallbackInteraction) {
|
|
805
798
|
handshakeInProgress = await isApprovalHandshakeInProgress({
|
|
806
|
-
canonicalAssistantId,
|
|
807
799
|
sourceChannel,
|
|
808
800
|
actorExternalId: (canonicalSenderId ?? rawSenderId)!,
|
|
809
801
|
});
|
|
810
802
|
} else {
|
|
811
803
|
try {
|
|
812
804
|
const accessResult = await notifyGuardianOfAccessRequest({
|
|
813
|
-
canonicalAssistantId,
|
|
814
805
|
sourceChannel,
|
|
815
806
|
conversationExternalId,
|
|
816
807
|
actorExternalId: canonicalSenderId ?? rawSenderId,
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
ADMISSION_FLOOR,
|
|
28
28
|
type AdmissionPolicy,
|
|
29
29
|
isAdmissionPolicyExemptChannel,
|
|
30
|
+
TRUST_CLASS_RANK,
|
|
30
31
|
} from "@vellumai/gateway-client";
|
|
31
32
|
|
|
32
33
|
import type { ChannelId } from "../../../channels/types.js";
|
|
@@ -73,23 +74,6 @@ export type AdmissionPolicyResult =
|
|
|
73
74
|
// Public API
|
|
74
75
|
// ---------------------------------------------------------------------------
|
|
75
76
|
|
|
76
|
-
/**
|
|
77
|
-
* Trust-class ordinal compared against {@link ADMISSION_FLOOR} to make the
|
|
78
|
-
* admission decision (`rank >= floor`). Higher rank = more trusted.
|
|
79
|
-
* Blocked/revoked never reach this comparison — they short-circuit to deny on
|
|
80
|
-
* member status above — so they carry no rank here.
|
|
81
|
-
*
|
|
82
|
-
* The two halves of the floor check: this table is keyed by `TrustClass`,
|
|
83
|
-
* `ADMISSION_FLOOR` (from `@vellumai/gateway-client`) by `AdmissionPolicy`.
|
|
84
|
-
* They are only ever read together, here, so they live next to their use.
|
|
85
|
-
*/
|
|
86
|
-
const TRUST_CLASS_RANK: Record<TrustClass, number> = {
|
|
87
|
-
guardian: 4,
|
|
88
|
-
trusted_contact: 3,
|
|
89
|
-
unverified_contact: 2,
|
|
90
|
-
unknown: 1,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
77
|
/**
|
|
94
78
|
* Policies under which completing verification could lift the sender past
|
|
95
79
|
* the floor. Used to decide whether to fire the upgrade UX on deny.
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
import type { ChannelId } from "../../../channels/types.js";
|
|
25
25
|
import { sendTelegramReply } from "../../../messaging/providers/telegram-bot/send.js";
|
|
26
26
|
import { getLogger } from "../../../util/logger.js";
|
|
27
|
+
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../../assistant-scope.js";
|
|
27
28
|
import { RESEND_COOLDOWN_MS } from "../../verification-outbound-actions.js";
|
|
28
29
|
import {
|
|
29
30
|
composeVerificationText,
|
|
@@ -40,7 +41,6 @@ export interface BootstrapInterceptParams {
|
|
|
40
41
|
isDuplicate: boolean;
|
|
41
42
|
commandIntent: Record<string, unknown> | undefined;
|
|
42
43
|
rawSenderId: string | undefined;
|
|
43
|
-
canonicalAssistantId: string;
|
|
44
44
|
sourceChannel: ChannelId;
|
|
45
45
|
conversationExternalId: string;
|
|
46
46
|
eventId: string;
|
|
@@ -96,7 +96,6 @@ export async function handleBootstrapIntercept(
|
|
|
96
96
|
isDuplicate,
|
|
97
97
|
commandIntent,
|
|
98
98
|
rawSenderId,
|
|
99
|
-
canonicalAssistantId,
|
|
100
99
|
sourceChannel,
|
|
101
100
|
conversationExternalId,
|
|
102
101
|
eventId,
|
|
@@ -208,7 +207,7 @@ export async function handleBootstrapIntercept(
|
|
|
208
207
|
deliverBootstrapVerificationTelegram(
|
|
209
208
|
conversationExternalId,
|
|
210
209
|
telegramBody,
|
|
211
|
-
|
|
210
|
+
DAEMON_INTERNAL_ASSISTANT_ID,
|
|
212
211
|
);
|
|
213
212
|
|
|
214
213
|
// Update delivery tracking (best-effort — the code is already on its way)
|
|
@@ -45,7 +45,6 @@ export interface EditInterceptParams {
|
|
|
45
45
|
externalMessageId: string;
|
|
46
46
|
sourceMessageId: string;
|
|
47
47
|
sourceThreadId?: string;
|
|
48
|
-
canonicalAssistantId: string;
|
|
49
48
|
assistantId: string;
|
|
50
49
|
content: string | undefined;
|
|
51
50
|
/** Channel ID for channel-level interaction tracking. */
|
|
@@ -68,7 +67,6 @@ export async function handleEditIntercept(
|
|
|
68
67
|
externalMessageId,
|
|
69
68
|
sourceMessageId,
|
|
70
69
|
sourceThreadId,
|
|
71
|
-
canonicalAssistantId,
|
|
72
70
|
assistantId,
|
|
73
71
|
content,
|
|
74
72
|
} = params;
|
|
@@ -78,7 +76,7 @@ export async function handleEditIntercept(
|
|
|
78
76
|
sourceChannel,
|
|
79
77
|
conversationExternalId,
|
|
80
78
|
externalMessageId,
|
|
81
|
-
{ sourceMessageId, sourceThreadId
|
|
79
|
+
{ sourceMessageId, sourceThreadId },
|
|
82
80
|
);
|
|
83
81
|
|
|
84
82
|
if (editResult.duplicate) {
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "../../../channels/gateway-guardian-requests.js";
|
|
16
16
|
import type { ChannelId } from "../../../channels/types.js";
|
|
17
17
|
import { getLogger } from "../../../util/logger.js";
|
|
18
|
+
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../../assistant-scope.js";
|
|
18
19
|
import { deliverChannelReply } from "../../gateway-client.js";
|
|
19
20
|
import {
|
|
20
21
|
type GuardianPendingScope,
|
|
@@ -41,7 +42,6 @@ export interface GuardianReplyInterceptParams {
|
|
|
41
42
|
reactedMessageTs?: string;
|
|
42
43
|
rawSenderId: string | undefined;
|
|
43
44
|
canonicalSenderId: string | null;
|
|
44
|
-
canonicalAssistantId: string;
|
|
45
45
|
sourceChannel: ChannelId;
|
|
46
46
|
conversationExternalId: string;
|
|
47
47
|
conversationId: string;
|
|
@@ -77,7 +77,6 @@ export async function handleGuardianReplyIntercept(
|
|
|
77
77
|
reactedMessageTs,
|
|
78
78
|
rawSenderId,
|
|
79
79
|
canonicalSenderId,
|
|
80
|
-
canonicalAssistantId,
|
|
81
80
|
sourceChannel,
|
|
82
81
|
conversationExternalId,
|
|
83
82
|
conversationId,
|
|
@@ -178,7 +177,7 @@ export async function handleGuardianReplyIntercept(
|
|
|
178
177
|
channelDeliveryContext: {
|
|
179
178
|
replyCallbackUrl,
|
|
180
179
|
guardianChatId: conversationExternalId,
|
|
181
|
-
assistantId:
|
|
180
|
+
assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
|
|
182
181
|
},
|
|
183
182
|
});
|
|
184
183
|
|
|
@@ -188,7 +187,7 @@ export async function handleGuardianReplyIntercept(
|
|
|
188
187
|
const routerReplyPayload: Parameters<typeof deliverChannelReply>[1] = {
|
|
189
188
|
chatId: conversationExternalId,
|
|
190
189
|
text: routerResult.replyText,
|
|
191
|
-
assistantId:
|
|
190
|
+
assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
|
|
192
191
|
};
|
|
193
192
|
// On Slack, send guardian management replies (disambiguation, pending
|
|
194
193
|
// request lists, etc.) as ephemeral so only the guardian sees them.
|
|
@@ -172,7 +172,6 @@ function buildParams(overrides: {
|
|
|
172
172
|
sourceInterface: "slack" as const,
|
|
173
173
|
conversationExternalId: SLACK_CHANNEL_ID,
|
|
174
174
|
externalMessageId: `${SLACK_CHANNEL_ID}:1700000000.1:${msgCounter}`,
|
|
175
|
-
canonicalAssistantId: "assistant-1",
|
|
176
175
|
rawSenderId: overrides.rawSenderId,
|
|
177
176
|
canonicalSenderId: overrides.rawSenderId,
|
|
178
177
|
actorDisplayName: "Reactor",
|
|
@@ -35,7 +35,6 @@ import {
|
|
|
35
35
|
import { markProcessed } from "../../../persistence/delivery-status.js";
|
|
36
36
|
import { upsertBinding } from "../../../persistence/external-conversation-store.js";
|
|
37
37
|
import { getLogger } from "../../../util/logger.js";
|
|
38
|
-
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../../assistant-scope.js";
|
|
39
38
|
import type { ApprovalConversationGenerator } from "../../http-types.js";
|
|
40
39
|
import {
|
|
41
40
|
actorTrustContextFromVerdict,
|
|
@@ -100,7 +99,6 @@ export interface ReactionInterceptParams {
|
|
|
100
99
|
sourceInterface: InterfaceId | undefined;
|
|
101
100
|
conversationExternalId: string;
|
|
102
101
|
externalMessageId: string;
|
|
103
|
-
canonicalAssistantId: string;
|
|
104
102
|
rawSenderId: string | undefined;
|
|
105
103
|
canonicalSenderId: string | null;
|
|
106
104
|
actorDisplayName: string | undefined;
|
|
@@ -126,7 +124,6 @@ export async function handleSlackReactionIntercept(
|
|
|
126
124
|
sourceInterface,
|
|
127
125
|
conversationExternalId,
|
|
128
126
|
externalMessageId,
|
|
129
|
-
canonicalAssistantId,
|
|
130
127
|
rawSenderId,
|
|
131
128
|
canonicalSenderId,
|
|
132
129
|
actorDisplayName,
|
|
@@ -182,7 +179,6 @@ export async function handleSlackReactionIntercept(
|
|
|
182
179
|
externalMessageId,
|
|
183
180
|
{
|
|
184
181
|
sourceMessageId: reactedMessageTs,
|
|
185
|
-
assistantId: canonicalAssistantId,
|
|
186
182
|
sourceThreadId: threadTs,
|
|
187
183
|
},
|
|
188
184
|
);
|
|
@@ -216,21 +212,17 @@ export async function handleSlackReactionIntercept(
|
|
|
216
212
|
};
|
|
217
213
|
}
|
|
218
214
|
|
|
219
|
-
// Maintain the conversation binding, matching the message pipeline.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
displayName: actorDisplayName ?? null,
|
|
231
|
-
username: actorUsername ?? null,
|
|
232
|
-
});
|
|
233
|
-
}
|
|
215
|
+
// Maintain the conversation binding, matching the message pipeline.
|
|
216
|
+
upsertBinding({
|
|
217
|
+
conversationId: result.conversationId,
|
|
218
|
+
sourceChannel,
|
|
219
|
+
externalChatId: conversationExternalId,
|
|
220
|
+
externalChatName: slackChannelName,
|
|
221
|
+
externalThreadId: threadTs ?? null,
|
|
222
|
+
externalUserId: canonicalSenderId ?? rawSenderId ?? null,
|
|
223
|
+
displayName: actorDisplayName ?? null,
|
|
224
|
+
username: actorUsername ?? null,
|
|
225
|
+
});
|
|
234
226
|
|
|
235
227
|
// Guardian approval-by-reaction → guardian decision pipeline, exactly like
|
|
236
228
|
// buttons and text replies. Only `reaction:` (added) expresses intent;
|
|
@@ -247,7 +239,6 @@ export async function handleSlackReactionIntercept(
|
|
|
247
239
|
reactedMessageTs,
|
|
248
240
|
rawSenderId,
|
|
249
241
|
canonicalSenderId,
|
|
250
|
-
canonicalAssistantId,
|
|
251
242
|
sourceChannel,
|
|
252
243
|
conversationExternalId,
|
|
253
244
|
conversationId: result.conversationId,
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from "../../../persistence/delivery-crud.js";
|
|
15
15
|
import { checkIngressForSecrets } from "../../../security/secret-ingress.js";
|
|
16
16
|
import { getLogger } from "../../../util/logger.js";
|
|
17
|
+
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../../assistant-scope.js";
|
|
17
18
|
|
|
18
19
|
const log = getLogger("runtime-http");
|
|
19
20
|
|
|
@@ -36,7 +37,6 @@ export interface SecretIngressCheckParams {
|
|
|
36
37
|
actorUsername: string | undefined;
|
|
37
38
|
trustCtx: TrustContext;
|
|
38
39
|
replyCallbackUrl: string | undefined;
|
|
39
|
-
canonicalAssistantId: string;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export interface SecretIngressCheckResult {
|
|
@@ -69,7 +69,6 @@ export function runSecretIngressCheck(
|
|
|
69
69
|
actorUsername,
|
|
70
70
|
trustCtx,
|
|
71
71
|
replyCallbackUrl,
|
|
72
|
-
canonicalAssistantId,
|
|
73
72
|
} = params;
|
|
74
73
|
|
|
75
74
|
// Persist the raw payload so dead-lettered events can always be replayed.
|
|
@@ -85,7 +84,7 @@ export function runSecretIngressCheck(
|
|
|
85
84
|
senderUsername: actorUsername,
|
|
86
85
|
trustCtx,
|
|
87
86
|
replyCallbackUrl,
|
|
88
|
-
assistantId:
|
|
87
|
+
assistantId: DAEMON_INTERNAL_ASSISTANT_ID,
|
|
89
88
|
});
|
|
90
89
|
|
|
91
90
|
// ── Secret ingress scan ──
|
|
@@ -29,11 +29,14 @@ import {
|
|
|
29
29
|
loadRawConfig,
|
|
30
30
|
} from "../../config/loader.js";
|
|
31
31
|
import {
|
|
32
|
-
LLMProvider,
|
|
33
32
|
ProfileEntry,
|
|
34
33
|
routingIdentityModelIssue,
|
|
35
34
|
} from "../../config/schemas/llm.js";
|
|
36
35
|
import { getDb } from "../../persistence/db-connection.js";
|
|
36
|
+
import {
|
|
37
|
+
resolveEntryProviderKind,
|
|
38
|
+
writableProfileProviderIssue,
|
|
39
|
+
} from "../../providers/connection-resolution.js";
|
|
37
40
|
import { ROUTING_IDENTITY_PROVIDERS } from "../../providers/inference/auth.js";
|
|
38
41
|
import type { ConnectionAvailability } from "../../providers/inference/connection-availability.js";
|
|
39
42
|
import {
|
|
@@ -150,10 +153,9 @@ const updateRequestSchema = z.object({
|
|
|
150
153
|
// ---------------------------------------------------------------------------
|
|
151
154
|
|
|
152
155
|
function assertValidProvider(provider: string): void {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
);
|
|
156
|
+
const issue = writableProfileProviderIssue(provider);
|
|
157
|
+
if (issue) {
|
|
158
|
+
throw new BadRequestError(issue);
|
|
157
159
|
}
|
|
158
160
|
}
|
|
159
161
|
|
|
@@ -182,31 +184,38 @@ function validateModel(
|
|
|
182
184
|
}
|
|
183
185
|
return [];
|
|
184
186
|
}
|
|
185
|
-
|
|
187
|
+
// An entry-name provider validates against its row's dispatchable kind,
|
|
188
|
+
// the same translation dispatch uses; the entry itself also serves as the
|
|
189
|
+
// model-list connection for custom endpoints below.
|
|
190
|
+
const entryKind = resolveEntryProviderKind(provider, model);
|
|
191
|
+
const catalogProvider = entryKind ?? provider;
|
|
192
|
+
if (isModelInCatalog(catalogProvider, model)) {
|
|
186
193
|
return [];
|
|
187
194
|
}
|
|
188
195
|
// The named connection's advertised model list is authoritative for models
|
|
189
196
|
// the code-owned catalog doesn't know — a custom (openai-compatible)
|
|
190
197
|
// endpoint declares its own models at connection-create time.
|
|
191
|
-
|
|
192
|
-
|
|
198
|
+
const modelListConnection =
|
|
199
|
+
connectionName ?? (entryKind !== null ? provider : undefined);
|
|
200
|
+
if (modelListConnection) {
|
|
201
|
+
const connection = getConnection(getDb(), modelListConnection);
|
|
193
202
|
if (connection?.models?.some((m) => m.id === model)) {
|
|
194
203
|
return [];
|
|
195
204
|
}
|
|
196
205
|
}
|
|
197
206
|
if (!allowUnlisted) {
|
|
198
207
|
const remedy =
|
|
199
|
-
|
|
208
|
+
catalogProvider === "openai-compatible"
|
|
200
209
|
? `Pass allowUnlisted to create it anyway, or declare the model on the connection ` +
|
|
201
210
|
`("assistant inference providers update <name> --model ${model}").`
|
|
202
211
|
: `Pass allowUnlisted to create it anyway, or run ` +
|
|
203
212
|
`"assistant inference models list --provider ${provider}" to see valid ids.`;
|
|
204
213
|
throw new BadRequestError(
|
|
205
|
-
`Model "${model}" is not in the catalog for provider "${
|
|
214
|
+
`Model "${model}" is not in the catalog for provider "${catalogProvider}". ${remedy}`,
|
|
206
215
|
);
|
|
207
216
|
}
|
|
208
217
|
return [
|
|
209
|
-
`Model "${model}" is not in the catalog for provider "${
|
|
218
|
+
`Model "${model}" is not in the catalog for provider "${catalogProvider}"; created anyway (allowUnlisted).`,
|
|
210
219
|
];
|
|
211
220
|
}
|
|
212
221
|
|