@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
|
@@ -1318,6 +1318,7 @@ describe("UsageTelemetryReporter", () => {
|
|
|
1318
1318
|
outcome?: string | null;
|
|
1319
1319
|
batchedInto?: string | null;
|
|
1320
1320
|
failureCode?: string | null;
|
|
1321
|
+
scripted?: boolean | null;
|
|
1321
1322
|
} = {},
|
|
1322
1323
|
) {
|
|
1323
1324
|
return {
|
|
@@ -1329,6 +1330,9 @@ describe("UsageTelemetryReporter", () => {
|
|
|
1329
1330
|
interfaceId: "macos",
|
|
1330
1331
|
channelId: "vellum",
|
|
1331
1332
|
clientMetadata: null,
|
|
1333
|
+
// Defaults to UNKNOWN so existing cases keep asserting the pre-marker
|
|
1334
|
+
// wire shape; each scripted case opts in explicitly.
|
|
1335
|
+
scripted: null,
|
|
1332
1336
|
...overrides,
|
|
1333
1337
|
};
|
|
1334
1338
|
}
|
|
@@ -1588,6 +1592,50 @@ describe("UsageTelemetryReporter", () => {
|
|
|
1588
1592
|
expect("failure_code" in byId["evt-cancelled"]).toBe(false);
|
|
1589
1593
|
});
|
|
1590
1594
|
|
|
1595
|
+
test("the scripted marker rides the turn event with all three states distinct", async () => {
|
|
1596
|
+
// `scripted` is what lets activation metrics exclude auto-sent onboarding
|
|
1597
|
+
// turns for EVERY owner rather than only diagnostics-consenting ones
|
|
1598
|
+
// (ANT-10), so its states must stay distinguishable on the wire. Note
|
|
1599
|
+
// diagnostics consent is OFF here: unlike `trace`, this field must ship
|
|
1600
|
+
// regardless: that independence is the entire point of the field.
|
|
1601
|
+
mockGetCachedShareDiagnostics.mockReturnValue(false);
|
|
1602
|
+
mockQueryUnreportedUsageEvents.mockReturnValue([]);
|
|
1603
|
+
useStatefulCheckpoints();
|
|
1604
|
+
mockQueryUnreportedTurnEvents.mockReturnValue([
|
|
1605
|
+
turnEvent("evt-scripted", 1700000010000, "conv-1", { scripted: true }),
|
|
1606
|
+
turnEvent("evt-typed", 1700000011000, "conv-1", { scripted: false }),
|
|
1607
|
+
turnEvent("evt-unknown", 1700000012000, "conv-2", { scripted: null }),
|
|
1608
|
+
]);
|
|
1609
|
+
mockIsTurnSettled.mockReturnValue(true);
|
|
1610
|
+
mockFetch.mockImplementation(() =>
|
|
1611
|
+
Promise.resolve(new Response('{"accepted":3}', { status: 200 })),
|
|
1612
|
+
);
|
|
1613
|
+
|
|
1614
|
+
const reporter = makeReporter();
|
|
1615
|
+
await reporter.flush();
|
|
1616
|
+
|
|
1617
|
+
const body = JSON.parse(
|
|
1618
|
+
(mockFetch.mock.calls[0] as [string, RequestInit])[1].body as string,
|
|
1619
|
+
);
|
|
1620
|
+
const byId = Object.fromEntries(
|
|
1621
|
+
body.events.map((e: { daemon_event_id: string }) => [
|
|
1622
|
+
e.daemon_event_id,
|
|
1623
|
+
e,
|
|
1624
|
+
]),
|
|
1625
|
+
);
|
|
1626
|
+
expect(byId["evt-scripted"].scripted).toBe(true);
|
|
1627
|
+
// The state most at risk: an omit-when-falsy spread would drop this and
|
|
1628
|
+
// silently downgrade a turn we KNOW was typed into "unknown", handing
|
|
1629
|
+
// activation back to the consent-gated classifier this field replaces.
|
|
1630
|
+
expect("scripted" in byId["evt-typed"]).toBe(true);
|
|
1631
|
+
expect(byId["evt-typed"].scripted).toBe(false);
|
|
1632
|
+
// A row predating the marker stays UNKNOWN: the key is absent, so the
|
|
1633
|
+
// wire shape is byte-identical to a pre-scripted turn event and
|
|
1634
|
+
// downstream falls back to the trace classifier rather than being told
|
|
1635
|
+
// something untrue about the turn.
|
|
1636
|
+
expect("scripted" in byId["evt-unknown"]).toBe(false);
|
|
1637
|
+
});
|
|
1638
|
+
|
|
1591
1639
|
test("an unrecognized outcome value in metadata is dropped from the wire", async () => {
|
|
1592
1640
|
mockGetCachedShareDiagnostics.mockReturnValue(false);
|
|
1593
1641
|
mockQueryUnreportedUsageEvents.mockReturnValue([]);
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
* `host_browser_session_invalidated`.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { getLogger } from "../../util/logger.js";
|
|
18
|
+
|
|
19
|
+
const log = getLogger("pinned-tabs");
|
|
18
20
|
|
|
19
21
|
const pinnedTabs = new Map<string, Map<string, string>>();
|
|
20
22
|
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
getMessages,
|
|
11
11
|
} from "../../persistence/conversation-crud.js";
|
|
12
12
|
import type { ContentBlock, Message } from "../../providers/types.js";
|
|
13
|
+
import { buildAdvisorContext } from "../../subagent/consult-context.js";
|
|
13
14
|
import {
|
|
14
15
|
advisorRequestText,
|
|
15
16
|
buildAdvisorSystem,
|
|
@@ -293,6 +294,23 @@ async function runAdvisorConsult(args: {
|
|
|
293
294
|
);
|
|
294
295
|
const sanitizedMessages = sanitizeConsultTranscript(withInFlight);
|
|
295
296
|
|
|
297
|
+
// Situational awareness for the advisor: the parent's live tool set, the
|
|
298
|
+
// full skill catalog, and its workspace. Assembled off the per-turn
|
|
299
|
+
// ToolContext snapshot (trust, channel) so the personal-memory sections
|
|
300
|
+
// are gated exactly like the runtime injectors. Best-effort: a null pack
|
|
301
|
+
// just means the consult runs on transcript + system prompt alone.
|
|
302
|
+
const situationalContext = await buildAdvisorContext({
|
|
303
|
+
conversationId: context.conversationId,
|
|
304
|
+
workingDir: context.workingDir,
|
|
305
|
+
allowedToolNames: context.allowedToolNames,
|
|
306
|
+
trustClass: context.trustClass,
|
|
307
|
+
sourceChannel: context.executionChannel,
|
|
308
|
+
enabledPluginSet: context.enabledPluginSet,
|
|
309
|
+
// The parent's warm per-turn catalog keeps the synchronous on-disk
|
|
310
|
+
// catalog scan out of the consult path.
|
|
311
|
+
skillCatalog: parentConversation.skillProjectionCache?.catalog,
|
|
312
|
+
});
|
|
313
|
+
|
|
296
314
|
// Default to the stronger advisor profile when the caller did not pin one;
|
|
297
315
|
// an explicit `inference_profile` wins (already forced upstream).
|
|
298
316
|
const advisorProfile = getConfig().llm.advisorProfile;
|
|
@@ -322,8 +340,12 @@ async function runAdvisorConsult(args: {
|
|
|
322
340
|
parentConversationId: context.conversationId,
|
|
323
341
|
label,
|
|
324
342
|
// Carry the agent's own objective into the consult request — the
|
|
325
|
-
// agent states the task here, and the inherited transcript can be
|
|
343
|
+
// agent states the task here, and the inherited transcript can be
|
|
344
|
+
// thin. The situational pack rides in the model request only
|
|
345
|
+
// (`requestText`), keeping the system prompt minimal and the
|
|
346
|
+
// display-facing `objective` free of bulky internal context.
|
|
326
347
|
objective: advisorRequestText(objective),
|
|
348
|
+
requestText: advisorRequestText(objective, situationalContext),
|
|
327
349
|
sendResultToUser: false,
|
|
328
350
|
role: "advisor",
|
|
329
351
|
fork: true,
|
|
@@ -7,7 +7,10 @@
|
|
|
7
7
|
* handled locally by the daemon.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
coerceSurfaceDataRecord,
|
|
12
|
+
normalizeVisualShowData,
|
|
13
|
+
} from "../../api/surfaces.js";
|
|
11
14
|
import { RiskLevel } from "../../permissions/types.js";
|
|
12
15
|
import { isWeakOpenModel } from "../../providers/weak-open-model.js";
|
|
13
16
|
import type {
|
|
@@ -22,6 +25,7 @@ import {
|
|
|
22
25
|
UI_SHOW_TYPE_DOCS,
|
|
23
26
|
uiShowTeachingError,
|
|
24
27
|
} from "./surface-shape-docs.js";
|
|
28
|
+
import { validateVisualHtml } from "./visual-validation.js";
|
|
25
29
|
|
|
26
30
|
// ---------------------------------------------------------------------------
|
|
27
31
|
// Helpers
|
|
@@ -59,6 +63,13 @@ function proxyExecute(toolName: string) {
|
|
|
59
63
|
};
|
|
60
64
|
}
|
|
61
65
|
|
|
66
|
+
if (toolName === "ui_show" && input.surface_type === "visual") {
|
|
67
|
+
const visualError = visualTeachingError(input);
|
|
68
|
+
if (visualError !== null) {
|
|
69
|
+
return { content: visualError, isError: true };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
62
73
|
if (toolName === "ui_show" && isDynamicPageAppSubstitute(input)) {
|
|
63
74
|
return {
|
|
64
75
|
content:
|
|
@@ -197,6 +208,33 @@ function isSubstantialInteractiveHtml(input: Record<string, unknown>): boolean {
|
|
|
197
208
|
return html.length > 2000 && INTERACTIVE_HTML_RE.test(html);
|
|
198
209
|
}
|
|
199
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Teaching error for a `visual` ui_show whose fragment would not render as
|
|
213
|
+
* intended, or null when it is sound. The checks run before proxying because
|
|
214
|
+
* the sandbox fails silently: an external resource never loads and an
|
|
215
|
+
* unknown `var()` resolves to nothing, so the user sees a blank or unthemed
|
|
216
|
+
* widget while the model believes it rendered.
|
|
217
|
+
*/
|
|
218
|
+
function visualTeachingError(input: Record<string, unknown>): string | null {
|
|
219
|
+
const { html } = normalizeVisualShowData(
|
|
220
|
+
input,
|
|
221
|
+
coerceSurfaceDataRecord(input.data),
|
|
222
|
+
);
|
|
223
|
+
if (html.trim().length === 0) {
|
|
224
|
+
return "Error: ui_show visual requires a non-empty HTML fragment in `data.html`. The surface was not displayed because no markup was provided — the user would see a blank box. Resend ui_show with the complete self-contained fragment in `data.html`.";
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const problems = validateVisualHtml(html);
|
|
228
|
+
if (problems.length === 0) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
return (
|
|
232
|
+
"Error: ui_show visual was not displayed — the fragment does not meet the sandbox contract:\n" +
|
|
233
|
+
problems.map((problem) => `- ${problem}`).join("\n") +
|
|
234
|
+
"\nFix every item above and call ui_show again."
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
200
238
|
function collectRoutingText(input: Record<string, unknown>): string[] {
|
|
201
239
|
const values: string[] = [];
|
|
202
240
|
addString(values, input.title);
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import {
|
|
20
20
|
coerceSurfaceDataRecord,
|
|
21
|
+
describeSurfaceDataStringParseFailure,
|
|
21
22
|
FileUploadSurfaceDataSchema,
|
|
22
23
|
normalizeCopyBlockShowData,
|
|
23
24
|
} from "../../api/surfaces.js";
|
|
@@ -66,7 +67,8 @@ interface SurfaceShapeDoc {
|
|
|
66
67
|
* Returns a description of what keeps the payload from rendering as intended
|
|
67
68
|
* — missing load-bearing content, or keys that would be silently dropped —
|
|
68
69
|
* or null when the payload is fine. Absent for types the daemon normalizes
|
|
69
|
-
* leniently (card) or that have bespoke handling (dynamic_page).
|
|
70
|
+
* leniently (card) or that have bespoke handling (dynamic_page, visual).
|
|
71
|
+
* Guards for
|
|
70
72
|
* types whose daemon normalizer recovers top-level input fields also receive
|
|
71
73
|
* the full tool `input`, so the guard accepts exactly what the normalizer
|
|
72
74
|
* accepts.
|
|
@@ -193,6 +195,12 @@ export const SURFACE_SHAPE_DOCS: Record<string, SurfaceShapeDoc> = {
|
|
|
193
195
|
shape:
|
|
194
196
|
"{ html, width?, height?, preview?: { title, subtitle?, description?, icon?, metrics?: [{ label, value }] } } — custom visual HTML for transient surfaces only, never app-like builds",
|
|
195
197
|
},
|
|
198
|
+
visual: {
|
|
199
|
+
purpose:
|
|
200
|
+
"polished inline diagram/chart/explainer — PREFER this when explaining how something works or compares; load the `visualize` skill first",
|
|
201
|
+
shape:
|
|
202
|
+
"{ html, height? } — one self-contained HTML/SVG fragment (no DOCTYPE/html/head/body, no external resources); every colour comes from the injected design-token CSS variables, so hex/rgb literals and invented `var()` names are rejected. Load the `visualize` skill with `skill_load` for the full contract and the token vocabulary",
|
|
203
|
+
},
|
|
196
204
|
channel_setup: {
|
|
197
205
|
purpose: "open the Slack/Telegram/Phone setup panel",
|
|
198
206
|
shape: '{ channel: "slack" | "telegram" | "phone" }',
|
|
@@ -243,12 +251,34 @@ export const UI_SHOW_TYPE_DOCS = [
|
|
|
243
251
|
`Other types: ${COLD_SURFACE_INDEX}. Send your best-guess data — if required content is missing, the error returns the exact shape.`,
|
|
244
252
|
].join("\n");
|
|
245
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Rejection envelope for a `data` argument the model double-encoded as a JSON
|
|
256
|
+
* string that does not parse — most often HTML whose inner double quotes were
|
|
257
|
+
* escaped wrong. The decode failure strands every field, so without this the
|
|
258
|
+
* surface's own shape check fires and blames the first field it misses, sending
|
|
259
|
+
* the model off to fix a fragment that was never the problem.
|
|
260
|
+
*/
|
|
261
|
+
function surfaceDataEncodingError(
|
|
262
|
+
surfaceType: string,
|
|
263
|
+
detail: string,
|
|
264
|
+
shape: string,
|
|
265
|
+
): string {
|
|
266
|
+
return (
|
|
267
|
+
`Error: ui_show ${surfaceType} was not displayed — \`data\` arrived as a JSON-encoded string that could not be parsed: ${detail}. ` +
|
|
268
|
+
"None of its fields could be read, so the surface looked empty. This is an argument-encoding problem, not a problem with the content itself. " +
|
|
269
|
+
`Pass \`data\` as a JSON object rather than a string: ${shape}. ` +
|
|
270
|
+
"If the content is HTML with double quotes inside, use single quotes for the HTML attributes (<rect class='box'>) so there is nothing to escape. " +
|
|
271
|
+
"Resend the same ui_show with `data` as an object."
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
246
275
|
/**
|
|
247
276
|
* Teaching error for a ui_show payload that would render nothing, or null
|
|
248
277
|
* when the payload is displayable. Unknown/missing surface_type gets the
|
|
249
|
-
* full type index;
|
|
250
|
-
*
|
|
251
|
-
*
|
|
278
|
+
* full type index; an undecodable JSON-string `data` gets the encoding
|
|
279
|
+
* envelope; a known type missing its load-bearing content gets that type's
|
|
280
|
+
* exact shape. dynamic_page emptiness and the `visual` fragment checks are
|
|
281
|
+
* handled by the bespoke envelopes in `definitions.ts`, not here.
|
|
252
282
|
*/
|
|
253
283
|
export function uiShowTeachingError(
|
|
254
284
|
input: Record<string, unknown>,
|
|
@@ -265,6 +295,10 @@ export function uiShowTeachingError(
|
|
|
265
295
|
return `Error: ui_show was not displayed — ${got}. Valid types: ${SURFACE_TYPE_INDEX}. Resend ui_show with one of these surface_type values; if a type's data is missing required content, the error will include its exact shape.`;
|
|
266
296
|
}
|
|
267
297
|
const doc = SURFACE_SHAPE_DOCS[surfaceType]!;
|
|
298
|
+
const parseFailure = describeSurfaceDataStringParseFailure(input.data);
|
|
299
|
+
if (parseFailure !== null) {
|
|
300
|
+
return surfaceDataEncodingError(surfaceType, parseFailure, doc.shape);
|
|
301
|
+
}
|
|
268
302
|
if (!doc.missingContent) {
|
|
269
303
|
return null;
|
|
270
304
|
}
|