@vellumai/assistant 0.6.5 → 0.6.6
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/AGENTS.md +9 -1
- package/ARCHITECTURE.md +15 -17
- package/Dockerfile +6 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
- package/docs/architecture/integrations.md +32 -39
- package/docs/architecture/memory.md +25 -30
- package/docs/architecture/security.md +7 -6
- package/docs/browser-use-architecture-phase2.md +63 -20
- package/docs/plugins.md +761 -0
- package/examples/plugins/echo/README.md +132 -0
- package/examples/plugins/echo/package.json +17 -0
- package/examples/plugins/echo/register.ts +187 -0
- package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
- package/openapi.yaml +212 -68
- package/package.json +1 -1
- package/src/__tests__/app-compiler.test.ts +57 -0
- package/src/__tests__/approval-cascade.test.ts +7 -2
- package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
- package/src/__tests__/avatar-generator.test.ts +4 -2
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/catalog-cache.test.ts +69 -0
- package/src/__tests__/checker.test.ts +459 -171
- package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
- package/src/__tests__/compaction-events.test.ts +501 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
- package/src/__tests__/config-model-image-provider.test.ts +110 -0
- package/src/__tests__/config-schema.test.ts +22 -9
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- package/src/__tests__/contacts-tools.test.ts +26 -0
- package/src/__tests__/context-overflow-policy.test.ts +7 -7
- package/src/__tests__/context-window-manager.test.ts +355 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +26 -30
- package/src/__tests__/conversation-agent-loop.test.ts +30 -141
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -1
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +2 -16
- package/src/__tests__/conversation-pairing.test.ts +174 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +4 -1
- package/src/__tests__/conversation-process-callsite.test.ts +3 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +16 -7
- package/src/__tests__/conversation-queue.test.ts +29 -14
- package/src/__tests__/conversation-routes-disk-view.test.ts +7 -6
- package/src/__tests__/conversation-runtime-assembly.test.ts +155 -110
- package/src/__tests__/conversation-runtime-workspace.test.ts +23 -38
- package/src/__tests__/conversation-seed-composer.test.ts +2 -2
- package/src/__tests__/conversation-slash-queue.test.ts +7 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +25 -2
- package/src/__tests__/conversation-speed-override.test.ts +6 -1
- package/src/__tests__/conversation-title-service.test.ts +116 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
- package/src/__tests__/conversation-usage.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +3 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -1
- package/src/__tests__/credential-health-service.test.ts +78 -9
- package/src/__tests__/credential-security-invariants.test.ts +2 -2
- package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
- package/src/__tests__/empty-response-pipeline.test.ts +305 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +3 -3
- package/src/__tests__/first-greeting.test.ts +247 -5
- package/src/__tests__/headless-browser-mode.test.ts +57 -0
- package/src/__tests__/history-repair-pipeline.test.ts +399 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
- package/src/__tests__/host-proxy-interface.test.ts +36 -2
- package/src/__tests__/image-credentials.test.ts +137 -0
- package/src/__tests__/image-service-dispatcher.test.ts +186 -0
- package/src/__tests__/injector-chain.test.ts +526 -0
- package/src/__tests__/intent-routing.test.ts +0 -26
- package/src/__tests__/llm-call-pipeline.test.ts +285 -0
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/media-generate-image.test.ts +119 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
- package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +5 -68
- package/src/__tests__/model-intents.test.ts +4 -2
- package/src/__tests__/notification-broadcaster.test.ts +3 -3
- package/src/__tests__/notification-decision-strategy.test.ts +0 -11
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +14 -12
- package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
- package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
- package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
- package/src/__tests__/oauth-providers-routes.test.ts +3 -2
- package/src/__tests__/oauth-store.test.ts +41 -76
- package/src/__tests__/onboarding-template-contract.test.ts +16 -64
- package/src/__tests__/openai-image-service.test.ts +368 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +0 -24
- package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
- package/src/__tests__/persistence-pipeline.test.ts +377 -0
- package/src/__tests__/pipeline-runner.test.ts +565 -0
- package/src/__tests__/platform.test.ts +5 -2
- package/src/__tests__/plugin-bootstrap.test.ts +483 -0
- package/src/__tests__/plugin-registry.test.ts +273 -0
- package/src/__tests__/plugin-route-contribution.test.ts +288 -0
- package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
- package/src/__tests__/plugin-types.test.ts +320 -0
- package/src/__tests__/pricing.test.ts +44 -12
- package/src/__tests__/proxy-approval-callback.test.ts +69 -8
- package/src/__tests__/reaction-persistence.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +0 -2
- package/src/__tests__/schedule-routes.test.ts +131 -1
- package/src/__tests__/scheduler-recurrence.test.ts +14 -70
- package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
- package/src/__tests__/secret-detection-handler.test.ts +0 -10
- package/src/__tests__/shell-identity.test.ts +0 -134
- package/src/__tests__/suggestion-routes.test.ts +103 -4
- package/src/__tests__/task-memory-cleanup.test.ts +1 -0
- package/src/__tests__/task-scheduler.test.ts +3 -15
- package/src/__tests__/test-preload.ts +11 -0
- package/src/__tests__/title-generate-pipeline.test.ts +224 -0
- package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
- package/src/__tests__/tool-error-pipeline.test.ts +244 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -6
- package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
- package/src/__tests__/tool-executor.test.ts +141 -0
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -110
- package/src/__tests__/user-plugin-loader.test.ts +191 -0
- package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
- package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
- package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
- package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
- package/src/__tests__/workspace-policy.test.ts +21 -3
- package/src/agent/loop.ts +340 -102
- package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
- package/src/approvals/guardian-request-resolvers.ts +80 -0
- package/src/backup/__tests__/backup-worker.test.ts +2 -13
- package/src/backup/backup-worker.ts +3 -15
- package/src/bundler/app-compiler.ts +84 -1
- package/src/calls/call-state.ts +2 -2
- package/src/channels/__tests__/types.test.ts +3 -3
- package/src/channels/types.ts +6 -4
- package/src/cli/__tests__/notifications.test.ts +87 -211
- package/src/cli/commands/__tests__/backup.test.ts +1 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +255 -35
- package/src/cli/commands/__tests__/inference-send.test.ts +12 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +12 -0
- package/src/cli/commands/backup.ts +2 -2
- package/src/cli/commands/clients.ts +138 -0
- package/src/cli/commands/completions.ts +2 -9
- package/src/cli/commands/conversations.ts +55 -7
- package/src/cli/commands/image-generation.ts +33 -34
- package/src/cli/commands/notifications.ts +68 -103
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +2 -2
- package/src/cli/commands/oauth/providers.ts +176 -8
- package/src/cli/commands/oauth/status.ts +46 -36
- package/src/cli/commands/skills.ts +3 -4
- package/src/cli/program.ts +25 -29
- package/src/config/__tests__/backup-schema.test.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +12 -0
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +58 -0
- package/src/config/bundled-skills/schedule/SKILL.md +8 -3
- package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
- package/src/config/bundled-tool-registry.ts +0 -15
- package/src/config/feature-flag-registry.json +17 -1
- package/src/config/schema.ts +19 -0
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/conversations.ts +16 -0
- package/src/config/schemas/llm.ts +2 -3
- package/src/config/schemas/security.ts +6 -6
- package/src/config/schemas/tts.ts +11 -0
- package/src/config/skill-state.ts +6 -2
- package/src/config/skills.ts +94 -5
- package/src/context/__tests__/compact-prompt.test.ts +27 -9
- package/src/context/prompts/compact.md +26 -12
- package/src/context/tool-result-truncation.ts +3 -63
- package/src/context/window-manager.ts +190 -16
- package/src/credential-health/credential-health-service.ts +19 -6
- package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
- package/src/daemon/config-watcher.ts +0 -2
- package/src/daemon/context-overflow-policy.ts +4 -13
- package/src/daemon/conversation-agent-loop-handlers.ts +83 -22
- package/src/daemon/conversation-agent-loop.ts +984 -683
- package/src/daemon/conversation-history.ts +10 -19
- package/src/daemon/conversation-lifecycle.ts +37 -19
- package/src/daemon/conversation-notifiers.ts +2 -110
- package/src/daemon/conversation-process.ts +14 -7
- package/src/daemon/conversation-runtime-assembly.ts +532 -411
- package/src/daemon/conversation-tool-setup.ts +41 -4
- package/src/daemon/conversation.ts +80 -35
- package/src/daemon/external-plugins-bootstrap.ts +478 -0
- package/src/daemon/first-greeting.ts +191 -14
- package/src/daemon/handlers/config-model.ts +11 -0
- package/src/daemon/handlers/skills.ts +5 -1
- package/src/daemon/lifecycle.ts +33 -68
- package/src/daemon/message-types/computer-use.ts +2 -34
- package/src/daemon/message-types/conversations.ts +49 -0
- package/src/daemon/message-types/messages.ts +12 -0
- package/src/daemon/server.ts +5 -3
- package/src/daemon/shutdown-handlers.ts +2 -12
- package/src/daemon/tool-side-effects.ts +14 -56
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
- package/src/heartbeat/heartbeat-service.ts +24 -1
- package/src/home/__tests__/feed-population-integration.test.ts +312 -0
- package/src/home/emit-feed-event.ts +7 -0
- package/src/home/feed-types.ts +41 -2
- package/src/home/rewrite-command-preview.ts +66 -0
- package/src/ipc/__tests__/socket-path.test.ts +11 -50
- package/src/ipc/cli-client.ts +1 -1
- package/src/ipc/cli-server.ts +3 -3
- package/src/ipc/gateway-client.ts +4 -1
- package/src/ipc/routes/browser-context.ts +2 -0
- package/src/ipc/routes/browser.ts +1 -0
- package/src/ipc/routes/get-contact.ts +16 -0
- package/src/ipc/routes/index.ts +14 -0
- package/src/ipc/routes/list-clients.ts +31 -0
- package/src/ipc/routes/merge-contacts.ts +17 -0
- package/src/ipc/routes/notification.ts +133 -0
- package/src/ipc/routes/rename-conversation.ts +59 -0
- package/src/ipc/routes/search-contacts.ts +19 -0
- package/src/ipc/routes/upsert-contact.ts +25 -0
- package/src/ipc/socket-path.ts +14 -38
- package/src/media/app-icon-generator.ts +23 -46
- package/src/media/avatar-router.ts +26 -41
- package/src/media/gemini-image-service.ts +8 -41
- package/src/media/image-credentials.ts +73 -0
- package/src/media/image-service.ts +85 -0
- package/src/media/openai-image-service.ts +131 -0
- package/src/media/types.ts +46 -0
- package/src/memory/conversation-crud.ts +48 -18
- package/src/memory/conversation-queries.ts +57 -4
- package/src/memory/conversation-title-service.ts +25 -0
- package/src/memory/db-init.ts +8 -0
- package/src/memory/embedding-gemini.test.ts +41 -2
- package/src/memory/embedding-gemini.ts +6 -1
- package/src/memory/graph/bootstrap.test.ts +282 -0
- package/src/memory/graph/bootstrap.ts +8 -5
- package/src/memory/graph/extraction.ts +10 -2
- package/src/memory/graph/graph-search.test.ts +1 -0
- package/src/memory/graph/inspect.ts +2 -2
- package/src/memory/graph/retriever.ts +10 -3
- package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
- package/src/memory/migrations/149-oauth-tables.ts +1 -0
- package/src/memory/migrations/223-schedule-script-column.ts +11 -0
- package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
- package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/pkb/pkb-index.test.ts +1 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +1 -0
- package/src/memory/pkb/pkb-search.test.ts +65 -4
- package/src/memory/pkb/pkb-search.ts +40 -18
- package/src/memory/qdrant-client.test.ts +60 -0
- package/src/memory/qdrant-client.ts +25 -0
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/schema/oauth.ts +4 -1
- package/src/messaging/providers/slack/render-transcript.test.ts +77 -29
- package/src/messaging/providers/slack/render-transcript.ts +58 -0
- package/src/notifications/conversation-pairing.ts +78 -19
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/signal.ts +1 -2
- package/src/oauth/AGENTS.md +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
- package/src/oauth/connect-orchestrator.ts +8 -34
- package/src/oauth/connect-types.ts +6 -10
- package/src/oauth/manual-token-connection.ts +23 -0
- package/src/oauth/oauth-store.ts +30 -14
- package/src/oauth/provider-serializer.ts +6 -1
- package/src/oauth/seed-providers.ts +56 -108
- package/src/outbound-proxy/http-forwarder.ts +9 -0
- package/src/permissions/approval-policy.test.ts +293 -18
- package/src/permissions/approval-policy.ts +110 -58
- package/src/permissions/arg-parser.test.ts +161 -0
- package/src/permissions/arg-parser.ts +141 -0
- package/src/permissions/bash-risk-classifier.test.ts +414 -2
- package/src/permissions/bash-risk-classifier.ts +303 -60
- package/src/permissions/checker.ts +157 -29
- package/src/permissions/command-registry.test.ts +239 -0
- package/src/permissions/command-registry.ts +234 -54
- package/src/permissions/defaults.ts +5 -4
- package/src/permissions/gateway-threshold-reader.ts +196 -0
- package/src/permissions/prompter.ts +4 -0
- package/src/permissions/risk-types.ts +61 -4
- package/src/permissions/schedule-risk-classifier.test.ts +129 -0
- package/src/permissions/schedule-risk-classifier.ts +85 -0
- package/src/permissions/shell-identity.ts +2 -42
- package/src/permissions/types.ts +2 -0
- package/src/permissions/workspace-policy.ts +8 -3
- package/src/plugins/defaults/circuit-breaker.ts +146 -0
- package/src/plugins/defaults/compaction.ts +145 -0
- package/src/plugins/defaults/empty-response.ts +126 -0
- package/src/plugins/defaults/history-repair.ts +85 -0
- package/src/plugins/defaults/index.ts +116 -0
- package/src/plugins/defaults/injectors.ts +491 -0
- package/src/plugins/defaults/llm-call.ts +82 -0
- package/src/plugins/defaults/memory-retrieval.ts +226 -0
- package/src/plugins/defaults/overflow-reduce.ts +181 -0
- package/src/plugins/defaults/persistence.ts +129 -0
- package/src/plugins/defaults/title-generate.ts +95 -0
- package/src/plugins/defaults/token-estimate.ts +104 -0
- package/src/plugins/defaults/tool-error.ts +126 -0
- package/src/plugins/defaults/tool-execute.ts +89 -0
- package/src/plugins/defaults/tool-result-truncate.ts +88 -0
- package/src/plugins/pipeline.ts +316 -0
- package/src/plugins/plugin-skill-contributions.ts +292 -0
- package/src/plugins/registry.ts +241 -0
- package/src/plugins/types.ts +1134 -0
- package/src/plugins/user-loader.ts +177 -0
- package/src/prompts/templates/BOOTSTRAP.md +27 -77
- package/src/providers/model-catalog.ts +52 -29
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +72 -4
- package/src/providers/speech-to-text/xai-realtime.ts +39 -14
- package/src/runtime/AGENTS.md +25 -16
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
- package/src/runtime/__tests__/client-registry.test.ts +293 -0
- package/src/runtime/client-registry.ts +261 -0
- package/src/runtime/http-server.ts +77 -8
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +1 -22
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +51 -31
- package/src/runtime/routes/approval-routes.ts +17 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
- package/src/runtime/routes/conversation-routes.ts +223 -116
- package/src/runtime/routes/inbound-message-handler.ts +88 -13
- package/src/runtime/routes/memory-item-routes.test.ts +1 -0
- package/src/runtime/routes/migration-routes.ts +0 -3
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
- package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
- package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
- package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
- package/src/runtime/routes/playground/deps.ts +56 -0
- package/src/runtime/routes/playground/force-compact.ts +73 -0
- package/src/runtime/routes/playground/guard.ts +37 -0
- package/src/runtime/routes/playground/index.ts +28 -0
- package/src/runtime/routes/playground/inject-failures.ts +159 -0
- package/src/runtime/routes/playground/reset-circuit.ts +115 -0
- package/src/runtime/routes/playground/seed-conversation.ts +139 -0
- package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
- package/src/runtime/routes/playground/state.ts +78 -0
- package/src/runtime/routes/schedule-routes.ts +89 -8
- package/src/runtime/skill-route-registry.ts +75 -15
- package/src/schedule/run-script.ts +68 -0
- package/src/schedule/schedule-store.ts +7 -1
- package/src/schedule/scheduler.ts +48 -8
- package/src/skills/catalog-cache.ts +12 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +189 -0
- package/src/tools/browser/browser-execution.ts +88 -19
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
- package/src/tools/browser/cdp-client/factory.ts +15 -4
- package/src/tools/executor.ts +126 -74
- package/src/tools/network/script-proxy/session-manager.ts +37 -1
- package/src/tools/permission-checker.ts +98 -49
- package/src/tools/policy-context.ts +4 -0
- package/src/tools/registry.ts +140 -3
- package/src/tools/schedule/create.ts +23 -8
- package/src/tools/schedule/update.ts +3 -1
- package/src/tools/secret-detection-handler.ts +0 -51
- package/src/tools/system/avatar-generator.ts +6 -2
- package/src/tools/types.ts +28 -2
- package/src/util/platform.ts +7 -2
- package/src/util/pricing.ts +26 -3
- package/src/workspace/migrations/006-services-config.ts +2 -4
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +3 -4
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
- package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
- package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
- package/src/workspace/migrations/registry.ts +12 -0
- package/tsconfig.json +1 -1
- package/hook-templates/debug-prompt-logger/hook.json +0 -7
- package/hook-templates/debug-prompt-logger/run.sh +0 -66
- package/src/__tests__/compaction-circuit-breaker.test.ts +0 -336
- package/src/__tests__/context-overflow-approval.test.ts +0 -156
- package/src/__tests__/hooks-blocking.test.ts +0 -178
- package/src/__tests__/hooks-cli.test.ts +0 -182
- package/src/__tests__/hooks-config.test.ts +0 -108
- package/src/__tests__/hooks-discovery.test.ts +0 -211
- package/src/__tests__/hooks-integration.test.ts +0 -196
- package/src/__tests__/hooks-manager.test.ts +0 -226
- package/src/__tests__/hooks-runner.test.ts +0 -175
- package/src/__tests__/hooks-settings.test.ts +0 -160
- package/src/__tests__/hooks-templates.test.ts +0 -169
- package/src/__tests__/hooks-ts-runner.test.ts +0 -170
- package/src/__tests__/hooks-watch.test.ts +0 -112
- package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
- package/src/__tests__/oauth-scope-policy.test.ts +0 -180
- package/src/__tests__/send-notification-tool.test.ts +0 -83
- package/src/cli/commands/shotgun.ts +0 -266
- package/src/config/bundled-skills/conversations/SKILL.md +0 -20
- package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -88
- package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
- package/src/config/bundled-skills/notifications/SKILL.md +0 -40
- package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
- package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
- package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
- package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
- package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
- package/src/daemon/context-overflow-approval.ts +0 -52
- package/src/daemon/watch-handler.ts +0 -399
- package/src/hooks/cli.ts +0 -253
- package/src/hooks/config.ts +0 -100
- package/src/hooks/discovery.ts +0 -135
- package/src/hooks/manager.ts +0 -179
- package/src/hooks/runner.ts +0 -117
- package/src/hooks/templates.ts +0 -77
- package/src/hooks/types.ts +0 -75
- package/src/oauth/scope-policy.ts +0 -89
- package/src/runtime/gateway-internal-client.ts +0 -94
- package/src/runtime/routes/watch-routes.ts +0 -156
- package/src/signals/shotgun.ts +0 -203
- package/src/tools/watch/screen-watch.ts +0 -144
- package/src/tools/watch/watch-state.ts +0 -142
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
3
|
-
existsSync,
|
|
4
|
-
mkdirSync,
|
|
5
|
-
readFileSync,
|
|
6
|
-
unlinkSync,
|
|
7
|
-
writeFileSync,
|
|
8
|
-
} from "node:fs";
|
|
9
|
-
import { join } from "node:path";
|
|
10
|
-
|
|
11
|
-
import type { Command } from "commander";
|
|
12
|
-
|
|
13
|
-
import { getSignalsDir } from "../../util/platform.js";
|
|
14
|
-
import { log } from "../logger.js";
|
|
15
|
-
|
|
16
|
-
const POLL_INTERVAL_MS = 100;
|
|
17
|
-
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
18
|
-
|
|
19
|
-
interface ShotgunResult {
|
|
20
|
-
requestId: string;
|
|
21
|
-
ok: boolean;
|
|
22
|
-
error?: string;
|
|
23
|
-
watchId?: string;
|
|
24
|
-
conversationId?: string;
|
|
25
|
-
status?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function writeShotgunSignal(
|
|
29
|
-
requestId: string,
|
|
30
|
-
payload: Record<string, unknown>,
|
|
31
|
-
): { signalPath: string; resultPath: string } | null {
|
|
32
|
-
const signalsDir = getSignalsDir();
|
|
33
|
-
try {
|
|
34
|
-
mkdirSync(signalsDir, { recursive: true });
|
|
35
|
-
} catch {
|
|
36
|
-
log.error("Failed to create signals directory.");
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const signalPath = join(signalsDir, `shotgun.${requestId}`);
|
|
41
|
-
const resultPath = join(signalsDir, `shotgun.${requestId}.result`);
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
writeFileSync(signalPath, JSON.stringify({ requestId, ...payload }));
|
|
45
|
-
} catch {
|
|
46
|
-
log.error("Failed to write shotgun signal file.");
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return { signalPath, resultPath };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function pollForResult(
|
|
54
|
-
requestId: string,
|
|
55
|
-
resultPath: string,
|
|
56
|
-
signalPath: string,
|
|
57
|
-
timeoutMs: number,
|
|
58
|
-
callback: (result: ShotgunResult) => void,
|
|
59
|
-
): void {
|
|
60
|
-
const deadline = Date.now() + timeoutMs + 5_000;
|
|
61
|
-
|
|
62
|
-
const poll = setInterval(() => {
|
|
63
|
-
if (Date.now() > deadline) {
|
|
64
|
-
clearInterval(poll);
|
|
65
|
-
cleanup(signalPath, resultPath);
|
|
66
|
-
log.error("Timed out waiting for response. Is the assistant running?");
|
|
67
|
-
process.exitCode = 1;
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!existsSync(resultPath)) return;
|
|
72
|
-
|
|
73
|
-
let result: ShotgunResult;
|
|
74
|
-
try {
|
|
75
|
-
const content = readFileSync(resultPath, "utf-8");
|
|
76
|
-
result = JSON.parse(content) as ShotgunResult;
|
|
77
|
-
} catch {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (result.requestId !== requestId) return;
|
|
82
|
-
|
|
83
|
-
clearInterval(poll);
|
|
84
|
-
cleanup(signalPath, resultPath);
|
|
85
|
-
callback(result);
|
|
86
|
-
}, POLL_INTERVAL_MS);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function cleanup(...paths: string[]): void {
|
|
90
|
-
for (const p of paths) {
|
|
91
|
-
try {
|
|
92
|
-
unlinkSync(p);
|
|
93
|
-
} catch {
|
|
94
|
-
// Best-effort cleanup.
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function registerShotgunCommand(program: Command): void {
|
|
100
|
-
const shotgun = program
|
|
101
|
-
.command("shotgun")
|
|
102
|
-
.description("Start and monitor screen-watch (shotgun) sessions via IPC");
|
|
103
|
-
|
|
104
|
-
shotgun.addHelpText(
|
|
105
|
-
"after",
|
|
106
|
-
`
|
|
107
|
-
Screen-watch sessions capture periodic screenshots and feed them to the
|
|
108
|
-
assistant for observation. The CLI communicates with the running assistant
|
|
109
|
-
via IPC signal files — the assistant must be running for these commands
|
|
110
|
-
to work.
|
|
111
|
-
|
|
112
|
-
Examples:
|
|
113
|
-
$ assistant shotgun start --duration 600 --focus "browsing workflow"
|
|
114
|
-
$ assistant shotgun status <watchId>`,
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
shotgun
|
|
118
|
-
.command("start")
|
|
119
|
-
.description("Start a new screen-watch session")
|
|
120
|
-
.option(
|
|
121
|
-
"-d, --duration <seconds>",
|
|
122
|
-
"Duration in seconds for the watch session",
|
|
123
|
-
"300",
|
|
124
|
-
)
|
|
125
|
-
.option("-i, --interval <seconds>", "Seconds between screen captures", "5")
|
|
126
|
-
.option(
|
|
127
|
-
"-f, --focus <area>",
|
|
128
|
-
"What to focus on observing",
|
|
129
|
-
"general observation",
|
|
130
|
-
)
|
|
131
|
-
.option(
|
|
132
|
-
"-t, --timeout <ms>",
|
|
133
|
-
"Timeout in milliseconds waiting for the assistant to respond",
|
|
134
|
-
String(DEFAULT_TIMEOUT_MS),
|
|
135
|
-
)
|
|
136
|
-
.addHelpText(
|
|
137
|
-
"after",
|
|
138
|
-
`
|
|
139
|
-
Starts a screen-watch session via IPC signal files. The assistant
|
|
140
|
-
creates a watch session and begins accepting screen observations from the
|
|
141
|
-
desktop client.
|
|
142
|
-
|
|
143
|
-
The CLI writes the request to signals/shotgun.<requestId> and polls
|
|
144
|
-
signals/shotgun.<requestId>.result for the response. The assistant must
|
|
145
|
-
be running for this to work.
|
|
146
|
-
|
|
147
|
-
Output (JSON): { ok, watchId, conversationId }
|
|
148
|
-
|
|
149
|
-
Examples:
|
|
150
|
-
$ assistant shotgun start
|
|
151
|
-
$ assistant shotgun start --duration 600 --interval 10 --focus "doordash.com"
|
|
152
|
-
$ assistant shotgun start -d 300 -i 5 -f "browsing workflow"`,
|
|
153
|
-
)
|
|
154
|
-
.action(
|
|
155
|
-
(opts: {
|
|
156
|
-
duration: string;
|
|
157
|
-
interval: string;
|
|
158
|
-
focus: string;
|
|
159
|
-
timeout: string;
|
|
160
|
-
}) => {
|
|
161
|
-
const durationSeconds = parseInt(opts.duration, 10);
|
|
162
|
-
if (!Number.isFinite(durationSeconds) || durationSeconds < 1) {
|
|
163
|
-
log.error("Invalid duration. Must be a positive integer.");
|
|
164
|
-
process.exitCode = 1;
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const intervalSeconds = parseInt(opts.interval, 10);
|
|
169
|
-
if (!Number.isFinite(intervalSeconds) || intervalSeconds < 1) {
|
|
170
|
-
log.error("Invalid interval. Must be a positive integer.");
|
|
171
|
-
process.exitCode = 1;
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const timeoutMs = parseInt(opts.timeout, 10);
|
|
176
|
-
if (!Number.isFinite(timeoutMs) || timeoutMs < 1) {
|
|
177
|
-
log.error("Invalid timeout. Must be a positive integer.");
|
|
178
|
-
process.exitCode = 1;
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const requestId = randomUUID();
|
|
183
|
-
const paths = writeShotgunSignal(requestId, {
|
|
184
|
-
action: "start",
|
|
185
|
-
durationSeconds,
|
|
186
|
-
intervalSeconds,
|
|
187
|
-
focusArea: opts.focus,
|
|
188
|
-
});
|
|
189
|
-
if (!paths) {
|
|
190
|
-
process.exitCode = 1;
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
pollForResult(
|
|
195
|
-
requestId,
|
|
196
|
-
paths.resultPath,
|
|
197
|
-
paths.signalPath,
|
|
198
|
-
timeoutMs,
|
|
199
|
-
(result) => {
|
|
200
|
-
if (!result.ok) {
|
|
201
|
-
process.stdout.write(JSON.stringify(result) + "\n");
|
|
202
|
-
process.exitCode = 1;
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
process.stdout.write(JSON.stringify(result) + "\n");
|
|
206
|
-
},
|
|
207
|
-
);
|
|
208
|
-
},
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
shotgun
|
|
212
|
-
.command("status <watchId>")
|
|
213
|
-
.description("Check the status of an active screen-watch session")
|
|
214
|
-
.option(
|
|
215
|
-
"-t, --timeout <ms>",
|
|
216
|
-
"Timeout in milliseconds waiting for the assistant to respond",
|
|
217
|
-
String(DEFAULT_TIMEOUT_MS),
|
|
218
|
-
)
|
|
219
|
-
.addHelpText(
|
|
220
|
-
"after",
|
|
221
|
-
`
|
|
222
|
-
Arguments:
|
|
223
|
-
watchId The watch session ID returned by 'assistant shotgun start'.
|
|
224
|
-
|
|
225
|
-
Queries the status of an existing screen-watch session by watchId.
|
|
226
|
-
|
|
227
|
-
Output (JSON): { ok, watchId, conversationId, status }
|
|
228
|
-
|
|
229
|
-
The status field is one of: "active", "completing", "completed", "cancelled".
|
|
230
|
-
|
|
231
|
-
Examples:
|
|
232
|
-
$ assistant shotgun status abc12345
|
|
233
|
-
$ assistant shotgun status abc12345 --timeout 5000`,
|
|
234
|
-
)
|
|
235
|
-
.action((watchId: string, opts: { timeout: string }) => {
|
|
236
|
-
const timeoutMs = parseInt(opts.timeout, 10);
|
|
237
|
-
if (!Number.isFinite(timeoutMs) || timeoutMs < 1) {
|
|
238
|
-
log.error("Invalid timeout. Must be a positive integer.");
|
|
239
|
-
process.exitCode = 1;
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const requestId = randomUUID();
|
|
244
|
-
const paths = writeShotgunSignal(requestId, {
|
|
245
|
-
action: "status",
|
|
246
|
-
watchId,
|
|
247
|
-
});
|
|
248
|
-
if (!paths) {
|
|
249
|
-
process.exitCode = 1;
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
pollForResult(
|
|
254
|
-
requestId,
|
|
255
|
-
paths.resultPath,
|
|
256
|
-
paths.signalPath,
|
|
257
|
-
timeoutMs,
|
|
258
|
-
(result) => {
|
|
259
|
-
process.stdout.write(JSON.stringify(result) + "\n");
|
|
260
|
-
if (!result.ok) {
|
|
261
|
-
process.exitCode = 1;
|
|
262
|
-
}
|
|
263
|
-
},
|
|
264
|
-
);
|
|
265
|
-
});
|
|
266
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: conversations
|
|
3
|
-
description: Manage conversation threads (rename)
|
|
4
|
-
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
6
|
-
emoji: "\U0001F4AC"
|
|
7
|
-
vellum:
|
|
8
|
-
display-name: "Conversations"
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
Tools for managing conversation threads.
|
|
12
|
-
|
|
13
|
-
## Renaming
|
|
14
|
-
|
|
15
|
-
Use the `rename_conversation` tool to rename the current conversation thread when:
|
|
16
|
-
- The topic has shifted significantly from the original title
|
|
17
|
-
- The auto-generated title is generic or unhelpful
|
|
18
|
-
- The user explicitly asks to rename the thread
|
|
19
|
-
|
|
20
|
-
Keep titles concise (under 60 characters) and descriptive of the current topic.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 1,
|
|
3
|
-
"tools": [
|
|
4
|
-
{
|
|
5
|
-
"name": "rename_conversation",
|
|
6
|
-
"description": "Rename the current conversation thread. Use this when the conversation topic has shifted significantly from the original title, or when you notice the title is generic/unhelpful and you can provide a better one based on what has been discussed.",
|
|
7
|
-
"category": "conversation",
|
|
8
|
-
"risk": "low",
|
|
9
|
-
"input_schema": {
|
|
10
|
-
"type": "object",
|
|
11
|
-
"properties": {
|
|
12
|
-
"title": {
|
|
13
|
-
"type": "string",
|
|
14
|
-
"description": "The new title for the conversation. Should be concise (under 60 characters) and descriptive of the current topic."
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"required": ["title"]
|
|
18
|
-
},
|
|
19
|
-
"executor": "tools/rename-conversation.ts",
|
|
20
|
-
"execution_target": "host"
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getConversation,
|
|
3
|
-
updateConversationTitle,
|
|
4
|
-
} from "../../../../memory/conversation-crud.js";
|
|
5
|
-
import { buildAssistantEvent } from "../../../../runtime/assistant-event.js";
|
|
6
|
-
import { assistantEventHub } from "../../../../runtime/assistant-event-hub.js";
|
|
7
|
-
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../../../../runtime/assistant-scope.js";
|
|
8
|
-
import type {
|
|
9
|
-
ToolContext,
|
|
10
|
-
ToolExecutionResult,
|
|
11
|
-
} from "../../../../tools/types.js";
|
|
12
|
-
import { getLogger } from "../../../../util/logger.js";
|
|
13
|
-
|
|
14
|
-
const log = getLogger("rename-conversation");
|
|
15
|
-
|
|
16
|
-
export async function run(
|
|
17
|
-
input: Record<string, unknown>,
|
|
18
|
-
context: ToolContext,
|
|
19
|
-
): Promise<ToolExecutionResult> {
|
|
20
|
-
const title = input.title;
|
|
21
|
-
if (typeof title !== "string" || title.trim() === "") {
|
|
22
|
-
return {
|
|
23
|
-
content: "Error: title must be a non-empty string.",
|
|
24
|
-
isError: true,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const trimmedTitle = title.trim();
|
|
29
|
-
const conversationId = context.conversationId;
|
|
30
|
-
|
|
31
|
-
const conversation = getConversation(conversationId);
|
|
32
|
-
if (!conversation) {
|
|
33
|
-
return {
|
|
34
|
-
content: `Error: conversation ${conversationId} not found.`,
|
|
35
|
-
isError: true,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Persist with isAutoTitle = 0 so auto-generation won't overwrite it
|
|
40
|
-
updateConversationTitle(conversationId, trimmedTitle, 0);
|
|
41
|
-
|
|
42
|
-
// Notify the client currently viewing this conversation so the header
|
|
43
|
-
// updates in-place. Scoped to this conversation so foreign
|
|
44
|
-
// `conversationId` values don't leak to other subscribers' speculative
|
|
45
|
-
// ID-resolution paths. Other clients learn about the rename via the
|
|
46
|
-
// unscoped `conversation_list_invalidated` published below, which
|
|
47
|
-
// triggers their sidebars to refetch and pick up the new title.
|
|
48
|
-
const assistantId = context.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID;
|
|
49
|
-
assistantEventHub
|
|
50
|
-
.publish(
|
|
51
|
-
buildAssistantEvent(
|
|
52
|
-
assistantId,
|
|
53
|
-
{
|
|
54
|
-
type: "conversation_title_updated",
|
|
55
|
-
conversationId,
|
|
56
|
-
title: trimmedTitle,
|
|
57
|
-
},
|
|
58
|
-
conversationId,
|
|
59
|
-
),
|
|
60
|
-
)
|
|
61
|
-
.catch((err) => {
|
|
62
|
-
log.warn({ err }, "Failed to publish conversation_title_updated event");
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Broadcast `conversation_list_invalidated` unscoped so every connected
|
|
66
|
-
// client's sidebar refetches and picks up the renamed title. Mirrors
|
|
67
|
-
// the HTTP rename route in `conversation-management-routes.ts`.
|
|
68
|
-
assistantEventHub
|
|
69
|
-
.publish(
|
|
70
|
-
buildAssistantEvent(assistantId, {
|
|
71
|
-
type: "conversation_list_invalidated",
|
|
72
|
-
reason: "renamed",
|
|
73
|
-
}),
|
|
74
|
-
)
|
|
75
|
-
.catch((err) => {
|
|
76
|
-
log.warn(
|
|
77
|
-
{ err },
|
|
78
|
-
"Failed to publish conversation_list_invalidated for rename",
|
|
79
|
-
);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
log.info({ conversationId, title: trimmedTitle }, "Conversation renamed");
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
content: `Conversation renamed to "${trimmedTitle}".`,
|
|
86
|
-
isError: false,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: heartbeat
|
|
3
|
-
description: Configure periodic background checklist runs
|
|
4
|
-
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
6
|
-
emoji: "\U0001F493"
|
|
7
|
-
vellum:
|
|
8
|
-
display-name: "Heartbeat"
|
|
9
|
-
activation-hints:
|
|
10
|
-
- "Set up a heartbeat, periodic checklist, background health check, or recurring background task"
|
|
11
|
-
avoid-when:
|
|
12
|
-
- "One-off or recurring schedules with specific payloads - use the schedule skill instead"
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
The heartbeat feature runs your `HEARTBEAT.md` checklist periodically in a background conversation. Each run, the assistant works through the checklist and flags anything that needs attention.
|
|
16
|
-
|
|
17
|
-
## Setup
|
|
18
|
-
|
|
19
|
-
Edit `config.json` using `file_edit`:
|
|
20
|
-
|
|
21
|
-
1. **Enable heartbeat**: Set `heartbeat.enabled` to `true`.
|
|
22
|
-
2. **Set interval**: Set `heartbeat.intervalMs` (milliseconds between runs, default: 3600000 = 1 hour).
|
|
23
|
-
3. **Optional active hours**: Set `heartbeat.activeHoursStart` and `heartbeat.activeHoursEnd` (0-23) to restrict runs to certain hours. Both must be set together.
|
|
24
|
-
|
|
25
|
-
Example config.json heartbeat section:
|
|
26
|
-
```json
|
|
27
|
-
{
|
|
28
|
-
"heartbeat": {
|
|
29
|
-
"enabled": true,
|
|
30
|
-
"intervalMs": 1800000,
|
|
31
|
-
"activeHoursStart": 8,
|
|
32
|
-
"activeHoursEnd": 22
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Then edit `HEARTBEAT.md` with the checklist items. The assistant will work through this file each heartbeat run.
|
|
38
|
-
|
|
39
|
-
## Notes
|
|
40
|
-
|
|
41
|
-
- Toggling `heartbeat.enabled` requires an assistant restart to take effect.
|
|
42
|
-
- Changes to `HEARTBEAT.md` take effect on the next heartbeat run (no restart needed).
|
|
43
|
-
- The heartbeat runs in a separate background conversation, not the user's active chat.
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: notifications
|
|
3
|
-
description: Send notifications through the unified notification router
|
|
4
|
-
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
6
|
-
emoji: "🔔"
|
|
7
|
-
vellum:
|
|
8
|
-
display-name: "Notifications"
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
Use `send_notification` for user-facing alerts and notifications. This tool routes through the unified notification pipeline, which handles channel selection, delivery, deduplication, and audit logging.
|
|
12
|
-
|
|
13
|
-
## Routing Behavior
|
|
14
|
-
|
|
15
|
-
- `preferred_channels` are **routing hints**, not hard channel forcing. The notification router makes the final delivery decision based on user preferences, channel availability, and urgency.
|
|
16
|
-
- Channel selection and delivery are handled entirely by the notification router -- do not attempt to control delivery manually.
|
|
17
|
-
|
|
18
|
-
## Deduplication (`dedupe_key`)
|
|
19
|
-
|
|
20
|
-
- `dedupe_key` suppresses duplicate signals **permanently**. A second notification with the same key is **dropped entirely** for the lifetime of the assistant's event store. Once a key has been used, it cannot be reused - any future notification with the same key will be silently discarded.
|
|
21
|
-
- Never reuse a `dedupe_key` across logically distinct notifications, even if they are related. The key means "this exact event already fired," not "these events are in the same category."
|
|
22
|
-
- If you omit `dedupe_key`, the LLM decision engine may generate one automatically based on signal context. This means even keyless signals can be deduplicated if the engine considers them duplicates of a recent event.
|
|
23
|
-
|
|
24
|
-
## Conversation Grouping
|
|
25
|
-
|
|
26
|
-
Conversation grouping is handled by the LLM-powered decision engine, not by any parameter you pass. There is no explicit "post to conversation X" parameter - conversation reuse is inferred, not commanded.
|
|
27
|
-
|
|
28
|
-
**How it works:** The engine evaluates recent notification conversation candidates and decides whether a new signal is a continuation of an existing conversation based on `source_event_name`, provenance metadata, and message content. Use natural, descriptive titles and bodies - the engine groups by semantic relatedness, not string matching.
|
|
29
|
-
|
|
30
|
-
**`source_event_name` is the primary grouping signal.** Use a stable event name for notifications that belong to the same logical stream (e.g. `dog.news.thread.reply` for all replies in a thread). Use a distinct event name when the notification represents a genuinely different kind of event.
|
|
31
|
-
|
|
32
|
-
**Practical constraints:**
|
|
33
|
-
|
|
34
|
-
- Conversation candidates are scoped to the **last 24 hours** (max 5 per channel). You cannot reuse an old conversation from days ago.
|
|
35
|
-
- The engine will only reuse conversations originally created by the notification system (`source === 'notification'`). It will never append to a user-initiated conversation, even if it looks related.
|
|
36
|
-
|
|
37
|
-
## Important
|
|
38
|
-
|
|
39
|
-
- Do **NOT** use AppleScript `display notification` or other OS-level notification commands for assistant-managed alerts. Always use `send_notification`.
|
|
40
|
-
- For sending rich content (digests, summaries, reports) to a specific chat or email destination, use the appropriate platform's API directly. For Gmail, use `messaging_send`. For Slack, use the Slack Web API directly (see the **slack** skill). The decision engine rewrites `send_notification` content into short alerts, which strips rich formatting.
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 1,
|
|
3
|
-
"tools": [
|
|
4
|
-
{
|
|
5
|
-
"name": "send_notification",
|
|
6
|
-
"description": "Send an immediate notification. Fires instantly with no delay capability. For one-time future alerts, use schedule_create with fire_at. For recurring alerts, use schedule_create with expression (cron/RRULE). The router decides channels/copy from preferences and urgency hints. Include a confidence score (0-1).",
|
|
7
|
-
"category": "notifications",
|
|
8
|
-
"risk": "medium",
|
|
9
|
-
"input_schema": {
|
|
10
|
-
"type": "object",
|
|
11
|
-
"properties": {
|
|
12
|
-
"message": {
|
|
13
|
-
"type": "string",
|
|
14
|
-
"description": "Notification message the user should receive"
|
|
15
|
-
},
|
|
16
|
-
"title": {
|
|
17
|
-
"type": "string",
|
|
18
|
-
"description": "Optional notification title"
|
|
19
|
-
},
|
|
20
|
-
"urgency": {
|
|
21
|
-
"type": "string",
|
|
22
|
-
"enum": ["low", "medium", "high"],
|
|
23
|
-
"description": "Urgency hint (default: \"medium\")"
|
|
24
|
-
},
|
|
25
|
-
"requires_action": {
|
|
26
|
-
"type": "boolean",
|
|
27
|
-
"description": "Whether the notification expects user action (default: true)"
|
|
28
|
-
},
|
|
29
|
-
"is_async_background": {
|
|
30
|
-
"type": "boolean",
|
|
31
|
-
"description": "Whether the event is asynchronous/background work (default: false)"
|
|
32
|
-
},
|
|
33
|
-
"visible_in_source_now": {
|
|
34
|
-
"type": "boolean",
|
|
35
|
-
"description": "Set true when user is already viewing the source context (default: false)"
|
|
36
|
-
},
|
|
37
|
-
"deadline_at": {
|
|
38
|
-
"type": "number",
|
|
39
|
-
"description": "Optional deadline timestamp in epoch milliseconds"
|
|
40
|
-
},
|
|
41
|
-
"preferred_channels": {
|
|
42
|
-
"type": "array",
|
|
43
|
-
"items": {
|
|
44
|
-
"type": "string",
|
|
45
|
-
"enum": ["vellum", "telegram", "slack"]
|
|
46
|
-
},
|
|
47
|
-
"description": "Optional routing hints for preferred channels (not deterministic)"
|
|
48
|
-
},
|
|
49
|
-
"conversation_id": {
|
|
50
|
-
"type": "string",
|
|
51
|
-
"description": "Optional source conversation ID for notification context"
|
|
52
|
-
},
|
|
53
|
-
"source_event_name": {
|
|
54
|
-
"type": "string",
|
|
55
|
-
"description": "Optional event name for audit and dedupe grouping (default: \"user.send_notification\")"
|
|
56
|
-
},
|
|
57
|
-
"deep_link_metadata": {
|
|
58
|
-
"type": "object",
|
|
59
|
-
"description": "Optional metadata clients can use for deep linking"
|
|
60
|
-
},
|
|
61
|
-
"dedupe_key": {
|
|
62
|
-
"type": "string",
|
|
63
|
-
"description": "Optional dedupe key to suppress duplicate notifications"
|
|
64
|
-
},
|
|
65
|
-
"confidence": {
|
|
66
|
-
"type": "number",
|
|
67
|
-
"description": "Confidence score (0-1) for this action"
|
|
68
|
-
},
|
|
69
|
-
"activity": {
|
|
70
|
-
"type": "string",
|
|
71
|
-
"description": "Brief non-technical explanation of why this tool is being called"
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
"required": ["message", "confidence"]
|
|
75
|
-
},
|
|
76
|
-
"executor": "tools/send-notification.ts",
|
|
77
|
-
"execution_target": "host"
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
}
|