@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
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace migration `138-backfill-home-feed-titles`.
|
|
3
|
+
*
|
|
4
|
+
* Gives every item in `<workspace>/data/home-feed.json` a non-empty
|
|
5
|
+
* `title`. The feed writer sets one on every item it appends; stored
|
|
6
|
+
* items that lack the field get a headline derived from their own
|
|
7
|
+
* `summary`, so the field is uniformly present across the file.
|
|
8
|
+
*
|
|
9
|
+
* Behaviour:
|
|
10
|
+
* - Missing file, unparseable JSON, or a non-object root: no-op.
|
|
11
|
+
* - Item that already has a non-empty `title`: untouched.
|
|
12
|
+
* - Item without one: title derived from `summary` (markdown and
|
|
13
|
+
* newlines flattened, first sentence, capped at 60 characters with
|
|
14
|
+
* an ellipsis).
|
|
15
|
+
* - `version`, `updatedAt`, and every other item field are preserved.
|
|
16
|
+
*
|
|
17
|
+
* Idempotent: a second run finds every item titled, so it writes
|
|
18
|
+
* nothing. The runner's checkpoint also skips re-runs, but this in-file
|
|
19
|
+
* guard keeps the migration safe even if the checkpoint is wiped.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
|
|
25
|
+
import { getLogger } from "../../util/logger.js";
|
|
26
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
27
|
+
|
|
28
|
+
const log = getLogger("workspace-migration-138-backfill-home-feed-titles");
|
|
29
|
+
|
|
30
|
+
const HOME_FEED_RELATIVE_PATH = join("data", "home-feed.json");
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Matches `NOTIFICATION_TITLE_MAX_LENGTH` in
|
|
34
|
+
* `notifications/notification-utils.ts`, the cap on the headline the feed
|
|
35
|
+
* writer derives from a summary, so a backfilled item and a freshly
|
|
36
|
+
* written one with the same summary carry the same title.
|
|
37
|
+
*/
|
|
38
|
+
const MAX_TITLE_LENGTH = 60;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The persisted item fields this migration touches. Inlined rather than
|
|
42
|
+
* imported from `home/feed-types.ts` so the migration stays
|
|
43
|
+
* self-contained per the migrations AGENTS.md.
|
|
44
|
+
*/
|
|
45
|
+
interface PersistedFeedItem {
|
|
46
|
+
/** Missing, empty, or non-string on the items repaired here. */
|
|
47
|
+
title?: unknown;
|
|
48
|
+
/** Source text for the derived title. */
|
|
49
|
+
summary?: unknown;
|
|
50
|
+
/** Every other persisted field is carried through untouched. */
|
|
51
|
+
[key: string]: unknown;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const backfillHomeFeedTitlesMigration: WorkspaceMigration = {
|
|
55
|
+
id: "138-backfill-home-feed-titles",
|
|
56
|
+
description:
|
|
57
|
+
"Backfill a summary-derived title on home-feed items that lack one",
|
|
58
|
+
|
|
59
|
+
run(workspaceDir: string): void {
|
|
60
|
+
const path = join(workspaceDir, HOME_FEED_RELATIVE_PATH);
|
|
61
|
+
if (!existsSync(path)) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Read outside the parse catch: a transient filesystem error (EIO,
|
|
66
|
+
// EACCES) must reach the runner so the migration retries, while
|
|
67
|
+
// malformed JSON is a permanent state this migration cannot repair.
|
|
68
|
+
const rawText = readFileSync(path, "utf-8");
|
|
69
|
+
|
|
70
|
+
let feed: Record<string, unknown>;
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(rawText);
|
|
73
|
+
if (!isPlainObject(parsed)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
feed = parsed;
|
|
77
|
+
} catch (err) {
|
|
78
|
+
log.warn(
|
|
79
|
+
{ err, path },
|
|
80
|
+
"Failed to parse home-feed.json; skipping title backfill",
|
|
81
|
+
);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const rawItems = Array.isArray(feed.items) ? feed.items : [];
|
|
86
|
+
let backfilled = 0;
|
|
87
|
+
for (const entry of rawItems) {
|
|
88
|
+
if (!isPlainObject(entry)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const item: PersistedFeedItem = entry;
|
|
92
|
+
if (typeof item.title === "string" && item.title.trim().length > 0) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (typeof item.summary !== "string") {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const derived = deriveTitle(item.summary);
|
|
99
|
+
if (derived.length === 0) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
item.title = derived;
|
|
103
|
+
backfilled++;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (backfilled === 0) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Write-then-rename so an interrupted write cannot leave
|
|
111
|
+
// home-feed.json truncated: the reader treats an unparseable file as
|
|
112
|
+
// an empty feed, so a torn in-place write would discard the user's
|
|
113
|
+
// notification history outright.
|
|
114
|
+
const tmpPath = `${path}.migration-138.tmp`;
|
|
115
|
+
writeFileSync(tmpPath, JSON.stringify(feed, null, 2), "utf-8");
|
|
116
|
+
renameSync(tmpPath, path);
|
|
117
|
+
|
|
118
|
+
log.info({ path, backfilled }, "Backfilled titles on home-feed items");
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// Deriving a title from the summary is idempotent, so a transient
|
|
122
|
+
// failure (full disk, I/O error) is safe to retry on later startups.
|
|
123
|
+
retryFailedCheckpoint: true,
|
|
124
|
+
|
|
125
|
+
down(_workspaceDir: string): void {
|
|
126
|
+
// Forward-only: a derived title is indistinguishable from an
|
|
127
|
+
// authored one, so there is nothing safe to strip back out.
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// Helpers: self-contained per the workspace migrations AGENTS.md
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Derive a short headline from a summary: the markdown is flattened to a
|
|
137
|
+
* single line of plain text, the first sentence is taken when the text
|
|
138
|
+
* has a terminator, and the result is capped at `MAX_TITLE_LENGTH`
|
|
139
|
+
* characters with an ellipsis. Returns "" when nothing usable survives.
|
|
140
|
+
*
|
|
141
|
+
* Inlined rather than imported from the notification pipeline so the
|
|
142
|
+
* migration stays self-contained per the migrations AGENTS.md.
|
|
143
|
+
*/
|
|
144
|
+
function deriveTitle(summary: string): string {
|
|
145
|
+
const text = flattenToPlainText(summary);
|
|
146
|
+
const firstSentenceEnd = text.search(/[.!?](\s|$)/);
|
|
147
|
+
const candidate =
|
|
148
|
+
firstSentenceEnd > 0 ? text.slice(0, firstSentenceEnd + 1) : text;
|
|
149
|
+
return candidate.length > MAX_TITLE_LENGTH
|
|
150
|
+
? candidate.slice(0, MAX_TITLE_LENGTH).trim() + "…"
|
|
151
|
+
: candidate.trim();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Reduce markdown-rich summary text to a single line of plain prose:
|
|
156
|
+
* block structure (code fences, headings, blockquotes, list markers) is
|
|
157
|
+
* dropped, inline formatting is unwrapped, and every run of whitespace,
|
|
158
|
+
* newlines included, collapses to one space.
|
|
159
|
+
*/
|
|
160
|
+
function flattenToPlainText(text: string): string {
|
|
161
|
+
return text
|
|
162
|
+
.replace(/^\s{0,3}(?:```|~~~).*$/gm, "")
|
|
163
|
+
.replace(/^\s{0,3}#{1,6}\s+/gm, "")
|
|
164
|
+
.replace(/^\s{0,3}>\s?/gm, "")
|
|
165
|
+
.replace(/^\s{0,3}(?:[-*+]|\d+[.)])\s+/gm, "")
|
|
166
|
+
.replace(/\*\*(.+?)\*\*/g, "$1")
|
|
167
|
+
.replace(/__(.+?)__/g, "$1")
|
|
168
|
+
.replace(/\*(.+?)\*/g, "$1")
|
|
169
|
+
.replace(/(?<!\w)_(.+?)_(?!\w)/g, "$1")
|
|
170
|
+
.replace(/~~(.+?)~~/g, "$1")
|
|
171
|
+
.replace(/`(.+?)`/g, "$1")
|
|
172
|
+
.replace(/\[(.+?)\]\(.*?\)/g, "$1")
|
|
173
|
+
.replace(/\s+/g, " ")
|
|
174
|
+
.trim();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
178
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
179
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Clear the machinery-written `"Speed"` label off the `cost-optimized`
|
|
8
|
+
* profile so the code catalog's new label ("Cost") reaches existing installs.
|
|
9
|
+
*
|
|
10
|
+
* `label` is workspace-owned overlay state: a managed-source entry's label
|
|
11
|
+
* wins over the code default (`WORKSPACE_OWNED_DEFAULT_FIELDS` in
|
|
12
|
+
* `config/default-profile-catalog.ts`). Migration 082 and the pre-catalog
|
|
13
|
+
* seeder both wrote `"Speed"` onto `cost-optimized`, and migration 126
|
|
14
|
+
* carried it onto the thin stub, so without this the picker would show two
|
|
15
|
+
* profiles named "Speed": `cost-optimized`'s stale overlay and
|
|
16
|
+
* `latency-optimized`, the user-facing Speed profile.
|
|
17
|
+
*
|
|
18
|
+
* Deleting the key (rather than writing "Cost") returns the label to code
|
|
19
|
+
* ownership, so later renames ship with a release instead of a migration.
|
|
20
|
+
*
|
|
21
|
+
* Only the exact string `"Speed"` is cleared. A user rename to anything else
|
|
22
|
+
* survives, as does an explicit `null` (label deliberately cleared). A rename
|
|
23
|
+
* that happened to be "Speed" is indistinguishable from the seeded value and
|
|
24
|
+
* is cleared too.
|
|
25
|
+
*
|
|
26
|
+
* Deliberately does NOT touch the `"Speed (Managed)"` label on BYOK hatch
|
|
27
|
+
* stubs: `ensureByokDefaultProfiles` matches that exact string to recognize a
|
|
28
|
+
* hatch stub and delete it (which is what re-enables the profile). Clearing
|
|
29
|
+
* it here would strand those installs with `cost-optimized` disabled. Once
|
|
30
|
+
* that pass removes the stub, the code label applies.
|
|
31
|
+
*/
|
|
32
|
+
export const clearRenamedCostProfileLabelMigration: WorkspaceMigration = {
|
|
33
|
+
id: "139-clear-renamed-cost-profile-label",
|
|
34
|
+
description:
|
|
35
|
+
'Clear the seeded "Speed" label on cost-optimized so the code catalog label applies',
|
|
36
|
+
run(workspaceDir: string): void {
|
|
37
|
+
const configPath = join(workspaceDir, "config.json");
|
|
38
|
+
if (!existsSync(configPath)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Read outside the parse catch: a transient filesystem error must reach
|
|
43
|
+
// the runner so the migration retries, while malformed JSON is a
|
|
44
|
+
// permanent state this migration cannot repair.
|
|
45
|
+
const rawText = readFileSync(configPath, "utf-8");
|
|
46
|
+
|
|
47
|
+
let config: Record<string, unknown>;
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(rawText);
|
|
50
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
config = parsed as Record<string, unknown>;
|
|
54
|
+
} catch {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const llm = readObject(config.llm);
|
|
59
|
+
if (llm === null) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const profiles = readObject(llm.profiles);
|
|
63
|
+
if (profiles === null) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const entry = readObject(profiles["cost-optimized"]);
|
|
67
|
+
if (entry === null) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Only a managed-source entry carries a machinery-written label. Anything
|
|
71
|
+
// else, a source-less legacy entry included, shadows the default outright
|
|
72
|
+
// (see `getEffectiveProfile`), so its label is the user's.
|
|
73
|
+
if (entry.source !== "managed") {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (entry.label !== "Speed") {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
delete entry.label;
|
|
81
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
82
|
+
},
|
|
83
|
+
down(_workspaceDir: string): void {
|
|
84
|
+
// Forward-only: the label is code-owned once cleared.
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
89
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
90
|
+
? (value as Record<string, unknown>)
|
|
91
|
+
: null;
|
|
92
|
+
}
|
|
@@ -134,6 +134,9 @@ import { collapseProviderConnectionsMigration } from "./133-collapse-provider-co
|
|
|
134
134
|
import { imageGenerationModeToProviderMigration } from "./134-image-generation-mode-to-provider.js";
|
|
135
135
|
import { copySubstrateTunablesMigration } from "./135-copy-substrate-tunables.js";
|
|
136
136
|
import { repairStaleFireworksKimiModelIdMigration } from "./136-repair-stale-fireworks-kimi-model-id.js";
|
|
137
|
+
import { repairRetiredFireworksMinimaxModelIdMigration } from "./137-repair-retired-fireworks-minimax-model-id.js";
|
|
138
|
+
import { backfillHomeFeedTitlesMigration } from "./138-backfill-home-feed-titles.js";
|
|
139
|
+
import { clearRenamedCostProfileLabelMigration } from "./139-clear-renamed-cost-profile-label.js";
|
|
137
140
|
import { migrateToWorkspaceVolumeMigration } from "./migrate-to-workspace-volume.js";
|
|
138
141
|
import type { WorkspaceMigration } from "./types.js";
|
|
139
142
|
|
|
@@ -283,4 +286,7 @@ export const WORKSPACE_MIGRATIONS: WorkspaceMigration[] = [
|
|
|
283
286
|
imageGenerationModeToProviderMigration,
|
|
284
287
|
copySubstrateTunablesMigration,
|
|
285
288
|
repairStaleFireworksKimiModelIdMigration,
|
|
289
|
+
repairRetiredFireworksMinimaxModelIdMigration,
|
|
290
|
+
backfillHomeFeedTitlesMigration,
|
|
291
|
+
clearRenamedCostProfileLabelMigration,
|
|
286
292
|
];
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canonical `conversations.source` string for background memory v2
|
|
3
|
-
* consolidation runs. Lives in a tiny constants module so the route layer can
|
|
4
|
-
* recognize consolidation conversations without importing the consolidation
|
|
5
|
-
* job (which pulls in agent-wake + bootstrap dependencies).
|
|
6
|
-
*/
|
|
7
|
-
// FROZEN: persisted `conversations.source` value — never rename it.
|
|
8
|
-
export const MEMORY_V2_CONSOLIDATION_SOURCE = "memory_v2_consolidation";
|