@vellumai/assistant 0.8.12 → 0.9.0-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/AGENTS.md +0 -14
- package/ARCHITECTURE.md +45 -45
- package/README.md +1 -1
- package/bun.lock +200 -154
- package/docs/architecture/integrations.md +3 -3
- package/docs/architecture/memory.md +2 -2
- package/docs/architecture/security.md +10 -10
- package/docs/runbook-trusted-contacts.md +12 -12
- package/docs/skills.md +6 -6
- package/docs/workflows-testing.md +221 -0
- package/docs/workflows.md +510 -0
- package/examples/plugins/echo/README.md +5 -5
- package/knip.json +2 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +105 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +12 -0
- package/openapi.yaml +7197 -5708
- package/package.json +8 -4
- package/scripts/generate-openapi.ts +66 -114
- package/src/__tests__/access-request-seed-content-blocks.test.ts +213 -0
- package/src/__tests__/adaptive-thinking-repair.test.ts +32 -3
- package/src/__tests__/agent-loop-output-hooks.test.ts +183 -0
- package/src/__tests__/agent-loop-regrowth-guard.test.ts +506 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +77 -0
- package/src/__tests__/app-compiler.test.ts +7 -1
- package/src/__tests__/app-dir-path-guard.test.ts +27 -3
- package/src/__tests__/app-executors.test.ts +43 -0
- package/src/__tests__/approval-cascade.test.ts +0 -5
- package/src/__tests__/approval-routes-http.test.ts +91 -0
- package/src/__tests__/assistant-stream-state.test.ts +107 -0
- package/src/__tests__/browser-fill-credential.test.ts +3 -3
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +1 -1
- package/src/__tests__/compaction-events.test.ts +63 -7
- package/src/__tests__/compaction-trail-store.test.ts +74 -1
- package/src/__tests__/compaction.benchmark.test.ts +63 -41
- package/src/__tests__/compactor-low-watermark-cut.test.ts +349 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +64 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -5
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -5
- package/src/__tests__/conversation-history-web-search.test.ts +7 -0
- package/src/__tests__/conversation-process-callsite.test.ts +0 -5
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -5
- package/src/__tests__/conversation-queue.test.ts +0 -5
- package/src/__tests__/conversation-slash-queue.test.ts +0 -5
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -5
- package/src/__tests__/conversation-speed-override.test.ts +0 -5
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +97 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
- package/src/__tests__/conversation-usage.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -5
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -5
- package/src/__tests__/credential-broker-browser-fill.test.ts +2 -2
- package/src/__tests__/credential-broker-server-use.test.ts +2 -2
- package/src/__tests__/credential-broker.test.ts +1 -1
- package/src/__tests__/credential-prompt-route.test.ts +417 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/credential-vault.test.ts +37 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +24 -0
- package/src/__tests__/dynamic-page-surface.test.ts +219 -0
- package/src/__tests__/empty-state-greeting-cache.test.ts +94 -0
- package/src/__tests__/gateway-flag-listener.test.ts +24 -7
- package/src/__tests__/guardian-action-sweep.test.ts +56 -219
- package/src/__tests__/guardian-routing-invariants.test.ts +138 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
- package/src/__tests__/list-messages-hidden-metadata.test.ts +99 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +87 -1
- package/src/__tests__/llm-resolver.test.ts +115 -0
- package/src/__tests__/managed-profile-guard.test.ts +6 -5
- package/src/__tests__/max-tokens-continue-hook.test.ts +184 -0
- package/src/__tests__/media-generate-image.test.ts +20 -9
- package/src/__tests__/mock-gateway-ipc.ts +23 -0
- package/src/__tests__/model-intents.test.ts +1 -1
- package/src/__tests__/normalize-onboarding.test.ts +26 -0
- package/src/__tests__/notification-decision-strategy.test.ts +4 -2
- package/src/__tests__/notification-telegram-adapter.test.ts +21 -3
- package/src/__tests__/pending-interactions-resolved-event.test.ts +62 -0
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +72 -18
- package/src/__tests__/require-fresh-approval.test.ts +425 -1
- package/src/__tests__/resolve-app-id.test.ts +56 -0
- package/src/__tests__/runtime-events-sse-parity.test.ts +2 -0
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +408 -0
- package/src/__tests__/schedule-routes.test.ts +257 -4
- package/src/__tests__/schedule-store.test.ts +60 -0
- package/src/__tests__/schedule-tools.test.ts +247 -2
- package/src/__tests__/skill-execute-input.test.ts +85 -0
- package/src/__tests__/skill-secret-handling-guard.test.ts +21 -20
- package/src/__tests__/skills.test.ts +3 -3
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +1 -1
- package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +547 -0
- package/src/__tests__/system-prompt.test.ts +1 -1
- package/src/__tests__/task-progress-nudge-hook.test.ts +372 -0
- package/src/__tests__/task-scheduler.test.ts +299 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +209 -0
- package/src/__tests__/tool-result-spool.test.ts +3 -1
- package/src/__tests__/workspace-migration-102-preserve-heartbeat-enabled-for-existing-workspaces.test.ts +181 -0
- package/src/__tests__/workspace-migration-103-upgrade-quality-profile-to-opus-4-8.test.ts +174 -0
- package/src/agent/compaction-circuit.ts +11 -0
- package/src/agent/loop.ts +181 -12
- package/src/api/constants/call-sites.ts +12 -0
- package/src/api/events/assistant-thinking-delta.ts +10 -0
- package/src/api/events/usage-update.ts +7 -0
- package/src/api/index.ts +4 -1
- package/src/api/responses/memory-v3-selection-log.ts +18 -11
- package/src/approvals/approval-primitive.ts +2 -2
- package/src/background-wake/background-wake-routes.test.ts +5 -2
- package/src/bundler/compiler-tools.ts +1 -1
- package/src/bundler/package-resolver.ts +0 -1
- package/src/calls/call-domain.ts +1 -1
- package/src/calls/guardian-action-sweep.ts +16 -93
- package/src/cli/AGENTS.md +4 -0
- package/src/cli/commands/__tests__/schedules.test.ts +430 -1
- package/src/cli/commands/credentials.ts +28 -24
- package/src/cli/commands/image-generation.ts +23 -9
- package/src/cli/commands/notifications.ts +1 -1
- package/src/cli/commands/plugins.ts +89 -46
- package/src/cli/commands/schedules.ts +384 -11
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +69 -5
- package/src/cli/lib/__tests__/install-from-github.test.ts +15 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +81 -4
- package/src/cli/lib/inspect-plugin.ts +62 -1
- package/src/cli/lib/install-from-github.ts +52 -5
- package/src/cli/lib/upgrade-plugin.ts +18 -0
- package/src/config/__tests__/workflows-schema.test.ts +60 -0
- package/src/config/bundled-skills/acp/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +6 -1
- package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +7 -1
- package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +7 -1
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +10 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +66 -19
- package/src/config/bundled-skills/image-studio/TOOLS.json +1 -6
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +22 -3
- package/src/config/bundled-skills/personal-page/SKILL.md +57 -0
- package/src/config/bundled-skills/personal-page/TOOLS.json +27 -0
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +17 -0
- package/src/config/bundled-skills/schedule/SKILL.md +7 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +48 -4
- package/src/config/bundled-skills/workflows/SKILL.md +214 -0
- package/src/config/bundled-skills/workflows/TOOLS.json +84 -0
- package/src/config/bundled-skills/workflows/tools/manage-workflows.ts +12 -0
- package/src/config/bundled-skills/workflows/tools/run-workflow.ts +12 -0
- package/src/config/bundled-tool-registry.ts +14 -2
- package/src/config/call-site-defaults.ts +5 -0
- package/src/config/feature-flag-registry.json +12 -4
- package/src/config/llm-context-resolution.ts +8 -0
- package/src/config/llm-resolver.ts +30 -0
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +22 -0
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +16 -0
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +77 -0
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +57 -0
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +28 -0
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +234 -0
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +48 -0
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +16 -0
- package/src/config/preloaded-apps/personal-page/src/index.html +20 -0
- package/src/config/preloaded-apps/personal-page/src/main.tsx +7 -0
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +82 -0
- package/src/config/preloaded-apps/personal-page/src/styles.css +759 -0
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/heartbeat.ts +4 -1
- package/src/config/schemas/llm.ts +33 -26
- package/src/config/schemas/memory-retrospective.ts +19 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/services.ts +5 -2
- package/src/config/schemas/workflows.ts +42 -0
- package/src/config/skills.ts +3 -3
- package/src/context/compactor.ts +273 -39
- package/src/context/post-turn-tool-result-truncation.ts +23 -6
- package/src/context/tool-result-spool.ts +12 -17
- package/src/credential-execution/executable-discovery.ts +1 -1
- package/src/credential-execution/process-manager.ts +37 -3
- package/src/credential-execution/prompted-credential.ts +205 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +14 -0
- package/src/daemon/conversation-process.ts +11 -2
- package/src/daemon/conversation-surfaces.ts +167 -3
- package/src/daemon/conversation-tool-setup.ts +103 -26
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +115 -11
- package/src/daemon/handlers/shared.ts +26 -14
- package/src/daemon/host-cu-proxy.ts +15 -12
- package/src/daemon/host-file-proxy.ts +15 -12
- package/src/daemon/host-transfer-proxy.ts +30 -24
- package/src/daemon/lifecycle.ts +40 -3
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/messages.ts +2 -10
- package/src/daemon/message-types/workflows.ts +49 -0
- package/src/daemon/parse-actual-tokens-from-error.test.ts +62 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +43 -4
- package/src/daemon/process-message.ts +6 -0
- package/src/daemon/tool-setup-types.ts +57 -0
- package/src/daemon/wake-conversation-ops.ts +18 -0
- package/src/heartbeat/heartbeat-run-store.ts +8 -2
- package/src/home/feed-types.ts +1 -1
- package/src/ipc/gateway-flag-listener.ts +28 -6
- package/src/mcp/mcp-auth-state.ts +8 -20
- package/src/media/__tests__/image-models.test.ts +57 -0
- package/src/media/image-models.ts +66 -0
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +38 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +12 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +911 -34
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +227 -5
- package/src/memory/__tests__/memory-retrospective-state.test.ts +195 -0
- package/src/memory/__tests__/preloaded-apps.test.ts +85 -0
- package/src/memory/auto-analysis-enqueue.ts +14 -1
- package/src/memory/compaction-log-store-clickhouse.ts +6 -4
- package/src/memory/conversation-crud.ts +9 -2
- package/src/memory/conversation-disk-view.ts +1 -1
- package/src/memory/conversation-queries.ts +22 -7
- package/src/memory/db-init.ts +20 -0
- package/src/memory/db-maintenance.ts +16 -0
- package/src/memory/embedding-runtime-manager.ts +1 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +112 -14
- package/src/memory/llm-request-log-source-local.ts +19 -1
- package/src/memory/llm-request-log-source.ts +35 -6
- package/src/memory/llm-request-log-store.ts +90 -2
- package/src/memory/memory-retrospective-constants.ts +9 -0
- package/src/memory/memory-retrospective-enqueue.ts +3 -6
- package/src/memory/memory-retrospective-fork-boundary.ts +94 -0
- package/src/memory/memory-retrospective-job.ts +500 -208
- package/src/memory/memory-retrospective-startup-cleanup.ts +97 -19
- package/src/memory/memory-retrospective-state.ts +85 -2
- package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +40 -0
- package/src/memory/migrations/282-schedule-inference-profile.test.ts +77 -0
- package/src/memory/migrations/282-schedule-inference-profile.ts +26 -0
- package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.test.ts +102 -0
- package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.ts +53 -0
- package/src/memory/migrations/284-workflow-runs.ts +51 -0
- package/src/memory/migrations/285-schedule-workflow-mode.ts +26 -0
- package/src/memory/migrations/286-workflow-run-trust.ts +27 -0
- package/src/memory/migrations/287-conversation-origin-channel-index.ts +15 -0
- package/src/memory/migrations/288-backfill-origin-channel-from-bindings.ts +43 -0
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +115 -0
- package/src/memory/migrations/290-schedule-capabilities.test.ts +77 -0
- package/src/memory/migrations/290-schedule-capabilities.ts +25 -0
- package/src/memory/migrations/__tests__/281-memory-retrospective-remembered-log.test.ts +96 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +571 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/preloaded-apps.ts +116 -0
- package/src/memory/schema/infrastructure.ts +4 -0
- package/src/memory/schema/memory-core.ts +4 -0
- package/src/memory/v2/__tests__/concept-page-frontmatter-schema.test.ts +45 -0
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +11 -7
- package/src/memory/v2/__tests__/page-store.test.ts +13 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +24 -0
- package/src/memory/v2/frontmatter-sweep.ts +7 -6
- package/src/memory/v2/page-store.ts +4 -3
- package/src/memory/v2/qdrant.ts +42 -3
- package/src/memory/v2/types.ts +16 -10
- package/src/messaging/draft-store.ts +1 -1
- package/src/notifications/access-request-copy.ts +200 -113
- package/src/notifications/adapters/slack.ts +250 -111
- package/src/notifications/adapters/telegram.ts +7 -44
- package/src/notifications/approval-card-builder.ts +93 -0
- package/src/notifications/broadcaster.ts +74 -0
- package/src/notifications/conversation-pairing.ts +8 -6
- package/src/notifications/copy-composer.ts +32 -26
- package/src/notifications/decision-engine.ts +59 -7
- package/src/notifications/guardian-question-mode.ts +145 -155
- package/src/notifications/home-feed-side-effect.ts +28 -11
- package/src/notifications/notification-utils.ts +66 -0
- package/src/notifications/signal.ts +6 -0
- package/src/notifications/tool-approval-copy.ts +142 -0
- package/src/notifications/types.ts +19 -0
- package/src/permissions/threshold.ts +11 -0
- package/src/plugin-api/types.ts +16 -4
- package/src/plugins/defaults/compaction/window-manager.ts +44 -0
- package/src/plugins/defaults/index.ts +46 -0
- package/src/plugins/defaults/max-tokens-continue/continue-state-store.ts +53 -0
- package/src/plugins/defaults/max-tokens-continue/hooks/post-model-call.ts +80 -0
- package/src/plugins/defaults/max-tokens-continue/hooks/stop.ts +20 -0
- package/src/plugins/defaults/max-tokens-continue/package.json +14 -0
- package/src/plugins/defaults/memory-retrieval/hooks/__tests__/user-prompt-submit.test.ts +37 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +29 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +8 -3
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +4 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +28 -18
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +67 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +122 -22
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +2 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +63 -1
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +61 -18
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +1 -1
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +39 -10
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +34 -1
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +112 -47
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +78 -15
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +206 -0
- package/src/plugins/defaults/task-progress-nudge/package.json +15 -0
- package/src/prompts/__tests__/system-prompt.test.ts +100 -1
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +5 -7
- package/src/prompts/normalize-onboarding.ts +2 -0
- package/src/prompts/persona-resolver.ts +3 -0
- package/src/prompts/system-prompt.ts +51 -2
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +3 -1
- package/src/prompts/templates/system-sections.ts +8 -3
- package/src/providers/call-site-routing.ts +6 -3
- package/src/providers/fireworks/client.ts +3 -0
- package/src/providers/inference/auth.ts +52 -46
- package/src/providers/model-intents.ts +2 -2
- package/src/providers/openai/__tests__/coerce-object-args.test.ts +105 -0
- package/src/providers/openai/chat-completions-provider.ts +47 -9
- package/src/providers/openai/coerce-object-args.ts +104 -0
- package/src/providers/retry.ts +8 -5
- package/src/providers/types.ts +10 -0
- package/src/runtime/__tests__/agent-wake.test.ts +629 -7
- package/src/runtime/access-request-helper.ts +16 -9
- package/src/runtime/agent-wake.ts +302 -51
- package/src/runtime/assistant-stream-state.ts +141 -8
- package/src/runtime/background-job-runner.ts +9 -0
- package/src/runtime/channel-approval-types.ts +1 -0
- package/src/runtime/channel-invite-transports/telegram.ts +6 -5
- package/src/runtime/channel-invite-transports/voice.ts +2 -2
- package/src/runtime/channel-invite-types.ts +4 -2
- package/src/runtime/channel-retry-sweep.ts +19 -41
- package/src/runtime/finalize-event-delivery.ts +72 -0
- package/src/runtime/guardian-action-message-composer.ts +0 -54
- package/src/runtime/http-server.ts +6 -14
- package/src/runtime/http-types.ts +0 -1
- package/src/runtime/message-composer-types.ts +0 -9
- package/src/runtime/middleware/__tests__/rate-limiter.test.ts +63 -0
- package/src/runtime/middleware/auth.ts +27 -3
- package/src/runtime/middleware/rate-limiter.ts +28 -1
- package/src/runtime/migrations/vbundle-builder.ts +6 -5
- package/src/runtime/pending-interactions.ts +20 -1
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +232 -173
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +18 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +436 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +11 -0
- package/src/runtime/routes/approval-routes.ts +35 -8
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -1
- package/src/runtime/routes/btw-routes.ts +37 -1
- package/src/runtime/routes/channel-delivery-routes.ts +11 -7
- package/src/runtime/routes/channel-route-definitions.ts +3 -0
- package/src/runtime/routes/channel-route-shared.ts +3 -1
- package/src/runtime/routes/consolidation-routes.ts +17 -13
- package/src/runtime/routes/conversation-compaction-routes.ts +159 -119
- package/src/runtime/routes/conversation-list-routes.ts +41 -4
- package/src/runtime/routes/conversation-query-routes.ts +196 -11
- package/src/runtime/routes/conversation-routes.ts +15 -1
- package/src/runtime/routes/credential-prompt-routes.ts +39 -17
- package/src/runtime/routes/empty-state-greeting-cache.ts +65 -0
- package/src/runtime/routes/heartbeat-routes.ts +18 -13
- package/src/runtime/routes/image-generation-routes.ts +20 -2
- package/src/runtime/routes/inbound-message-handler.ts +13 -12
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +32 -31
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +7 -5
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +7 -21
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +6 -15
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +1 -1
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/log-export/AGENTS.md +1 -1
- package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
- package/src/runtime/routes/migration-routes.ts +5 -9
- package/src/runtime/routes/plugins-routes.ts +26 -0
- package/src/runtime/routes/ps-routes.ts +10 -8
- package/src/runtime/routes/retrospective-routes.ts +235 -0
- package/src/runtime/routes/runs-pagination.ts +75 -0
- package/src/runtime/routes/schedule-routes.ts +367 -59
- package/src/runtime/routes/sounds-config-routes.ts +239 -0
- package/src/runtime/routes/surface-action-routes.ts +84 -4
- package/src/runtime/routes/workflow-routes.test.ts +372 -0
- package/src/runtime/routes/workflow-routes.ts +363 -0
- package/src/runtime/routes/workspace-routes.test.ts +61 -1
- package/src/runtime/routes/workspace-routes.ts +26 -1
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +38 -0
- package/src/runtime/services/analyze-conversation.ts +26 -13
- package/src/schedule/inference-profile.ts +28 -0
- package/src/schedule/schedule-store.ts +152 -4
- package/src/schedule/scheduler-types.ts +6 -0
- package/src/schedule/scheduler.ts +96 -0
- package/src/security/secret-allowlist.ts +1 -1
- package/src/skills/path-classifier.ts +1 -1
- package/src/tools/apps/executors.ts +23 -0
- package/src/tools/apps/resolve-app-id.ts +42 -0
- package/src/tools/browser/browser-execution.ts +9 -11
- package/src/tools/credentials/broker.ts +4 -4
- package/src/tools/credentials/vault.ts +26 -137
- package/src/tools/executor.ts +69 -0
- package/src/tools/flag-gated-tools.test.ts +76 -0
- package/src/tools/permission-checker.ts +8 -1
- package/src/tools/registry.ts +51 -0
- package/src/tools/schedule/create.ts +77 -1
- package/src/tools/schedule/list.ts +1 -0
- package/src/tools/schedule/update.ts +73 -1
- package/src/tools/skills/execute.ts +56 -0
- package/src/tools/terminal/shell.ts +1 -1
- package/src/tools/ui-surface/definitions.ts +91 -2
- package/src/tools/workflows/manage-workflows.ts +183 -0
- package/src/tools/workflows/run-workflow.test.ts +442 -0
- package/src/tools/workflows/run-workflow.ts +88 -0
- package/src/types/onboarding-context.ts +2 -0
- package/src/usage/attribution.ts +24 -0
- package/src/util/canonicalize-identity.ts +12 -3
- package/src/util/platform.ts +17 -17
- package/src/watcher/__tests__/engine.test.ts +24 -0
- package/src/watcher/__tests__/telemetry.test.ts +135 -0
- package/src/watcher/engine.ts +7 -0
- package/src/watcher/telemetry.ts +74 -0
- package/src/workflows/capabilities.test.ts +365 -0
- package/src/workflows/capabilities.ts +359 -0
- package/src/workflows/deterministic-stringify.ts +27 -0
- package/src/workflows/engine-integration.test.ts +656 -0
- package/src/workflows/engine.test.ts +1144 -0
- package/src/workflows/engine.ts +1078 -0
- package/src/workflows/fanout-load.test.ts +168 -0
- package/src/workflows/journal-store.test.ts +369 -0
- package/src/workflows/journal-store.ts +470 -0
- package/src/workflows/leaf-runner.test.ts +704 -0
- package/src/workflows/leaf-runner.ts +589 -0
- package/src/workflows/library.test.ts +134 -0
- package/src/workflows/library.ts +124 -0
- package/src/workflows/run-manager.test.ts +711 -0
- package/src/workflows/run-manager.ts +593 -0
- package/src/workflows/sandbox-escape.test.ts +339 -0
- package/src/workflows/sandbox.test.ts +251 -0
- package/src/workflows/sandbox.ts +447 -0
- package/src/workspace/adaptive-thinking-repair.ts +33 -11
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +1 -1
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +1 -1
- package/src/workspace/migrations/026-backfill-install-meta.ts +1 -1
- package/src/workspace/migrations/030-seed-pkb-autoinject.ts +2 -1
- package/src/workspace/migrations/031-drop-user-md.ts +1 -4
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +1 -1
- package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +5 -2
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +1 -1
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +8 -2
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +41 -14
- package/src/workspace/migrations/102-preserve-heartbeat-enabled-for-existing-workspaces.ts +69 -0
- package/src/workspace/migrations/103-upgrade-quality-profile-to-opus-4-8.ts +83 -0
- package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +133 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/workspace/migrations/runner.ts +1 -1
- package/tsconfig.json +1 -1
- package/src/__tests__/guardian-action-copy-generator.test.ts +0 -200
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -579
- package/src/__tests__/guardian-action-store.test.ts +0 -106
- package/src/daemon/guardian-action-generators.ts +0 -71
- package/src/memory/guardian-action-store.ts +0 -484
- package/src/runtime/guardian-action-grant-minter.ts +0 -150
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
inspectPlugin,
|
|
15
15
|
type PluginInspection,
|
|
16
16
|
PluginInspectNotFoundError,
|
|
17
|
+
type PluginRemoteInfo,
|
|
17
18
|
} from "../lib/inspect-plugin.js";
|
|
18
19
|
import {
|
|
19
20
|
DEFAULT_PLUGIN_REF,
|
|
@@ -380,33 +381,44 @@ function shortSha(sha: string | null): string {
|
|
|
380
381
|
return sha ? sha.slice(0, 7) : "—";
|
|
381
382
|
}
|
|
382
383
|
|
|
383
|
-
/**
|
|
384
|
-
|
|
385
|
-
|
|
384
|
+
/**
|
|
385
|
+
* Render a commit timestamp as the human-facing version: a UTC `YYYY-MM-DDThh:mm:ss`
|
|
386
|
+
* string (seconds precision, no fractional or zone suffix). Older installs with
|
|
387
|
+
* no recorded commit date — and remote pins whose date could not be fetched —
|
|
388
|
+
* fall back to `unknown`, with the SHA still shown alongside as the precise id.
|
|
389
|
+
*/
|
|
390
|
+
function formatTimestamp(iso: string | null): string {
|
|
391
|
+
if (!iso) return "unknown";
|
|
392
|
+
const ms = Date.parse(iso);
|
|
393
|
+
if (!Number.isFinite(ms)) return "unknown";
|
|
394
|
+
return new Date(ms).toISOString().slice(0, 19);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/** Human-readable status line for an inspection result. The from/to revisions
|
|
398
|
+
* now live in the installed/remote blocks, so the status itself is just words. */
|
|
399
|
+
function statusLine(status: PluginInspection["status"]): string {
|
|
386
400
|
switch (status) {
|
|
387
401
|
case "up-to-date":
|
|
388
402
|
return "up to date";
|
|
389
403
|
case "update-available":
|
|
390
|
-
return
|
|
391
|
-
remote?.commit ?? null,
|
|
392
|
-
)})`;
|
|
404
|
+
return "update available";
|
|
393
405
|
case "not-installed":
|
|
394
406
|
return "not installed";
|
|
395
407
|
case "not-in-marketplace":
|
|
396
408
|
return "installed (not in marketplace)";
|
|
397
409
|
case "unknown-provenance":
|
|
398
|
-
return "unknown
|
|
410
|
+
return "unknown (reinstall to record provenance)";
|
|
399
411
|
case "remote-unavailable":
|
|
400
412
|
return "installed (marketplace unavailable)";
|
|
401
413
|
}
|
|
402
414
|
}
|
|
403
415
|
|
|
404
416
|
/**
|
|
405
|
-
* Summarize
|
|
406
|
-
*
|
|
407
|
-
*
|
|
417
|
+
* Summarize drift relative to the install-time fingerprint. Reports "unknown"
|
|
418
|
+
* when no baseline was recorded (an older or manually-copied install), "none"
|
|
419
|
+
* when the on-disk tree matches, or a per-category count.
|
|
408
420
|
*/
|
|
409
|
-
function
|
|
421
|
+
function driftLine(changes: FingerprintComparison | null): string {
|
|
410
422
|
if (!changes)
|
|
411
423
|
return "unknown (no recorded baseline; reinstall to record one)";
|
|
412
424
|
if (changes.clean) return "none";
|
|
@@ -418,74 +430,105 @@ function localEditsLine(changes: FingerprintComparison | null): string {
|
|
|
418
430
|
return parts.join(", ");
|
|
419
431
|
}
|
|
420
432
|
|
|
421
|
-
/**
|
|
433
|
+
/** Build the GitHub web URL for a remote pin's location (repo, or repo subtree). */
|
|
434
|
+
function remoteLocation(remote: PluginRemoteInfo): string {
|
|
435
|
+
const base = `https://github.com/${remote.repo}`;
|
|
436
|
+
return remote.path ? `${base}/tree/${remote.commit}/${remote.path}` : base;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Render an inspection with timestamps as the headline version. The layout is a
|
|
441
|
+
* name heading + rule, a top-level `status`, then `installed`/`remote` blocks
|
|
442
|
+
* that each carry `timestamp` (the human version), `hash` (the precise id), and
|
|
443
|
+
* `location`, with a `drift` line under the installed copy.
|
|
444
|
+
*/
|
|
422
445
|
function formatInspection(inspection: PluginInspection): string[] {
|
|
423
|
-
const { name, local, remote, remoteError } = inspection;
|
|
424
|
-
const lines: string[] = [
|
|
425
|
-
const
|
|
426
|
-
lines.push(
|
|
446
|
+
const { name, status, local, remote, remoteError } = inspection;
|
|
447
|
+
const lines: string[] = [name, "─".repeat(44)];
|
|
448
|
+
const topRow = (label: string, value: string) =>
|
|
449
|
+
lines.push(`${label.padEnd(11)} ${value}`);
|
|
450
|
+
const blockRow = (label: string, value: string) =>
|
|
451
|
+
lines.push(` ${label.padEnd(9)} ${value}`);
|
|
427
452
|
|
|
428
|
-
|
|
453
|
+
topRow("status", statusLine(status));
|
|
429
454
|
|
|
430
455
|
if (local) {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
456
|
+
lines.push("installed");
|
|
457
|
+
blockRow("timestamp", formatTimestamp(local.committedAt));
|
|
458
|
+
blockRow("hash", shortSha(local.commit));
|
|
459
|
+
blockRow("location", local.target);
|
|
460
|
+
// `installedAt` is rewritten on every install/upgrade, so it reads as the
|
|
461
|
+
// last time this copy was materialized rather than a first-install date.
|
|
462
|
+
blockRow("updated", formatTimestamp(local.installedAt));
|
|
463
|
+
topRow("drift", driftLine(local.localChanges));
|
|
436
464
|
}
|
|
437
465
|
|
|
438
466
|
if (remote) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
);
|
|
467
|
+
lines.push("remote");
|
|
468
|
+
blockRow("timestamp", formatTimestamp(remote.committedAt));
|
|
469
|
+
blockRow("hash", shortSha(remote.commit));
|
|
470
|
+
blockRow("location", remoteLocation(remote));
|
|
444
471
|
} else if (remoteError) {
|
|
445
|
-
|
|
472
|
+
topRow("remote", `unavailable: ${remoteError}`);
|
|
446
473
|
}
|
|
447
474
|
|
|
448
|
-
const
|
|
449
|
-
if (
|
|
475
|
+
const pkgVersion = local?.version ?? null;
|
|
476
|
+
if (pkgVersion) topRow("pkg version", pkgVersion);
|
|
450
477
|
|
|
451
478
|
const license = remote?.license ?? null;
|
|
452
479
|
const homepage = remote?.homepage ?? null;
|
|
453
|
-
if (license
|
|
454
|
-
|
|
455
|
-
else if (homepage) row("homepage", homepage);
|
|
480
|
+
if (license) topRow("license", license);
|
|
481
|
+
if (homepage) topRow("homepage", homepage);
|
|
456
482
|
|
|
457
483
|
const description = remote?.description ?? local?.description ?? null;
|
|
458
|
-
if (description)
|
|
484
|
+
if (description) topRow("description", description);
|
|
459
485
|
|
|
460
|
-
for (const issue of local?.issues ?? [])
|
|
486
|
+
for (const issue of local?.issues ?? []) topRow("issue", issue);
|
|
461
487
|
|
|
462
488
|
return lines;
|
|
463
489
|
}
|
|
464
490
|
|
|
465
|
-
/**
|
|
491
|
+
/**
|
|
492
|
+
* Render an upgrade result with the `timestamp (hash) → timestamp (hash)` move
|
|
493
|
+
* as the headline, mirroring the inspect layout so the same version identity is
|
|
494
|
+
* used everywhere.
|
|
495
|
+
*/
|
|
466
496
|
function formatUpgrade(result: PluginUpgradeResult): string[] {
|
|
467
|
-
const { name, fromCommit, toCommit } = result;
|
|
468
|
-
const move =
|
|
497
|
+
const { name, fromCommit, fromTimestamp, toCommit, toTimestamp } = result;
|
|
498
|
+
const move =
|
|
499
|
+
`${formatTimestamp(fromTimestamp)} (${shortSha(fromCommit)})` +
|
|
500
|
+
` → ${formatTimestamp(toTimestamp)} (${shortSha(toCommit)})`;
|
|
469
501
|
const provenanceNote = result.provenanceWasUnknown
|
|
470
|
-
? "
|
|
471
|
-
:
|
|
502
|
+
? "Previous install had no recorded provenance; it has been re-pinned."
|
|
503
|
+
: null;
|
|
472
504
|
|
|
473
505
|
switch (result.outcome) {
|
|
474
506
|
case "already-up-to-date":
|
|
475
|
-
return [`"${name}" is already up to date (${shortSha(toCommit)}).`];
|
|
476
|
-
case "would-upgrade":
|
|
477
507
|
return [
|
|
478
|
-
`"${name}"
|
|
508
|
+
`"${name}" is already up to date at ${formatTimestamp(toTimestamp)} (${shortSha(toCommit)}).`,
|
|
479
509
|
];
|
|
510
|
+
case "would-upgrade": {
|
|
511
|
+
const lines = [
|
|
512
|
+
`"${name}" would upgrade ${move}`,
|
|
513
|
+
"",
|
|
514
|
+
"dry run; no changes made.",
|
|
515
|
+
];
|
|
516
|
+
if (provenanceNote) lines.push(provenanceNote);
|
|
517
|
+
return lines;
|
|
518
|
+
}
|
|
480
519
|
case "upgraded": {
|
|
481
520
|
const count =
|
|
482
521
|
result.fileCount === null
|
|
483
522
|
? ""
|
|
484
|
-
: `
|
|
485
|
-
|
|
486
|
-
`Upgraded "${name}" ${move}
|
|
523
|
+
: `(${result.fileCount} file${result.fileCount === 1 ? "" : "s"}) `;
|
|
524
|
+
const lines = [
|
|
525
|
+
`Upgraded "${name}" ${move}`,
|
|
526
|
+
"",
|
|
527
|
+
`${count}→ ${result.target}`,
|
|
487
528
|
"Restart the assistant to pick up the upgrade.",
|
|
488
529
|
];
|
|
530
|
+
if (provenanceNote) lines.push(provenanceNote);
|
|
531
|
+
return lines;
|
|
489
532
|
}
|
|
490
533
|
}
|
|
491
534
|
}
|
|
@@ -22,6 +22,9 @@ interface ScheduleRecord {
|
|
|
22
22
|
retryCount: number;
|
|
23
23
|
maxRetries: number;
|
|
24
24
|
retryBackoffMs: number;
|
|
25
|
+
timeoutMs: number | null;
|
|
26
|
+
inferenceProfile: string | null;
|
|
27
|
+
createdFromConversationId: string | null;
|
|
25
28
|
description: string | null;
|
|
26
29
|
cadenceDescription: string | null;
|
|
27
30
|
mode: string;
|
|
@@ -36,6 +39,10 @@ interface ListSchedulesResponse {
|
|
|
36
39
|
schedules: ScheduleRecord[];
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
interface GetScheduleResponse {
|
|
43
|
+
schedule: ScheduleRecord;
|
|
44
|
+
}
|
|
45
|
+
|
|
39
46
|
interface ScheduleRunRecord {
|
|
40
47
|
id: string;
|
|
41
48
|
jobId: string;
|
|
@@ -64,19 +71,17 @@ export function registerSchedulesCommand(program: Command): void {
|
|
|
64
71
|
`
|
|
65
72
|
Schedules are recurring or one-shot jobs run by the assistant.
|
|
66
73
|
|
|
67
|
-
This
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
This namespace exposes full CRUD against the assistant's schedule store:
|
|
75
|
+
create, list, get, update, enable/disable, cancel, delete, plus run history
|
|
76
|
+
and manual one-time execution. One documented exception: 'create' is limited
|
|
77
|
+
to 'execute' mode — notify/script/wake schedules are created via the
|
|
78
|
+
in-assistant schedule_create tool, but can be inspected and updated here.
|
|
71
79
|
|
|
72
80
|
Examples:
|
|
73
81
|
$ assistant schedules list
|
|
74
|
-
$ assistant schedules
|
|
75
|
-
$ assistant schedules
|
|
82
|
+
$ assistant schedules get <schedule-id>
|
|
83
|
+
$ assistant schedules update <schedule-id> --expression '0 9 * * *'
|
|
76
84
|
$ assistant schedules runs <schedule-id> --limit 25 --json
|
|
77
|
-
$ assistant schedules disable <schedule-id>
|
|
78
|
-
$ assistant schedules enable <schedule-id>
|
|
79
|
-
$ assistant schedules cancel <schedule-id>
|
|
80
85
|
$ assistant schedules execute <schedule-id>`,
|
|
81
86
|
);
|
|
82
87
|
|
|
@@ -199,6 +204,94 @@ Examples:
|
|
|
199
204
|
},
|
|
200
205
|
);
|
|
201
206
|
|
|
207
|
+
schedules
|
|
208
|
+
.command("get <id>")
|
|
209
|
+
.alias("inspect")
|
|
210
|
+
.description("Show full details for a single schedule")
|
|
211
|
+
.option("--json", "Machine-readable compact JSON output")
|
|
212
|
+
.addHelpText(
|
|
213
|
+
"after",
|
|
214
|
+
`
|
|
215
|
+
Options:
|
|
216
|
+
--json Output the raw schedule object as compact JSON.
|
|
217
|
+
|
|
218
|
+
Arguments:
|
|
219
|
+
<id> Schedule ID (UUID) — run 'assistant schedules list --all' to find it.
|
|
220
|
+
|
|
221
|
+
Behavior:
|
|
222
|
+
Prints every stored field of the schedule: name, description, mode,
|
|
223
|
+
expression/syntax, timezone, enabled state, status, next/last run times,
|
|
224
|
+
message or script body, inference profile (shown as 'default (mainAgent)'
|
|
225
|
+
when none is pinned), routing intent, and retry policy. Works for
|
|
226
|
+
deferred schedules that 'assistant schedules list' hides by default.
|
|
227
|
+
Aliased as 'inspect'.
|
|
228
|
+
|
|
229
|
+
Examples:
|
|
230
|
+
$ assistant schedules get 9f2c4f3a-3f1a-41e4-88e7-abc123
|
|
231
|
+
$ assistant schedules inspect 9f2c4f3a-3f1a-41e4-88e7-abc123
|
|
232
|
+
$ assistant schedules get 9f2c4f3a-3f1a-41e4-88e7-abc123 --json`,
|
|
233
|
+
)
|
|
234
|
+
.action(async (id: string, opts: { json?: boolean }, cmd: Command) => {
|
|
235
|
+
const scheduleId = id.trim();
|
|
236
|
+
const result = await cliIpcCall<GetScheduleResponse>("getSchedule", {
|
|
237
|
+
pathParams: { id: scheduleId },
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
if (!result.ok) return exitFromIpcResult(result, cmd);
|
|
241
|
+
|
|
242
|
+
const schedule = result.result?.schedule;
|
|
243
|
+
if (!schedule) {
|
|
244
|
+
const error = `Schedule "${scheduleId}" not found. Run 'assistant schedules list --all' to see available schedules.`;
|
|
245
|
+
if (opts.json) {
|
|
246
|
+
writeOutput(cmd, { ok: false, error });
|
|
247
|
+
} else {
|
|
248
|
+
log.error(error);
|
|
249
|
+
}
|
|
250
|
+
process.exitCode = 1;
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (opts.json) {
|
|
255
|
+
writeOutput(cmd, { schedule });
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const fields: Array<[string, string]> = [
|
|
260
|
+
["ID", schedule.id],
|
|
261
|
+
["Name", schedule.name],
|
|
262
|
+
["Description", schedule.description ?? "—"],
|
|
263
|
+
["Enabled", schedule.enabled ? "enabled" : "disabled"],
|
|
264
|
+
["Status", schedule.status],
|
|
265
|
+
["Mode", schedule.mode],
|
|
266
|
+
["Syntax", schedule.syntax],
|
|
267
|
+
["Expression", schedule.expression ?? "—"],
|
|
268
|
+
["Cadence", describeSchedule(schedule)],
|
|
269
|
+
["Timezone", schedule.timezone ?? "—"],
|
|
270
|
+
["Next run", formatTimestamp(schedule.nextRunAt)],
|
|
271
|
+
["Last run", formatNullableTimestamp(schedule.lastRunAt)],
|
|
272
|
+
["Last status", schedule.lastStatus ?? "—"],
|
|
273
|
+
["One-shot", schedule.isOneShot ? "yes" : "no"],
|
|
274
|
+
["Message", schedule.message || "—"],
|
|
275
|
+
["Script", schedule.script ?? "—"],
|
|
276
|
+
[
|
|
277
|
+
"Inference profile",
|
|
278
|
+
schedule.inferenceProfile ?? "default (mainAgent)",
|
|
279
|
+
],
|
|
280
|
+
["Routing intent", schedule.routingIntent],
|
|
281
|
+
["Reuse conversation", schedule.reuseConversation ? "yes" : "no"],
|
|
282
|
+
["Wake conversation", schedule.wakeConversationId ?? "—"],
|
|
283
|
+
["Retry count", String(schedule.retryCount)],
|
|
284
|
+
["Max retries", String(schedule.maxRetries)],
|
|
285
|
+
["Retry backoff", formatDuration(schedule.retryBackoffMs)],
|
|
286
|
+
["Timeout", formatDuration(schedule.timeoutMs)],
|
|
287
|
+
["Source conversation", schedule.createdFromConversationId ?? "—"],
|
|
288
|
+
];
|
|
289
|
+
const labelWidth = Math.max(...fields.map(([label]) => label.length));
|
|
290
|
+
for (const [label, value] of fields) {
|
|
291
|
+
log.info(`${`${label}:`.padEnd(labelWidth + 2)}${value}`);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
202
295
|
schedules
|
|
203
296
|
.command("runs <id>")
|
|
204
297
|
.description("List recent runs for a schedule")
|
|
@@ -331,6 +424,10 @@ Examples:
|
|
|
331
424
|
"-t, --timezone <tz>",
|
|
332
425
|
"IANA timezone for the expression (e.g. America/New_York)",
|
|
333
426
|
)
|
|
427
|
+
.option(
|
|
428
|
+
"--profile <name>",
|
|
429
|
+
"Inference profile (llm.profiles key) the schedule's runs use; defaults to the mainAgent model selection when omitted",
|
|
430
|
+
)
|
|
334
431
|
.option("--no-enabled", "Create the schedule in a disabled state")
|
|
335
432
|
.option("--json", "Machine-readable compact JSON output")
|
|
336
433
|
.addHelpText(
|
|
@@ -341,6 +438,9 @@ Options:
|
|
|
341
438
|
-d, --description <text> Authored description explaining what the schedule is for.
|
|
342
439
|
-m, --message <text> Message body sent on each fire.
|
|
343
440
|
-t, --timezone <tz> IANA timezone applied to the expression.
|
|
441
|
+
--profile <name> Inference profile (llm.profiles key) the schedule's
|
|
442
|
+
runs use. When omitted, runs use the default —
|
|
443
|
+
the mainAgent call site's model selection.
|
|
344
444
|
--no-enabled Create the schedule disabled. Defaults to enabled.
|
|
345
445
|
--json Output the updated schedule list as compact JSON.
|
|
346
446
|
|
|
@@ -376,6 +476,7 @@ Examples:
|
|
|
376
476
|
description: string;
|
|
377
477
|
message: string;
|
|
378
478
|
timezone?: string;
|
|
479
|
+
profile?: string;
|
|
379
480
|
enabled: boolean;
|
|
380
481
|
json?: boolean;
|
|
381
482
|
},
|
|
@@ -413,6 +514,7 @@ Examples:
|
|
|
413
514
|
enabled: opts.enabled,
|
|
414
515
|
};
|
|
415
516
|
if (opts.timezone != null) body.timezone = opts.timezone;
|
|
517
|
+
if (opts.profile != null) body.inferenceProfile = opts.profile;
|
|
416
518
|
|
|
417
519
|
const result = await cliIpcCall<ListSchedulesResponse>(
|
|
418
520
|
"createSchedule",
|
|
@@ -431,6 +533,251 @@ Examples:
|
|
|
431
533
|
},
|
|
432
534
|
);
|
|
433
535
|
|
|
536
|
+
schedules
|
|
537
|
+
.command("update <id>")
|
|
538
|
+
.description("Update fields on an existing schedule")
|
|
539
|
+
.option("--name <text>", "New display name")
|
|
540
|
+
.option(
|
|
541
|
+
"-d, --description <text>",
|
|
542
|
+
"New authored description explaining what the schedule is for",
|
|
543
|
+
)
|
|
544
|
+
.option(
|
|
545
|
+
"-e, --expression <expr>",
|
|
546
|
+
"New cron or RRULE expression for the fire times",
|
|
547
|
+
)
|
|
548
|
+
.option(
|
|
549
|
+
"-t, --timezone <tz>",
|
|
550
|
+
"IANA timezone for the expression (e.g. America/New_York)",
|
|
551
|
+
)
|
|
552
|
+
.option(
|
|
553
|
+
"-m, --message <text>",
|
|
554
|
+
"New message body sent to the assistant on each fire",
|
|
555
|
+
)
|
|
556
|
+
.option("--script <command>", "Shell command for script-mode schedules")
|
|
557
|
+
.option(
|
|
558
|
+
"--mode <mode>",
|
|
559
|
+
"One of: notify, execute, script, wake (wake only when the schedule already has a wake conversation target)",
|
|
560
|
+
)
|
|
561
|
+
.option(
|
|
562
|
+
"--routing-intent <intent>",
|
|
563
|
+
"One of: single_channel, multi_channel, all_channels",
|
|
564
|
+
)
|
|
565
|
+
.option("--quiet", "Suppress notifications for this schedule")
|
|
566
|
+
.option("--no-quiet", "Re-enable notifications for this schedule")
|
|
567
|
+
.option(
|
|
568
|
+
"--reuse-conversation",
|
|
569
|
+
"Reuse one conversation across recurring fires",
|
|
570
|
+
)
|
|
571
|
+
.option(
|
|
572
|
+
"--no-reuse-conversation",
|
|
573
|
+
"Start a fresh conversation on each fire",
|
|
574
|
+
)
|
|
575
|
+
.option("--max-retries <count>", "Maximum retry attempts (integer)")
|
|
576
|
+
.option(
|
|
577
|
+
"--retry-backoff-ms <ms>",
|
|
578
|
+
"Retry backoff in milliseconds (integer)",
|
|
579
|
+
)
|
|
580
|
+
.option(
|
|
581
|
+
"--timeout-ms <ms>",
|
|
582
|
+
"Script-mode execution timeout in milliseconds (integer)",
|
|
583
|
+
)
|
|
584
|
+
.option(
|
|
585
|
+
"--clear-timeout",
|
|
586
|
+
"Clear the script timeout override and use the assistant default",
|
|
587
|
+
)
|
|
588
|
+
.option(
|
|
589
|
+
"--profile <name>",
|
|
590
|
+
"Inference profile (llm.profiles key) the schedule's runs use; the default when unset is the mainAgent model selection",
|
|
591
|
+
)
|
|
592
|
+
.option(
|
|
593
|
+
"--clear-profile",
|
|
594
|
+
"Clear the inference profile and revert to the default mainAgent model selection",
|
|
595
|
+
)
|
|
596
|
+
.option("--json", "Machine-readable compact JSON output")
|
|
597
|
+
.addHelpText(
|
|
598
|
+
"after",
|
|
599
|
+
`
|
|
600
|
+
Options:
|
|
601
|
+
--name <text> New display name.
|
|
602
|
+
-d, --description <text> New authored description (must be non-empty).
|
|
603
|
+
-e, --expression <expr> Cron (e.g. '*/30 * * * *') or RRULE expression.
|
|
604
|
+
-t, --timezone <tz> IANA timezone applied to the expression.
|
|
605
|
+
-m, --message <text> New message body sent on each fire.
|
|
606
|
+
--script <command> Shell command for script-mode schedules.
|
|
607
|
+
--mode <mode> notify, execute, script, or wake.
|
|
608
|
+
--routing-intent <intent> single_channel, multi_channel, or all_channels.
|
|
609
|
+
--quiet / --no-quiet Toggle notification suppression.
|
|
610
|
+
--reuse-conversation / --no-reuse-conversation
|
|
611
|
+
Toggle conversation reuse across recurring fires.
|
|
612
|
+
--max-retries <count> Maximum retry attempts.
|
|
613
|
+
--retry-backoff-ms <ms> Retry backoff in milliseconds.
|
|
614
|
+
--timeout-ms <ms> Script-mode execution timeout in milliseconds.
|
|
615
|
+
--clear-timeout Remove the timeout override (mutually exclusive
|
|
616
|
+
with --timeout-ms).
|
|
617
|
+
--profile <name> Inference profile (llm.profiles key) the schedule's
|
|
618
|
+
runs use. When no profile is set, runs use the
|
|
619
|
+
default — the mainAgent call site's model selection.
|
|
620
|
+
--clear-profile Remove the inference profile and revert to the
|
|
621
|
+
default mainAgent model selection (mutually
|
|
622
|
+
exclusive with --profile).
|
|
623
|
+
--json Output the updated schedule list as compact JSON.
|
|
624
|
+
|
|
625
|
+
Arguments:
|
|
626
|
+
<id> Schedule ID (UUID) — run 'assistant schedules list --all' to find it.
|
|
627
|
+
|
|
628
|
+
Behavior:
|
|
629
|
+
Partially updates the schedule: only fields for flags you pass are changed,
|
|
630
|
+
everything else is preserved. At least one update flag is required. To
|
|
631
|
+
enable or disable a schedule, use 'assistant schedules enable <id>' or
|
|
632
|
+
'assistant schedules disable <id>' instead.
|
|
633
|
+
|
|
634
|
+
Examples:
|
|
635
|
+
$ assistant schedules update 9f2c4f3a-3f1a-41e4-88e7-abc123 \\
|
|
636
|
+
--expression '0 9 * * MON-FRI' --timezone America/New_York
|
|
637
|
+
$ assistant schedules update 9f2c4f3a-3f1a-41e4-88e7-abc123 \\
|
|
638
|
+
--name "Morning summary" --message 'write the morning summary'
|
|
639
|
+
$ assistant schedules update 9f2c4f3a-3f1a-41e4-88e7-abc123 \\
|
|
640
|
+
--max-retries 5 --retry-backoff-ms 30000 --json`,
|
|
641
|
+
)
|
|
642
|
+
.action(
|
|
643
|
+
async (
|
|
644
|
+
id: string,
|
|
645
|
+
opts: {
|
|
646
|
+
name?: string;
|
|
647
|
+
description?: string;
|
|
648
|
+
expression?: string;
|
|
649
|
+
timezone?: string;
|
|
650
|
+
message?: string;
|
|
651
|
+
script?: string;
|
|
652
|
+
mode?: string;
|
|
653
|
+
routingIntent?: string;
|
|
654
|
+
quiet?: boolean;
|
|
655
|
+
reuseConversation?: boolean;
|
|
656
|
+
maxRetries?: string;
|
|
657
|
+
retryBackoffMs?: string;
|
|
658
|
+
timeoutMs?: string;
|
|
659
|
+
clearTimeout?: boolean;
|
|
660
|
+
profile?: string;
|
|
661
|
+
clearProfile?: boolean;
|
|
662
|
+
json?: boolean;
|
|
663
|
+
},
|
|
664
|
+
cmd: Command,
|
|
665
|
+
) => {
|
|
666
|
+
const scheduleId = id.trim();
|
|
667
|
+
const fail = (error: string) => {
|
|
668
|
+
if (opts.json) {
|
|
669
|
+
writeOutput(cmd, { ok: false, error });
|
|
670
|
+
} else {
|
|
671
|
+
log.error(error);
|
|
672
|
+
}
|
|
673
|
+
process.exitCode = 1;
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
const parseInteger = (
|
|
677
|
+
flag: string,
|
|
678
|
+
value: string,
|
|
679
|
+
): number | null => {
|
|
680
|
+
const parsed = Number(value);
|
|
681
|
+
if (!Number.isInteger(parsed)) {
|
|
682
|
+
fail(`${flag} must be an integer, got "${value}"`);
|
|
683
|
+
return null;
|
|
684
|
+
}
|
|
685
|
+
return parsed;
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
if (opts.clearTimeout && opts.timeoutMs != null) {
|
|
689
|
+
fail(
|
|
690
|
+
"--timeout-ms and --clear-timeout are mutually exclusive; pass --timeout-ms to set a timeout or --clear-timeout to remove it",
|
|
691
|
+
);
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
if (opts.clearProfile && opts.profile != null) {
|
|
696
|
+
fail(
|
|
697
|
+
"--profile and --clear-profile are mutually exclusive; pass --profile to set a profile or --clear-profile to revert to the default mainAgent model selection",
|
|
698
|
+
);
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// Wake mode requires a wake conversation target, which this CLI
|
|
703
|
+
// cannot set. Allow `--mode wake` only when the schedule already
|
|
704
|
+
// has one — otherwise the scheduler would skip every fire as a
|
|
705
|
+
// no-op.
|
|
706
|
+
if (opts.mode === "wake") {
|
|
707
|
+
const existing = await cliIpcCall<GetScheduleResponse>(
|
|
708
|
+
"getSchedule",
|
|
709
|
+
{ pathParams: { id: scheduleId } },
|
|
710
|
+
);
|
|
711
|
+
if (!existing.ok) return exitFromIpcResult(existing, cmd);
|
|
712
|
+
if (!existing.result?.schedule.wakeConversationId) {
|
|
713
|
+
fail(
|
|
714
|
+
"--mode wake requires the schedule to already have a wake conversation target; this CLI cannot set one. Create wake schedules with the schedule tool instead.",
|
|
715
|
+
);
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
const body: Record<string, unknown> = {};
|
|
721
|
+
if (opts.name != null) body.name = opts.name;
|
|
722
|
+
if (opts.description != null) body.description = opts.description;
|
|
723
|
+
if (opts.expression != null) body.expression = opts.expression;
|
|
724
|
+
if (opts.timezone != null) body.timezone = opts.timezone;
|
|
725
|
+
if (opts.message != null) body.message = opts.message;
|
|
726
|
+
if (opts.script != null) body.script = opts.script;
|
|
727
|
+
if (opts.mode != null) body.mode = opts.mode;
|
|
728
|
+
if (opts.routingIntent != null) {
|
|
729
|
+
body.routingIntent = opts.routingIntent;
|
|
730
|
+
}
|
|
731
|
+
if (opts.quiet != null) body.quiet = opts.quiet;
|
|
732
|
+
if (opts.reuseConversation != null) {
|
|
733
|
+
body.reuseConversation = opts.reuseConversation;
|
|
734
|
+
}
|
|
735
|
+
if (opts.maxRetries != null) {
|
|
736
|
+
const parsed = parseInteger("--max-retries", opts.maxRetries);
|
|
737
|
+
if (parsed == null) return;
|
|
738
|
+
body.maxRetries = parsed;
|
|
739
|
+
}
|
|
740
|
+
if (opts.retryBackoffMs != null) {
|
|
741
|
+
const parsed = parseInteger(
|
|
742
|
+
"--retry-backoff-ms",
|
|
743
|
+
opts.retryBackoffMs,
|
|
744
|
+
);
|
|
745
|
+
if (parsed == null) return;
|
|
746
|
+
body.retryBackoffMs = parsed;
|
|
747
|
+
}
|
|
748
|
+
if (opts.timeoutMs != null) {
|
|
749
|
+
const parsed = parseInteger("--timeout-ms", opts.timeoutMs);
|
|
750
|
+
if (parsed == null) return;
|
|
751
|
+
body.timeoutMs = parsed;
|
|
752
|
+
}
|
|
753
|
+
if (opts.clearTimeout) body.timeoutMs = null;
|
|
754
|
+
if (opts.profile != null) body.inferenceProfile = opts.profile;
|
|
755
|
+
if (opts.clearProfile) body.inferenceProfile = null;
|
|
756
|
+
|
|
757
|
+
if (Object.keys(body).length === 0) {
|
|
758
|
+
fail(
|
|
759
|
+
"At least one update flag is required. Run 'assistant schedules update --help' for the available flags.",
|
|
760
|
+
);
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
const result = await cliIpcCall<ListSchedulesResponse>(
|
|
765
|
+
"updateSchedule",
|
|
766
|
+
{ pathParams: { id: scheduleId }, body },
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
if (!result.ok) return exitFromIpcResult(result, cmd);
|
|
770
|
+
|
|
771
|
+
const response = result.result ?? { schedules: [] };
|
|
772
|
+
if (opts.json) {
|
|
773
|
+
writeOutput(cmd, response);
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
log.info(`Updated schedule: ${scheduleId}`);
|
|
778
|
+
},
|
|
779
|
+
);
|
|
780
|
+
|
|
434
781
|
schedules
|
|
435
782
|
.command("enable <id>")
|
|
436
783
|
.description("Enable a schedule")
|
|
@@ -701,6 +1048,32 @@ function formatNullableTimestamp(value: number | null): string {
|
|
|
701
1048
|
}
|
|
702
1049
|
|
|
703
1050
|
function formatDuration(value: number | null): string {
|
|
704
|
-
if (value == null || !Number.isFinite(value)) return "—";
|
|
705
|
-
return `${value}ms`;
|
|
1051
|
+
if (value == null || !Number.isFinite(value) || value < 0) return "—";
|
|
1052
|
+
if (value < 1000) return `${Math.round(value)}ms`;
|
|
1053
|
+
|
|
1054
|
+
// Keep one decimal of precision only in the sub-minute range, where it's
|
|
1055
|
+
// meaningful; coarser units round to whole seconds. Working in tenths of a
|
|
1056
|
+
// second lets the tier boundary (e.g. 59.97s) round up cleanly to "1m".
|
|
1057
|
+
const tenths = Math.round(value / 100);
|
|
1058
|
+
if (tenths < 600) {
|
|
1059
|
+
const seconds = tenths / 10;
|
|
1060
|
+
return `${Number.isInteger(seconds) ? seconds : seconds.toFixed(1)}s`;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
const totalSeconds = Math.round(value / 1000);
|
|
1064
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
1065
|
+
const seconds = totalSeconds % 60;
|
|
1066
|
+
if (minutes < 60) {
|
|
1067
|
+
return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
const hours = Math.floor(minutes / 60);
|
|
1071
|
+
const remMinutes = minutes % 60;
|
|
1072
|
+
if (hours < 24) {
|
|
1073
|
+
return remMinutes > 0 ? `${hours}h ${remMinutes}m` : `${hours}h`;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
const days = Math.floor(hours / 24);
|
|
1077
|
+
const remHours = hours % 24;
|
|
1078
|
+
return remHours > 0 ? `${days}d ${remHours}h` : `${days}d`;
|
|
706
1079
|
}
|