@vellumai/assistant 0.11.1 → 0.11.2-staging.2
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 +1 -3
- package/README.md +1 -1
- package/eslint.config.mjs +28 -8
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/stripe-currency.test.ts +37 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/stripe-currency.ts +55 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/stripe-currency.test.ts +37 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/stripe-currency.ts +55 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/stripe-currency.test.ts +37 -0
- package/node_modules/@vellumai/service-contracts/src/stripe-currency.ts +55 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +48 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +25 -6
- package/openapi.yaml +292 -5
- package/package.json +1 -1
- package/src/__tests__/agent-loop-resume-interrupted.test.ts +223 -0
- package/src/__tests__/byok-default-profile-ensure.test.ts +43 -0
- package/src/__tests__/cli-logger-boundary-guard.test.ts +87 -0
- package/src/__tests__/compaction-events.test.ts +139 -2
- package/src/__tests__/config-loader-backfill.test.ts +35 -3
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +30 -0
- package/src/__tests__/conversation-agent-loop.test.ts +180 -7
- package/src/__tests__/conversation-error.test.ts +211 -4
- package/src/__tests__/conversation-options-turn-scoped-transport.test.ts +64 -0
- package/src/__tests__/conversation-queue.test.ts +126 -0
- package/src/__tests__/conversation-retry-route.test.ts +46 -7
- package/src/__tests__/conversation-slash.test.ts +4 -2
- package/src/__tests__/conversation-summarize-route.test.ts +7 -1
- package/src/__tests__/conversation-summarize-up-to.test.ts +71 -5
- package/src/__tests__/document-create-dedupe.test.ts +2 -1
- package/src/__tests__/document-find-replace.test.ts +2 -1
- package/src/__tests__/document-tool-security.test.ts +2 -1
- package/src/__tests__/document-update-default-surface.test.ts +2 -1
- package/src/__tests__/document-workspace-file.test.ts +467 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +290 -49
- package/src/__tests__/guardian-card-withdrawal.test.ts +91 -3
- package/src/__tests__/http-user-message-parity.test.ts +66 -0
- package/src/__tests__/list-messages-attachments.test.ts +87 -0
- package/src/__tests__/list-messages-provider-error.test.ts +143 -0
- package/src/__tests__/list-messages-system-card.test.ts +100 -0
- package/src/__tests__/llm-resolver.test.ts +19 -9
- package/src/__tests__/managed-profile-guard.test.ts +23 -0
- package/src/__tests__/notification-platform-adapter.test.ts +130 -2
- package/src/__tests__/notification-telegram-adapter.test.ts +6 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +45 -0
- package/src/__tests__/plugin-api-model-profiles.test.ts +10 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +3 -0
- package/src/__tests__/provider-error-scenarios.test.ts +140 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +95 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +66 -3
- package/src/__tests__/scripted-turn-metadata-persistence.test.ts +209 -0
- package/src/__tests__/skills.test.ts +27 -0
- package/src/__tests__/slack-channels-routes.test.ts +0 -2
- package/src/__tests__/slack-share-routes.test.ts +0 -3
- package/src/__tests__/slack-users-routes.test.ts +0 -2
- package/src/__tests__/subagent-tools.test.ts +11 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +58 -0
- package/src/__tests__/tool-result-spool.test.ts +5 -4
- package/src/__tests__/turn-boundary-resolution.test.ts +53 -0
- package/src/__tests__/turn-events-store.test.ts +26 -0
- package/src/__tests__/ui-visual-surface.test.ts +695 -0
- package/src/__tests__/unified-turn-context-visible-app.test.ts +99 -0
- package/src/__tests__/visible-app-context.test.ts +189 -0
- package/src/__tests__/workspace-git-service.test.ts +173 -33
- package/src/__tests__/workspace-migration-137-repair-retired-fireworks-minimax-model-id.test.ts +157 -0
- package/src/__tests__/workspace-migration-138-backfill-home-feed-titles.test.ts +373 -0
- package/src/__tests__/workspace-migration-139-clear-renamed-cost-profile-label.test.ts +137 -0
- package/src/agent/loop.ts +36 -7
- package/src/api/events/context-window-usage.ts +31 -0
- package/src/api/events/notification-intent.ts +8 -0
- package/src/api/events/ui-surface-pending.ts +35 -0
- package/src/api/index.ts +14 -0
- package/src/api/responses/conversation-message.ts +25 -4
- package/src/api/surfaces.ts +90 -1
- package/src/approvals/guardian-card-withdrawal.ts +66 -31
- package/src/approvals/guardian-decision-primitive.ts +4 -0
- package/src/calls/__tests__/call-setup-router.test.ts +156 -26
- package/src/calls/__tests__/voice-session-bridge.test.ts +201 -12
- package/src/calls/call-setup-router.ts +80 -36
- package/src/calls/voice-session-bridge.ts +173 -26
- package/src/cli/commands/inference.help.ts +3 -3
- package/src/cli/commands/notifications.help.ts +3 -2
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +42 -128
- package/src/cli/commands/platform/__tests__/credits.test.ts +9 -78
- package/src/cli/commands/platform/__tests__/helpers.ts +90 -0
- package/src/cli/commands/platform/__tests__/invoices.test.ts +238 -0
- package/src/cli/commands/platform/__tests__/plans.test.ts +9 -88
- package/src/cli/commands/platform/__tests__/status.test.ts +12 -87
- package/src/cli/commands/platform/__tests__/subscription.test.ts +9 -86
- package/src/cli/commands/platform/index.help.ts +92 -0
- package/src/cli/commands/platform/index.ts +7 -0
- package/src/cli/commands/platform/invoices.ts +132 -0
- package/src/cli/commands/usage.help.ts +1 -1
- package/src/cli/lib/list-installed-plugins.ts +2 -1
- package/src/config/__tests__/default-profile-catalog.test.ts +7 -10
- package/src/config/__tests__/deployment-context-defaults.test.ts +27 -5
- package/src/config/assistant-feature-flags.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +3 -2
- package/src/config/bundled-skills/subagent/SKILL.md +3 -1
- package/src/config/bundled-skills/subagent/TOOLS.json +3 -3
- package/src/config/bundled-skills/visualize/SKILL.md +163 -0
- package/src/config/call-site-defaults.ts +3 -2
- package/src/config/default-profile-catalog.ts +75 -70
- package/src/config/default-profile-names.ts +13 -28
- package/src/config/env-registry.ts +1 -0
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/llm-resolver.ts +21 -5
- package/src/config/loader.ts +18 -11
- package/src/config/schemas/llm.ts +1 -9
- package/src/config/schemas/memory-retrospective.ts +9 -0
- package/src/config/schemas/monitoring.ts +28 -2
- package/src/config/schemas/workspace-git.ts +15 -0
- package/src/config/seed-inference-profiles.ts +19 -5
- package/src/context/post-turn-tool-result-truncation.ts +2 -2
- package/src/conversations/__tests__/message-consolidation.test.ts +54 -0
- package/src/conversations/message-consolidation.ts +17 -15
- package/src/daemon/__tests__/turn-tail-assistant-reply-notify.test.ts +182 -0
- package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +181 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +90 -7
- package/src/daemon/conversation-agent-loop.ts +107 -22
- package/src/daemon/conversation-error.ts +169 -48
- package/src/daemon/conversation-messaging.ts +87 -4
- package/src/daemon/conversation-process.ts +57 -45
- package/src/daemon/conversation-runtime-assembly.ts +57 -0
- package/src/daemon/conversation-store.ts +36 -1
- package/src/daemon/conversation-surfaces.ts +68 -6
- package/src/daemon/conversation-turn-finalize.ts +76 -18
- package/src/daemon/conversation.ts +122 -27
- package/src/daemon/lifecycle.ts +9 -0
- package/src/daemon/message-types/conversations.ts +8 -0
- package/src/daemon/message-types/surfaces.ts +3 -0
- package/src/documents/document-store.ts +247 -10
- package/src/home/__tests__/feed-types.test.ts +43 -8
- package/src/home/__tests__/feed-writer.test.ts +59 -0
- package/src/home/feed-types.ts +34 -7
- package/src/home/feed-writer.ts +15 -6
- package/src/live-voice/__tests__/activity-label.test.ts +95 -0
- package/src/live-voice/__tests__/live-activity-reporter.test.ts +86 -5
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +310 -25
- package/src/live-voice/__tests__/live-voice-events.test.ts +4 -4
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +8 -4
- package/src/live-voice/__tests__/live-voice-vad.test.ts +9 -1
- package/src/live-voice/activity-label.ts +169 -0
- package/src/live-voice/live-activity-reporter.ts +35 -6
- package/src/live-voice/live-voice-session.ts +282 -41
- package/src/live-voice/protocol.ts +35 -0
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +84 -2
- package/src/messaging/providers/slack/adapter.ts +86 -19
- package/src/messaging/providers/slack/api.test.ts +85 -1
- package/src/messaging/providers/slack/api.ts +121 -288
- package/src/messaging/providers/slack/client.ts +20 -251
- package/src/messaging/providers/slack/send.test.ts +4 -9
- package/src/messaging/providers/slack/send.ts +1 -1
- package/src/messaging/providers/slack/types.ts +5 -0
- package/src/messaging/providers/slack/web-api-transport.test.ts +181 -0
- package/src/messaging/providers/slack/web-api-transport.ts +367 -0
- package/src/messaging/providers/slack/withdraw.ts +6 -14
- package/src/messaging/providers/telegram-bot/send.test.ts +31 -1
- package/src/messaging/providers/telegram-bot/send.ts +23 -2
- package/src/messaging/providers/telegram-bot/withdraw.test.ts +152 -0
- package/src/messaging/providers/telegram-bot/withdraw.ts +166 -0
- package/src/monitoring/__tests__/db-integrity-sample.test.ts +18 -4
- package/src/monitoring/__tests__/file-descriptors.test.ts +144 -0
- package/src/monitoring/file-descriptors.ts +262 -0
- package/src/monitoring/process-memory.ts +4 -11
- package/src/monitoring/resource-sampler.ts +5 -0
- package/src/monitoring/worker.ts +12 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +740 -0
- package/src/notifications/__tests__/broadcaster.test.ts +347 -7
- package/src/notifications/__tests__/copy-composer.test.ts +53 -3
- package/src/notifications/__tests__/decision-engine.test.ts +349 -29
- package/src/notifications/__tests__/deterministic-checks.test.ts +21 -0
- package/src/notifications/__tests__/edit-notification.test.ts +330 -0
- package/src/notifications/__tests__/guardian-delivery-recorder.test.ts +71 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +170 -12
- package/src/notifications/adapters/macos.ts +3 -0
- package/src/notifications/adapters/platform.ts +90 -14
- package/src/notifications/adapters/telegram.ts +6 -4
- package/src/notifications/assistant-reply-producer.ts +219 -0
- package/src/notifications/broadcaster.ts +523 -317
- package/src/notifications/copy-composer.ts +27 -6
- package/src/notifications/decision-engine.ts +154 -77
- package/src/notifications/deterministic-checks.ts +6 -7
- package/src/notifications/edit-notification.ts +8 -4
- package/src/notifications/emit-signal.ts +49 -16
- package/src/notifications/guardian-delivery-recorder.ts +8 -2
- package/src/notifications/home-feed-side-effect.ts +43 -6
- package/src/notifications/notification-utils.ts +39 -4
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +17 -0
- package/src/persistence/bookmark-crud.ts +18 -9
- package/src/persistence/conversation-attention-store.ts +26 -0
- package/src/persistence/conversation-crud.ts +79 -32
- package/src/persistence/conversation-queries.ts +30 -15
- package/src/persistence/conversation-title-service.ts +5 -170
- package/src/persistence/conversation-types.ts +192 -1
- package/src/persistence/db-init.ts +14 -1
- package/src/persistence/db-maintenance.ts +5 -4
- package/src/persistence/embeddings/__tests__/plugin-index-qdrant-init.test.ts +219 -0
- package/src/persistence/embeddings/__tests__/plugin-index.test.ts +22 -0
- package/src/persistence/embeddings/__tests__/worker-script-version.test.ts +76 -0
- package/src/persistence/embeddings/embedding-local.ts +2 -1
- package/src/persistence/embeddings/embedding-runtime-manager.ts +29 -5
- package/src/persistence/embeddings/plugin-index.ts +84 -12
- package/src/persistence/migrations/360-add-document-workspace-path.test.ts +110 -0
- package/src/persistence/migrations/360-add-document-workspace-path.ts +39 -0
- package/src/persistence/planner-statistics.ts +14 -0
- package/src/persistence/schema/documents.ts +26 -11
- package/src/persistence/steps.ts +2 -0
- package/src/platform/client.test.ts +172 -2
- package/src/platform/client.ts +178 -55
- package/src/plugin-api/conversation-turn.ts +13 -0
- package/src/plugin-api/model-profiles.test.ts +6 -2
- package/src/plugins/defaults/memory/__tests__/bookmark-crud.test.ts +34 -0
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +22 -0
- package/src/plugins/defaults/memory/__tests__/jobs-store-enqueue-gate.test.ts +11 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +199 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +98 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +105 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +24 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +524 -0
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +9 -4
- package/src/plugins/defaults/memory/host-utils.ts +5 -0
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +105 -1
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +64 -5
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +36 -1
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +12 -3
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +1 -0
- package/src/plugins/defaults/memory/substrate/__tests__/skill-store.test.ts +195 -1
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +1 -1
- package/src/plugins/defaults/memory/substrate/skill-store.ts +167 -29
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +131 -0
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +1 -0
- package/src/plugins/defaults/memory/v2/activation-log-store.ts +4 -0
- package/src/plugins/defaults/memory/v2/injection.ts +48 -3
- package/src/plugins/defaults/memory/v2/rerank-local.ts +6 -2
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +1 -1
- package/src/plugins/defaults/platform-hosted/routes/reengage.ts +1 -1
- package/src/plugins/defaults/turn-context/injectors.ts +1 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +26 -0
- package/src/plugins/types.ts +17 -0
- package/src/prompts/templates/system-sections.ts +2 -2
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +43 -2
- package/src/providers/__tests__/vellum-mismatch-routing.test.ts +8 -0
- package/src/providers/call-site-routing.ts +77 -14
- package/src/providers/connection-resolution.ts +42 -2
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +127 -1
- package/src/providers/inference/adapter-factory.ts +70 -12
- package/src/providers/model-catalog.ts +0 -11
- package/src/providers/model-intents.ts +11 -0
- package/src/providers/registry.ts +8 -0
- package/src/providers/retry.ts +85 -17
- package/src/providers/types.ts +8 -1
- package/src/runtime/__tests__/agent-wake.test.ts +181 -0
- package/src/runtime/agent-wake.ts +132 -9
- package/src/runtime/channel-approval-types.ts +25 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +2 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +11 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +121 -9
- package/src/runtime/routes/__tests__/platform-invoice-routes.test.ts +392 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +7 -0
- package/src/runtime/routes/__tests__/workspace-commit-routes.test.ts +63 -0
- package/src/runtime/routes/consolidation-routes.ts +1 -1
- package/src/runtime/routes/conversation-management-routes.ts +18 -6
- package/src/runtime/routes/conversation-query-routes.ts +14 -23
- package/src/runtime/routes/conversation-routes.ts +113 -8
- package/src/runtime/routes/credential-routes.ts +1 -5
- package/src/runtime/routes/documents-routes.ts +207 -12
- package/src/runtime/routes/identity-routes.ts +3 -93
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +31 -1
- package/src/runtime/routes/inbound-stages/admission-policy.ts +18 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +52 -3
- package/src/runtime/routes/notification-routes.ts +4 -1
- package/src/runtime/routes/platform-routes.ts +238 -3
- package/src/runtime/routes/playground/guard.ts +1 -2
- package/src/runtime/routes/slack-channel-routes.ts +2 -4
- package/src/runtime/routes/workspace-commit-routes.ts +49 -2
- package/src/runtime/routes/workspace-routes.ts +11 -12
- package/src/runtime/routes/workspace-utils.ts +49 -2
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/subagent/__tests__/consult-context-gating.test.ts +98 -0
- package/src/subagent/__tests__/consult-context-skills.test.ts +82 -0
- package/src/subagent/__tests__/consult-context.test.ts +84 -0
- package/src/subagent/__tests__/consult-prompt.test.ts +36 -0
- package/src/subagent/consult-context.ts +410 -0
- package/src/subagent/consult-prompt.ts +38 -5
- package/src/subagent/manager.ts +9 -4
- package/src/subagent/types.ts +8 -0
- package/src/telemetry/telemetry-event-sources.ts +7 -0
- package/src/telemetry/telemetry-wire-source.json +1 -1
- package/src/telemetry/telemetry-wire.generated.ts +1 -0
- package/src/telemetry/turn-events-store.ts +30 -1
- package/src/telemetry/types.ts +24 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/tools/browser/pinned-tabs.ts +3 -1
- package/src/tools/subagent/spawn.ts +23 -1
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/ui-surface/definitions.ts +39 -1
- package/src/tools/ui-surface/surface-shape-docs.ts +38 -4
- package/src/tools/ui-surface/visual-validation.ts +787 -0
- package/src/tools/workflows/run-workflow.test.ts +1 -0
- package/src/util/__tests__/short-title.test.ts +229 -0
- package/src/util/__tests__/worker-compute.test.ts +65 -0
- package/src/util/cgroup-cpu.ts +93 -0
- package/src/util/errors.ts +27 -0
- package/src/util/process-tree.ts +19 -0
- package/src/util/short-title.ts +189 -0
- package/src/util/worker-compute.ts +83 -0
- package/src/workspace/byok-default-profile-ensure.ts +25 -15
- package/src/workspace/git-service.ts +79 -30
- package/src/workspace/migrations/137-repair-retired-fireworks-minimax-model-id.ts +131 -0
- package/src/workspace/migrations/138-backfill-home-feed-titles.ts +179 -0
- package/src/workspace/migrations/139-clear-renamed-cost-profile-label.ts +92 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/plugins/defaults/memory/substrate/constants.ts +0 -8
package/Dockerfile
CHANGED
|
@@ -22,9 +22,7 @@ ENV PATH="/root/.bun/bin:${PATH}"
|
|
|
22
22
|
# Note that we don't need source code to resolve cross-workspace dependencies.
|
|
23
23
|
COPY package.json bun.lock ./
|
|
24
24
|
COPY patches ./patches
|
|
25
|
-
COPY clients
|
|
26
|
-
COPY clients/macos/package.json ./clients/macos/
|
|
27
|
-
COPY clients/web/package.json ./clients/web/
|
|
25
|
+
COPY --parents clients/*/package.json ./
|
|
28
26
|
COPY cli/package.json ./cli/
|
|
29
27
|
COPY gateway/package.json ./gateway/
|
|
30
28
|
COPY credential-executor/package.json ./credential-executor/
|
package/README.md
CHANGED
package/eslint.config.mjs
CHANGED
|
@@ -49,14 +49,29 @@ const eslintConfig = defineConfig([
|
|
|
49
49
|
"@typescript-eslint/no-explicit-any": "off",
|
|
50
50
|
},
|
|
51
51
|
},
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
52
|
+
// Two unrelated import bans share one `no-restricted-imports` entry on
|
|
53
|
+
// purpose: flat config replaces rule options rather than merging them, so a
|
|
54
|
+
// second block setting the same rule over overlapping files would silently
|
|
55
|
+
// drop the first one's patterns.
|
|
56
|
+
//
|
|
57
|
+
// 1. Managed-column profile resolution (`getEffectiveProfile(s)`) resolves
|
|
58
|
+
// default profiles against the vellum column only, ignoring
|
|
59
|
+
// `llm.defaultProvider`; on a BYO install that is not the body that
|
|
60
|
+
// dispatches. Runtime code must use `resolveDefaultProfileForProvider` /
|
|
61
|
+
// `getEffectiveProfilesForProvider` instead. The allowlist below is the
|
|
62
|
+
// full set of intentional managed-column consumers: the catalog itself,
|
|
63
|
+
// hatch-time seeding (writes managed stubs by design), and write-path
|
|
64
|
+
// validation.
|
|
65
|
+
//
|
|
66
|
+
// 2. `cli/logger` is the plain-stdout writer for short-lived `assistant …`
|
|
67
|
+
// invocations. It has no level filtering and no log-file routing, so a
|
|
68
|
+
// daemon-side module reaching for it writes debug output straight to a
|
|
69
|
+
// stdout the daemon may not own. Daemon code uses `getLogger()` from
|
|
70
|
+
// `util/logger.js`. The pattern matches on the import specifier, so
|
|
71
|
+
// CLI-internal files (which reach their logger relatively, as
|
|
72
|
+
// `../logger.js`) are unaffected. The companion guard test
|
|
73
|
+
// `src/__tests__/cli-logger-boundary-guard.test.ts` enforces the same
|
|
74
|
+
// boundary by resolved path, independent of how a specifier is spelled.
|
|
60
75
|
{
|
|
61
76
|
files: ["src/**/*.ts"],
|
|
62
77
|
ignores: [
|
|
@@ -77,6 +92,11 @@ const eslintConfig = defineConfig([
|
|
|
77
92
|
message:
|
|
78
93
|
"Managed-column resolution ignores llm.defaultProvider. Use resolveDefaultProfileForProvider / getEffectiveProfilesForProvider with the parsed config's llm.defaultProvider ?? null.",
|
|
79
94
|
},
|
|
95
|
+
{
|
|
96
|
+
group: ["**/cli/logger.js"],
|
|
97
|
+
message:
|
|
98
|
+
"cli/logger writes unfiltered plain text to stdout and is for src/cli/ only. Daemon and shared modules must use getLogger() from util/logger.js so output is level-filtered and routed to the log file. Within src/cli/, import the logger relatively (../logger.js).",
|
|
99
|
+
},
|
|
80
100
|
],
|
|
81
101
|
},
|
|
82
102
|
],
|
package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"./attachment-naming": "./src/attachment-naming.ts",
|
|
20
20
|
"./redacted-credential": "./src/redacted-credential.ts",
|
|
21
21
|
"./secret-detection": "./src/secret-detection.ts",
|
|
22
|
+
"./stripe-currency": "./src/stripe-currency.ts",
|
|
22
23
|
"./error": "./src/error.ts"
|
|
23
24
|
},
|
|
24
25
|
"scripts": {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
STRIPE_THREE_DECIMAL_CURRENCIES,
|
|
5
|
+
STRIPE_ZERO_DECIMAL_CURRENCIES,
|
|
6
|
+
stripeScaleDigits,
|
|
7
|
+
} from "../stripe-currency.js";
|
|
8
|
+
|
|
9
|
+
describe("stripeScaleDigits", () => {
|
|
10
|
+
test("zero-decimal currencies scale to 0 digits", () => {
|
|
11
|
+
expect(stripeScaleDigits("JPY")).toBe(0);
|
|
12
|
+
expect(stripeScaleDigits("KRW")).toBe(0);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("three-decimal currencies scale to 3 digits", () => {
|
|
16
|
+
expect(stripeScaleDigits("BHD")).toBe(3);
|
|
17
|
+
expect(stripeScaleDigits("KWD")).toBe(3);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("everything else scales to 2 digits", () => {
|
|
21
|
+
expect(stripeScaleDigits("USD")).toBe(2);
|
|
22
|
+
expect(stripeScaleDigits("EUR")).toBe(2);
|
|
23
|
+
expect(stripeScaleDigits("XYZ")).toBe(2);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("Stripe's charge-side two-decimal special cases stay at 2 digits", () => {
|
|
27
|
+
for (const code of ["ISK", "HUF", "TWD", "UGX"]) {
|
|
28
|
+
expect(stripeScaleDigits(code)).toBe(2);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("the currency sets do not overlap", () => {
|
|
33
|
+
for (const code of STRIPE_ZERO_DECIMAL_CURRENCIES) {
|
|
34
|
+
expect(STRIPE_THREE_DECIMAL_CURRENCIES.has(code)).toBe(false);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stripe amount scaling rules for charges and invoices.
|
|
3
|
+
*
|
|
4
|
+
* These sets follow Stripe's amount scaling rules
|
|
5
|
+
* (https://docs.stripe.com/currencies), not ISO 4217 metadata: divide the
|
|
6
|
+
* minor-unit integer by 100 for most currencies, by 1 for the zero-decimal
|
|
7
|
+
* set (e.g. JPY, KRW), and by 1000 for the three-decimal set (e.g. BHD).
|
|
8
|
+
* ISK, HUF, TWD, and UGX are deliberately absent from the zero-decimal set:
|
|
9
|
+
* Stripe charges and invoices them as two-decimal amounts and treats them
|
|
10
|
+
* as zero-decimal only for payouts, per Stripe's currency docs.
|
|
11
|
+
*
|
|
12
|
+
* Only the scaling data and digit selection live here; presentation (locale,
|
|
13
|
+
* symbol vs code display, fallbacks for unknown codes) belongs to each
|
|
14
|
+
* consumer.
|
|
15
|
+
*/
|
|
16
|
+
export const STRIPE_ZERO_DECIMAL_CURRENCIES: ReadonlySet<string> = new Set([
|
|
17
|
+
"BIF",
|
|
18
|
+
"CLP",
|
|
19
|
+
"DJF",
|
|
20
|
+
"GNF",
|
|
21
|
+
"JPY",
|
|
22
|
+
"KMF",
|
|
23
|
+
"KRW",
|
|
24
|
+
"MGA",
|
|
25
|
+
"PYG",
|
|
26
|
+
"RWF",
|
|
27
|
+
"VND",
|
|
28
|
+
"VUV",
|
|
29
|
+
"XAF",
|
|
30
|
+
"XOF",
|
|
31
|
+
"XPF",
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
export const STRIPE_THREE_DECIMAL_CURRENCIES: ReadonlySet<string> = new Set([
|
|
35
|
+
"BHD",
|
|
36
|
+
"JOD",
|
|
37
|
+
"KWD",
|
|
38
|
+
"OMR",
|
|
39
|
+
"TND",
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Fraction digits Stripe uses when charging or invoicing in the given
|
|
44
|
+
* currency. Expects an uppercase ISO 4217 code; unknown codes get the
|
|
45
|
+
* two-decimal default.
|
|
46
|
+
*/
|
|
47
|
+
export function stripeScaleDigits(currencyCode: string): number {
|
|
48
|
+
if (STRIPE_ZERO_DECIMAL_CURRENCIES.has(currencyCode)) {
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
if (STRIPE_THREE_DECIMAL_CURRENCIES.has(currencyCode)) {
|
|
52
|
+
return 3;
|
|
53
|
+
}
|
|
54
|
+
return 2;
|
|
55
|
+
}
|
package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"./attachment-naming": "./src/attachment-naming.ts",
|
|
20
20
|
"./redacted-credential": "./src/redacted-credential.ts",
|
|
21
21
|
"./secret-detection": "./src/secret-detection.ts",
|
|
22
|
+
"./stripe-currency": "./src/stripe-currency.ts",
|
|
22
23
|
"./error": "./src/error.ts"
|
|
23
24
|
},
|
|
24
25
|
"scripts": {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
STRIPE_THREE_DECIMAL_CURRENCIES,
|
|
5
|
+
STRIPE_ZERO_DECIMAL_CURRENCIES,
|
|
6
|
+
stripeScaleDigits,
|
|
7
|
+
} from "../stripe-currency.js";
|
|
8
|
+
|
|
9
|
+
describe("stripeScaleDigits", () => {
|
|
10
|
+
test("zero-decimal currencies scale to 0 digits", () => {
|
|
11
|
+
expect(stripeScaleDigits("JPY")).toBe(0);
|
|
12
|
+
expect(stripeScaleDigits("KRW")).toBe(0);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("three-decimal currencies scale to 3 digits", () => {
|
|
16
|
+
expect(stripeScaleDigits("BHD")).toBe(3);
|
|
17
|
+
expect(stripeScaleDigits("KWD")).toBe(3);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("everything else scales to 2 digits", () => {
|
|
21
|
+
expect(stripeScaleDigits("USD")).toBe(2);
|
|
22
|
+
expect(stripeScaleDigits("EUR")).toBe(2);
|
|
23
|
+
expect(stripeScaleDigits("XYZ")).toBe(2);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("Stripe's charge-side two-decimal special cases stay at 2 digits", () => {
|
|
27
|
+
for (const code of ["ISK", "HUF", "TWD", "UGX"]) {
|
|
28
|
+
expect(stripeScaleDigits(code)).toBe(2);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("the currency sets do not overlap", () => {
|
|
33
|
+
for (const code of STRIPE_ZERO_DECIMAL_CURRENCIES) {
|
|
34
|
+
expect(STRIPE_THREE_DECIMAL_CURRENCIES.has(code)).toBe(false);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stripe amount scaling rules for charges and invoices.
|
|
3
|
+
*
|
|
4
|
+
* These sets follow Stripe's amount scaling rules
|
|
5
|
+
* (https://docs.stripe.com/currencies), not ISO 4217 metadata: divide the
|
|
6
|
+
* minor-unit integer by 100 for most currencies, by 1 for the zero-decimal
|
|
7
|
+
* set (e.g. JPY, KRW), and by 1000 for the three-decimal set (e.g. BHD).
|
|
8
|
+
* ISK, HUF, TWD, and UGX are deliberately absent from the zero-decimal set:
|
|
9
|
+
* Stripe charges and invoices them as two-decimal amounts and treats them
|
|
10
|
+
* as zero-decimal only for payouts, per Stripe's currency docs.
|
|
11
|
+
*
|
|
12
|
+
* Only the scaling data and digit selection live here; presentation (locale,
|
|
13
|
+
* symbol vs code display, fallbacks for unknown codes) belongs to each
|
|
14
|
+
* consumer.
|
|
15
|
+
*/
|
|
16
|
+
export const STRIPE_ZERO_DECIMAL_CURRENCIES: ReadonlySet<string> = new Set([
|
|
17
|
+
"BIF",
|
|
18
|
+
"CLP",
|
|
19
|
+
"DJF",
|
|
20
|
+
"GNF",
|
|
21
|
+
"JPY",
|
|
22
|
+
"KMF",
|
|
23
|
+
"KRW",
|
|
24
|
+
"MGA",
|
|
25
|
+
"PYG",
|
|
26
|
+
"RWF",
|
|
27
|
+
"VND",
|
|
28
|
+
"VUV",
|
|
29
|
+
"XAF",
|
|
30
|
+
"XOF",
|
|
31
|
+
"XPF",
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
export const STRIPE_THREE_DECIMAL_CURRENCIES: ReadonlySet<string> = new Set([
|
|
35
|
+
"BHD",
|
|
36
|
+
"JOD",
|
|
37
|
+
"KWD",
|
|
38
|
+
"OMR",
|
|
39
|
+
"TND",
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Fraction digits Stripe uses when charging or invoicing in the given
|
|
44
|
+
* currency. Expects an uppercase ISO 4217 code; unknown codes get the
|
|
45
|
+
* two-decimal default.
|
|
46
|
+
*/
|
|
47
|
+
export function stripeScaleDigits(currencyCode: string): number {
|
|
48
|
+
if (STRIPE_ZERO_DECIMAL_CURRENCIES.has(currencyCode)) {
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
if (STRIPE_THREE_DECIMAL_CURRENCIES.has(currencyCode)) {
|
|
52
|
+
return 3;
|
|
53
|
+
}
|
|
54
|
+
return 2;
|
|
55
|
+
}
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"./attachment-naming": "./src/attachment-naming.ts",
|
|
20
20
|
"./redacted-credential": "./src/redacted-credential.ts",
|
|
21
21
|
"./secret-detection": "./src/secret-detection.ts",
|
|
22
|
+
"./stripe-currency": "./src/stripe-currency.ts",
|
|
22
23
|
"./error": "./src/error.ts"
|
|
23
24
|
},
|
|
24
25
|
"scripts": {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
STRIPE_THREE_DECIMAL_CURRENCIES,
|
|
5
|
+
STRIPE_ZERO_DECIMAL_CURRENCIES,
|
|
6
|
+
stripeScaleDigits,
|
|
7
|
+
} from "../stripe-currency.js";
|
|
8
|
+
|
|
9
|
+
describe("stripeScaleDigits", () => {
|
|
10
|
+
test("zero-decimal currencies scale to 0 digits", () => {
|
|
11
|
+
expect(stripeScaleDigits("JPY")).toBe(0);
|
|
12
|
+
expect(stripeScaleDigits("KRW")).toBe(0);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("three-decimal currencies scale to 3 digits", () => {
|
|
16
|
+
expect(stripeScaleDigits("BHD")).toBe(3);
|
|
17
|
+
expect(stripeScaleDigits("KWD")).toBe(3);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("everything else scales to 2 digits", () => {
|
|
21
|
+
expect(stripeScaleDigits("USD")).toBe(2);
|
|
22
|
+
expect(stripeScaleDigits("EUR")).toBe(2);
|
|
23
|
+
expect(stripeScaleDigits("XYZ")).toBe(2);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("Stripe's charge-side two-decimal special cases stay at 2 digits", () => {
|
|
27
|
+
for (const code of ["ISK", "HUF", "TWD", "UGX"]) {
|
|
28
|
+
expect(stripeScaleDigits(code)).toBe(2);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("the currency sets do not overlap", () => {
|
|
33
|
+
for (const code of STRIPE_ZERO_DECIMAL_CURRENCIES) {
|
|
34
|
+
expect(STRIPE_THREE_DECIMAL_CURRENCIES.has(code)).toBe(false);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stripe amount scaling rules for charges and invoices.
|
|
3
|
+
*
|
|
4
|
+
* These sets follow Stripe's amount scaling rules
|
|
5
|
+
* (https://docs.stripe.com/currencies), not ISO 4217 metadata: divide the
|
|
6
|
+
* minor-unit integer by 100 for most currencies, by 1 for the zero-decimal
|
|
7
|
+
* set (e.g. JPY, KRW), and by 1000 for the three-decimal set (e.g. BHD).
|
|
8
|
+
* ISK, HUF, TWD, and UGX are deliberately absent from the zero-decimal set:
|
|
9
|
+
* Stripe charges and invoices them as two-decimal amounts and treats them
|
|
10
|
+
* as zero-decimal only for payouts, per Stripe's currency docs.
|
|
11
|
+
*
|
|
12
|
+
* Only the scaling data and digit selection live here; presentation (locale,
|
|
13
|
+
* symbol vs code display, fallbacks for unknown codes) belongs to each
|
|
14
|
+
* consumer.
|
|
15
|
+
*/
|
|
16
|
+
export const STRIPE_ZERO_DECIMAL_CURRENCIES: ReadonlySet<string> = new Set([
|
|
17
|
+
"BIF",
|
|
18
|
+
"CLP",
|
|
19
|
+
"DJF",
|
|
20
|
+
"GNF",
|
|
21
|
+
"JPY",
|
|
22
|
+
"KMF",
|
|
23
|
+
"KRW",
|
|
24
|
+
"MGA",
|
|
25
|
+
"PYG",
|
|
26
|
+
"RWF",
|
|
27
|
+
"VND",
|
|
28
|
+
"VUV",
|
|
29
|
+
"XAF",
|
|
30
|
+
"XOF",
|
|
31
|
+
"XPF",
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
export const STRIPE_THREE_DECIMAL_CURRENCIES: ReadonlySet<string> = new Set([
|
|
35
|
+
"BHD",
|
|
36
|
+
"JOD",
|
|
37
|
+
"KWD",
|
|
38
|
+
"OMR",
|
|
39
|
+
"TND",
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Fraction digits Stripe uses when charging or invoicing in the given
|
|
44
|
+
* currency. Expects an uppercase ISO 4217 code; unknown codes get the
|
|
45
|
+
* two-decimal default.
|
|
46
|
+
*/
|
|
47
|
+
export function stripeScaleDigits(currencyCode: string): number {
|
|
48
|
+
if (STRIPE_ZERO_DECIMAL_CURRENCIES.has(currencyCode)) {
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
if (STRIPE_THREE_DECIMAL_CURRENCIES.has(currencyCode)) {
|
|
52
|
+
return 3;
|
|
53
|
+
}
|
|
54
|
+
return 2;
|
|
55
|
+
}
|
|
@@ -14,6 +14,36 @@ describe("extractSlackUserMentionIds", () => {
|
|
|
14
14
|
extractSlackUserMentionIds("<@U123> hi <@W456> and <@U123> again"),
|
|
15
15
|
).toEqual(["U123", "W456"]);
|
|
16
16
|
});
|
|
17
|
+
|
|
18
|
+
test("includes pipe-form user mention IDs", () => {
|
|
19
|
+
expect(extractSlackUserMentionIds("<@U123|jane> and <@W456|>")).toEqual([
|
|
20
|
+
"U123",
|
|
21
|
+
"W456",
|
|
22
|
+
]);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("buildSlackUserLabelMap", () => {
|
|
27
|
+
test("skips pipe-form mentions with usable embedded labels, queues the rest", async () => {
|
|
28
|
+
const requested: string[] = [];
|
|
29
|
+
const labels = await buildSlackUserLabelMap(
|
|
30
|
+
["<@U123|jane> <@U456|> <@U789|U789> <@U999>"],
|
|
31
|
+
async (id) => {
|
|
32
|
+
requested.push(id);
|
|
33
|
+
return `name-${id}`;
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// Usable embedded label: rendered from the token, no lookup.
|
|
38
|
+
expect(requested).not.toContain("U123");
|
|
39
|
+
// Empty or ID-shaped embedded labels still need resolution.
|
|
40
|
+
expect(requested.sort()).toEqual(["U456", "U789", "U999"]);
|
|
41
|
+
expect(labels).toEqual({
|
|
42
|
+
U456: "name-U456",
|
|
43
|
+
U789: "name-U789",
|
|
44
|
+
U999: "name-U999",
|
|
45
|
+
});
|
|
46
|
+
});
|
|
17
47
|
});
|
|
18
48
|
|
|
19
49
|
describe("extractSlackChannelReferenceIds", () => {
|
|
@@ -52,6 +82,24 @@ describe("renderSlackTextForModel", () => {
|
|
|
52
82
|
).toBe("hello @unknown-user");
|
|
53
83
|
});
|
|
54
84
|
|
|
85
|
+
test("prefers embedded pipe-form user labels over lookups", () => {
|
|
86
|
+
expect(renderSlackTextForModel("hi <@U123|jane>")).toBe("hi @jane");
|
|
87
|
+
expect(
|
|
88
|
+
renderSlackTextForModel("hi <@U123|jane>", {
|
|
89
|
+
userLabels: { U123: "Jane Doe" },
|
|
90
|
+
}),
|
|
91
|
+
).toBe("hi @jane");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("falls back past ID-shaped embedded user labels to resolved ones", () => {
|
|
95
|
+
expect(
|
|
96
|
+
renderSlackTextForModel("hi <@U123|U123>", {
|
|
97
|
+
userLabels: { U123: "Jane Doe" },
|
|
98
|
+
}),
|
|
99
|
+
).toBe("hi @Jane Doe");
|
|
100
|
+
expect(renderSlackTextForModel("hi <@U123|U123>")).toBe("hi @unknown-user");
|
|
101
|
+
});
|
|
102
|
+
|
|
55
103
|
test("renders channel references with labels and fallbacks", () => {
|
|
56
104
|
expect(
|
|
57
105
|
renderSlackTextForModel("<#C123|general> <#C456>", {
|
|
@@ -5,7 +5,7 @@ export interface RenderSlackTextOptions {
|
|
|
5
5
|
channelFallbackLabel?: string;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
const SLACK_USER_MENTION_RE = /<@([UW][A-Z0-9]+)
|
|
8
|
+
const SLACK_USER_MENTION_RE = /<@([UW][A-Z0-9]+)(?:\|[^>]*)?>/g;
|
|
9
9
|
const SLACK_CHANNEL_REFERENCE_RE = /<#([CDG][A-Z0-9]+)(?:\|[^>]*)?>/g;
|
|
10
10
|
|
|
11
11
|
export function extractSlackUserMentionIds(text: string): string[] {
|
|
@@ -107,7 +107,14 @@ export async function buildSlackUserLabelMap(
|
|
|
107
107
|
|
|
108
108
|
for (const text of texts) {
|
|
109
109
|
if (!text) continue;
|
|
110
|
-
for (const
|
|
110
|
+
for (const match of text.matchAll(SLACK_USER_MENTION_RE)) {
|
|
111
|
+
const id = match[1];
|
|
112
|
+
// A pipe-form mention carrying a usable embedded label renders from
|
|
113
|
+
// that label directly; only queue a lookup when the label is missing,
|
|
114
|
+
// empty, or ID-shaped. Mirrors the channel builder below.
|
|
115
|
+
const [, embeddedLabel] = splitSlackLabel(match[0].slice(1, -1));
|
|
116
|
+
const sanitizedEmbeddedLabel = sanitizeOptionalLabel(embeddedLabel);
|
|
117
|
+
if (sanitizedEmbeddedLabel && sanitizedEmbeddedLabel !== id) continue;
|
|
111
118
|
if (seen.has(id)) continue;
|
|
112
119
|
seen.add(id);
|
|
113
120
|
ids.push(id);
|
|
@@ -175,17 +182,29 @@ function renderUserMention(
|
|
|
175
182
|
content: string,
|
|
176
183
|
options: RenderSlackTextOptions,
|
|
177
184
|
): string {
|
|
178
|
-
const
|
|
185
|
+
const [idWithPrefix, label] = splitSlackLabel(content);
|
|
186
|
+
const id = idWithPrefix.slice(1);
|
|
179
187
|
if (!isSlackUserId(id)) {
|
|
180
188
|
return `<${content}>`;
|
|
181
189
|
}
|
|
182
190
|
|
|
191
|
+
// Slack's legacy pipe form (`<@U123|username>`) carries its own label:
|
|
192
|
+
// prefer it over a lookup, mirroring renderChannelReference. The embedded
|
|
193
|
+
// label is Slack-sourced (part of the token), so entities decode before
|
|
194
|
+
// sanitization; the caller-resolved label below is not.
|
|
195
|
+
const embeddedLabel = sanitizeOptionalLabel(
|
|
196
|
+
label === undefined ? undefined : decodeSlackHtmlEntities(label),
|
|
197
|
+
);
|
|
198
|
+
if (embeddedLabel && embeddedLabel !== id) {
|
|
199
|
+
return `@${embeddedLabel}`;
|
|
200
|
+
}
|
|
201
|
+
|
|
183
202
|
const fallback = sanitizeLabel(options.userFallbackLabel, "unknown-user");
|
|
184
|
-
const
|
|
185
|
-
if (
|
|
203
|
+
const resolvedLabel = sanitizeLabel(options.userLabels?.[id], fallback);
|
|
204
|
+
if (resolvedLabel === id) {
|
|
186
205
|
return `@${fallback}`;
|
|
187
206
|
}
|
|
188
|
-
return `@${
|
|
207
|
+
return `@${resolvedLabel}`;
|
|
189
208
|
}
|
|
190
209
|
|
|
191
210
|
function renderChannelReference(
|