@vellumai/assistant 0.5.16 → 0.6.0
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/ARCHITECTURE.md +1 -1
- package/Dockerfile +0 -3
- package/knip.json +2 -1
- package/openapi.yaml +660 -80
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +68 -0
- package/src/__tests__/agent-loop.test.ts +0 -32
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/anthropic-provider.test.ts +57 -3
- package/src/__tests__/app-compiler.test.ts +120 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/call-conversation-messages.test.ts +2 -6
- package/src/__tests__/call-domain.test.ts +2 -6
- package/src/__tests__/call-pointer-messages.test.ts +2 -14
- package/src/__tests__/call-recovery.test.ts +2 -6
- package/src/__tests__/call-routes-http.test.ts +2 -6
- package/src/__tests__/call-store.test.ts +2 -6
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
- package/src/__tests__/canonical-guardian-store.test.ts +2 -6
- package/src/__tests__/channel-delivery-store.test.ts +2 -6
- package/src/__tests__/channel-retry-sweep.test.ts +2 -6
- package/src/__tests__/checker.test.ts +25 -3
- package/src/__tests__/clawhub.test.ts +54 -24
- package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
- package/src/__tests__/cli-memory.test.ts +74 -69
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/config-set-platform-guard.test.ts +302 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
- package/src/__tests__/contacts-tools.test.ts +31 -0
- package/src/__tests__/context-overflow-reducer.test.ts +86 -0
- package/src/__tests__/context-token-estimator.test.ts +175 -10
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
- package/src/__tests__/conversation-agent-loop.test.ts +9 -0
- package/src/__tests__/conversation-attachments.test.ts +2 -6
- package/src/__tests__/conversation-attention-store.test.ts +2 -6
- package/src/__tests__/conversation-clear-safety.test.ts +2 -6
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
- package/src/__tests__/conversation-disk-view.test.ts +2 -6
- package/src/__tests__/conversation-error.test.ts +33 -2
- package/src/__tests__/conversation-fork-crud.test.ts +2 -6
- package/src/__tests__/conversation-history-web-search.test.ts +5 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
- package/src/__tests__/conversation-media-retry.test.ts +91 -0
- package/src/__tests__/conversation-starter-routes.test.ts +20 -11
- package/src/__tests__/conversation-store.test.ts +2 -6
- package/src/__tests__/conversation-usage.test.ts +2 -6
- package/src/__tests__/conversation-wipe.test.ts +11 -408
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
- package/src/__tests__/credential-security-e2e.test.ts +2 -0
- package/src/__tests__/followup-tools.test.ts +2 -6
- package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
- package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
- package/src/__tests__/guardian-action-store.test.ts +2 -6
- package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
- package/src/__tests__/guardian-dispatch.test.ts +2 -6
- package/src/__tests__/guardian-grant-minting.test.ts +2 -14
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
- package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
- package/src/__tests__/guardian-routing-state.test.ts +2 -6
- package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
- package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
- package/src/__tests__/injection-block.test.ts +154 -0
- package/src/__tests__/install-meta.test.ts +506 -0
- package/src/__tests__/install-skill-routing.test.ts +292 -0
- package/src/__tests__/invite-redemption-service.test.ts +2 -6
- package/src/__tests__/invite-routes-http.test.ts +2 -6
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
- package/src/__tests__/list-messages-attachments.test.ts +2 -6
- package/src/__tests__/llm-context-route-provider.test.ts +2 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
- package/src/__tests__/llm-usage-store.test.ts +2 -6
- package/src/__tests__/log-export-workspace.test.ts +2 -6
- package/src/__tests__/managed-store.test.ts +38 -11
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
- package/src/__tests__/memory-recall-log-store.test.ts +2 -6
- package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
- package/src/__tests__/non-member-access-request.test.ts +2 -6
- package/src/__tests__/notification-guardian-path.test.ts +2 -6
- package/src/__tests__/oauth-cli.test.ts +364 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
- package/src/__tests__/outlook-attachments.test.ts +301 -0
- package/src/__tests__/outlook-automation-tools.test.ts +425 -0
- package/src/__tests__/outlook-categories.test.ts +212 -0
- package/src/__tests__/outlook-client-automation.test.ts +246 -0
- package/src/__tests__/outlook-compose-tools.test.ts +325 -0
- package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
- package/src/__tests__/outlook-email-watcher.test.ts +322 -0
- package/src/__tests__/outlook-follow-up.test.ts +196 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
- package/src/__tests__/outlook-trash.test.ts +77 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
- package/src/__tests__/platform-callback-registration.test.ts +4 -4
- package/src/__tests__/playbook-execution.test.ts +76 -80
- package/src/__tests__/playbook-tools.test.ts +5 -7
- package/src/__tests__/provider-error-scenarios.test.ts +21 -0
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
- package/src/__tests__/registry.test.ts +2 -2
- package/src/__tests__/require-fresh-approval.test.ts +64 -2
- package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
- package/src/__tests__/runtime-events-sse.test.ts +2 -6
- package/src/__tests__/schedule-store.test.ts +2 -6
- package/src/__tests__/schedule-tools.test.ts +2 -6
- package/src/__tests__/scheduler-recurrence.test.ts +1 -5
- package/src/__tests__/scoped-approval-grants.test.ts +2 -6
- package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
- package/src/__tests__/search-skills-unified.test.ts +421 -0
- package/src/__tests__/secret-onetime-send.test.ts +2 -0
- package/src/__tests__/send-endpoint-busy.test.ts +2 -6
- package/src/__tests__/sequence-store.test.ts +2 -6
- package/src/__tests__/server-history-render.test.ts +2 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +11 -11
- package/src/__tests__/skill-memory.test.ts +140 -98
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/skills.test.ts +1 -1
- package/src/__tests__/slack-inbound-verification.test.ts +2 -6
- package/src/__tests__/task-compiler.test.ts +2 -6
- package/src/__tests__/task-management-tools.test.ts +2 -6
- package/src/__tests__/task-memory-cleanup.test.ts +173 -229
- package/src/__tests__/task-runner.test.ts +2 -6
- package/src/__tests__/task-scheduler.test.ts +2 -6
- package/src/__tests__/test-preload.ts +3 -0
- package/src/__tests__/tool-approval-handler.test.ts +2 -6
- package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
- package/src/__tests__/trust-store.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
- package/src/__tests__/trusted-contact-verification.test.ts +2 -6
- package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
- package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
- package/src/__tests__/usage-routes.test.ts +2 -6
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +2 -6
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
- package/src/__tests__/voice-session-bridge.test.ts +2 -6
- package/src/__tests__/volume-security-guard.test.ts +2 -0
- package/src/__tests__/workspace-lifecycle.test.ts +29 -1
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
- package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
- package/src/__tests__/workspace-policy.test.ts +1 -1
- package/src/agent/attachments.ts +7 -2
- package/src/agent/image-optimize.ts +165 -0
- package/src/agent/loop.ts +1 -15
- package/src/bundler/app-compiler.ts +179 -2
- package/src/bundler/package-resolver.ts +3 -5
- package/src/cli/__tests__/notifications.test.ts +1 -2
- package/src/cli/cli-memory.ts +67 -64
- package/src/cli/commands/avatar.ts +3 -3
- package/src/cli/commands/config.ts +26 -13
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/memory.ts +41 -55
- package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
- package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
- package/src/cli/commands/oauth/connect.ts +11 -6
- package/src/cli/commands/oauth/mode.ts +7 -0
- package/src/cli/commands/oauth/shared.ts +39 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
- package/src/cli/commands/platform/index.ts +16 -16
- package/src/cli/commands/skills.ts +88 -16
- package/src/cli/commands/trust.ts +2 -2
- package/src/cli/lib/daemon-credential-client.ts +2 -3
- package/src/config/bundled-skills/acp/TOOLS.json +1 -1
- package/src/config/bundled-skills/contacts/SKILL.md +0 -1
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
- package/src/config/bundled-skills/gmail/SKILL.md +2 -10
- package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
- package/src/config/bundled-skills/messaging/SKILL.md +10 -18
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
- package/src/config/bundled-skills/outlook/SKILL.md +189 -0
- package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
- package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
- package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
- package/src/config/bundled-skills/slack/SKILL.md +1 -7
- package/src/config/bundled-tool-registry.ts +56 -4
- package/src/config/env-registry.ts +15 -8
- package/src/config/feature-flag-registry.json +21 -124
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/config/skills.ts +18 -7
- package/src/context/token-estimator.ts +25 -18
- package/src/context/window-manager.ts +6 -2
- package/src/credential-execution/process-manager.ts +3 -1
- package/src/daemon/context-overflow-reducer.ts +46 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
- package/src/daemon/conversation-agent-loop.ts +96 -61
- package/src/daemon/conversation-error.ts +31 -8
- package/src/daemon/conversation-lifecycle.ts +33 -0
- package/src/daemon/conversation-media-retry.ts +85 -7
- package/src/daemon/conversation-notifiers.ts +4 -1
- package/src/daemon/conversation-runtime-assembly.ts +5 -0
- package/src/daemon/conversation.ts +41 -2
- package/src/daemon/daemon-control.ts +8 -2
- package/src/daemon/handlers/shared.ts +22 -12
- package/src/daemon/handlers/skills.ts +416 -202
- package/src/daemon/lifecycle.ts +40 -1
- package/src/daemon/main.ts +5 -1
- package/src/daemon/message-types/conversations.ts +4 -1
- package/src/daemon/message-types/messages.ts +3 -1
- package/src/daemon/message-types/skills.ts +97 -36
- package/src/daemon/providers-setup.ts +5 -0
- package/src/daemon/server.ts +11 -2
- package/src/daemon/tool-side-effects.ts +27 -5
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/hooks/cli.ts +2 -2
- package/src/hooks/runner.ts +15 -38
- package/src/inbound/platform-callback-registration.ts +14 -14
- package/src/memory/admin.ts +11 -45
- package/src/memory/conversation-bootstrap.ts +2 -0
- package/src/memory/conversation-crud.ts +242 -348
- package/src/memory/conversation-group-migration.ts +157 -0
- package/src/memory/conversation-queries.ts +4 -2
- package/src/memory/db-init.ts +30 -3
- package/src/memory/embed.ts +73 -0
- package/src/memory/embedding-backend.ts +8 -14
- package/src/memory/embedding-runtime-manager.ts +12 -114
- package/src/memory/fingerprint.ts +2 -2
- package/src/memory/graph/bootstrap.ts +512 -0
- package/src/memory/graph/capability-seed.ts +297 -0
- package/src/memory/graph/consolidation.ts +691 -0
- package/src/memory/graph/conversation-graph-memory.ts +630 -0
- package/src/memory/graph/decay.test.ts +208 -0
- package/src/memory/graph/decay.ts +195 -0
- package/src/memory/graph/extraction-job.ts +69 -0
- package/src/memory/graph/extraction.test.ts +936 -0
- package/src/memory/graph/extraction.ts +1254 -0
- package/src/memory/graph/graph-search.ts +266 -0
- package/src/memory/graph/image-ref-utils.ts +29 -0
- package/src/memory/graph/injection.test.ts +513 -0
- package/src/memory/graph/injection.ts +439 -0
- package/src/memory/graph/inspect.ts +534 -0
- package/src/memory/graph/narrative.ts +267 -0
- package/src/memory/graph/pattern-scan.ts +269 -0
- package/src/memory/graph/retriever.ts +1008 -0
- package/src/memory/graph/scoring.test.ts +548 -0
- package/src/memory/graph/scoring.ts +232 -0
- package/src/memory/graph/serendipity.ts +65 -0
- package/src/memory/graph/store.test.ts +1050 -0
- package/src/memory/graph/store.ts +699 -0
- package/src/memory/graph/tool-handlers.ts +426 -0
- package/src/memory/graph/tools.ts +141 -0
- package/src/memory/graph/triggers.test.ts +487 -0
- package/src/memory/graph/triggers.ts +223 -0
- package/src/memory/graph/types.ts +271 -0
- package/src/memory/group-crud.ts +191 -0
- package/src/memory/indexer.ts +37 -19
- package/src/memory/job-handlers/cleanup.ts +0 -53
- package/src/memory/job-handlers/conversation-starters.ts +91 -53
- package/src/memory/job-handlers/embedding.ts +5 -31
- package/src/memory/job-handlers/index-maintenance.ts +23 -11
- package/src/memory/job-handlers/summarization.ts +32 -17
- package/src/memory/job-utils.ts +1 -1
- package/src/memory/jobs-store.ts +50 -70
- package/src/memory/jobs-worker.ts +147 -112
- package/src/memory/message-content.ts +1 -0
- package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
- package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
- package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
- package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/qdrant-client.ts +44 -17
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/memory-graph.ts +139 -0
- package/src/memory/search/semantic.ts +47 -91
- package/src/memory/task-memory-cleanup.ts +28 -50
- package/src/messaging/providers/outlook/adapter.ts +8 -1
- package/src/messaging/providers/outlook/client.ts +299 -0
- package/src/messaging/providers/outlook/types.ts +118 -0
- package/src/notifications/adapters/macos.ts +1 -0
- package/src/notifications/copy-composer.ts +9 -0
- package/src/notifications/signal.ts +16 -0
- package/src/oauth/seed-providers.ts +2 -1
- package/src/permissions/checker.ts +24 -3
- package/src/permissions/defaults.ts +4 -4
- package/src/permissions/workspace-policy.ts +1 -1
- package/src/playbooks/playbook-compiler.ts +19 -18
- package/src/playbooks/types.ts +4 -3
- package/src/prompts/system-prompt.ts +3 -29
- package/src/providers/anthropic/client.ts +47 -19
- package/src/providers/gemini/client.ts +1 -1
- package/src/providers/openai/client.ts +1 -1
- package/src/providers/registry.ts +1 -1
- package/src/providers/retry.ts +19 -3
- package/src/runtime/actor-trust-resolver.ts +5 -1
- package/src/runtime/auth/route-policy.ts +7 -0
- package/src/runtime/guardian-reply-router.ts +5 -1
- package/src/runtime/http-server.ts +23 -3
- package/src/runtime/middleware/auth.ts +20 -0
- package/src/runtime/routes/attachment-routes.test.ts +106 -0
- package/src/runtime/routes/attachment-routes.ts +106 -16
- package/src/runtime/routes/brain-graph-routes.ts +21 -22
- package/src/runtime/routes/btw-routes.ts +8 -0
- package/src/runtime/routes/conversation-management-routes.ts +2 -0
- package/src/runtime/routes/conversation-starter-routes.ts +2 -2
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/global-search-routes.ts +21 -19
- package/src/runtime/routes/group-routes.ts +207 -0
- package/src/runtime/routes/guardian-action-routes.ts +21 -10
- package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
- package/src/runtime/routes/inbound-message-handler.ts +19 -0
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
- package/src/runtime/routes/memory-item-routes.test.ts +2 -14
- package/src/runtime/routes/memory-item-routes.ts +341 -388
- package/src/runtime/routes/schedule-routes.ts +2 -0
- package/src/runtime/routes/skills-routes.ts +103 -37
- package/src/runtime/routes/work-items-routes.test.ts +2 -6
- package/src/schedule/scheduler.ts +8 -1
- package/src/security/oauth2.ts +1 -1
- package/src/security/secure-keys.ts +4 -8
- package/src/shared/provider-env-vars.ts +19 -0
- package/src/skills/catalog-cache.ts +5 -0
- package/src/skills/catalog-install.ts +15 -14
- package/src/skills/clawhub.ts +134 -154
- package/src/skills/install-meta.ts +208 -0
- package/src/skills/managed-store.ts +27 -16
- package/src/skills/skill-memory.ts +152 -77
- package/src/skills/skillssh-registry.ts +19 -17
- package/src/tasks/task-runner.ts +3 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
- package/src/tools/browser/runtime-check.ts +3 -1
- package/src/tools/memory/register.ts +63 -46
- package/src/tools/permission-checker.ts +7 -1
- package/src/tools/shared/filesystem/image-read.ts +22 -85
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/tool-manifest.ts +3 -3
- package/src/util/browser.ts +25 -10
- package/src/util/bun-runtime.ts +172 -0
- package/src/watcher/providers/outlook-calendar.ts +343 -0
- package/src/watcher/providers/outlook.ts +198 -0
- package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
- package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
- package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/context-memory-e2e.test.ts +0 -415
- package/src/__tests__/journal-context.test.ts +0 -268
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
- package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
- package/src/__tests__/memory-query-builder.test.ts +0 -59
- package/src/__tests__/memory-recall-quality.test.ts +0 -1046
- package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
- package/src/__tests__/memory-regressions.test.ts +0 -3696
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
- package/src/daemon/conversation-memory.ts +0 -207
- package/src/memory/conversation-starters-cadence.ts +0 -74
- package/src/memory/items-extractor.ts +0 -860
- package/src/memory/job-handlers/batch-extraction.ts +0 -753
- package/src/memory/job-handlers/extraction.ts +0 -40
- package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
- package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
- package/src/memory/journal-memory.ts +0 -224
- package/src/memory/query-builder.ts +0 -47
- package/src/memory/query-expansion.ts +0 -83
- package/src/memory/retriever.test.ts +0 -1592
- package/src/memory/retriever.ts +0 -1331
- package/src/memory/search/formatting.test.ts +0 -140
- package/src/memory/search/formatting.ts +0 -262
- package/src/memory/search/mmr.ts +0 -139
- package/src/memory/search/ranking.ts +0 -15
- package/src/memory/search/staleness.ts +0 -40
- package/src/memory/search/tier-classifier.ts +0 -18
- package/src/memory/search/types.ts +0 -121
- package/src/prompts/journal-context.ts +0 -154
- package/src/tools/memory/definitions.ts +0 -69
- package/src/tools/memory/handlers.test.ts +0 -562
- package/src/tools/memory/handlers.ts +0 -434
|
@@ -56,7 +56,7 @@ import * as contactMerge from "./bundled-skills/contacts/tools/contact-merge.js"
|
|
|
56
56
|
import * as contactSearch from "./bundled-skills/contacts/tools/contact-search.js";
|
|
57
57
|
import * as contactUpsert from "./bundled-skills/contacts/tools/contact-upsert.js";
|
|
58
58
|
import * as googleContacts from "./bundled-skills/contacts/tools/google-contacts.js";
|
|
59
|
-
// ── conversations
|
|
59
|
+
// ── conversations ──────────────────────────────────────────────────────────────
|
|
60
60
|
import * as renameConversation from "./bundled-skills/conversations/tools/rename-conversation.js";
|
|
61
61
|
// ── document ───────────────────────────────────────────────────────────────────
|
|
62
62
|
import * as documentCreate from "./bundled-skills/document/tools/document-create.js";
|
|
@@ -107,6 +107,25 @@ import * as messagingSend from "./bundled-skills/messaging/tools/messaging-send.
|
|
|
107
107
|
import * as messagingSenderDigest from "./bundled-skills/messaging/tools/messaging-sender-digest.js";
|
|
108
108
|
// ── notifications ──────────────────────────────────────────────────────────────
|
|
109
109
|
import * as sendNotification from "./bundled-skills/notifications/tools/send-notification.js";
|
|
110
|
+
// ── outlook ────────────────────────────────────────────────────────────────────
|
|
111
|
+
import * as outlookAttachments from "./bundled-skills/outlook/tools/outlook-attachments.js";
|
|
112
|
+
import * as outlookCategories from "./bundled-skills/outlook/tools/outlook-categories.js";
|
|
113
|
+
import * as outlookDraft from "./bundled-skills/outlook/tools/outlook-draft.js";
|
|
114
|
+
import * as outlookFollowUp from "./bundled-skills/outlook/tools/outlook-follow-up.js";
|
|
115
|
+
import * as outlookForward from "./bundled-skills/outlook/tools/outlook-forward.js";
|
|
116
|
+
import * as outlookOutreachScan from "./bundled-skills/outlook/tools/outlook-outreach-scan.js";
|
|
117
|
+
import * as outlookRules from "./bundled-skills/outlook/tools/outlook-rules.js";
|
|
118
|
+
import * as outlookSendDraft from "./bundled-skills/outlook/tools/outlook-send-draft.js";
|
|
119
|
+
import * as outlookSenderDigest from "./bundled-skills/outlook/tools/outlook-sender-digest.js";
|
|
120
|
+
import * as outlookTrash from "./bundled-skills/outlook/tools/outlook-trash.js";
|
|
121
|
+
import * as outlookUnsubscribe from "./bundled-skills/outlook/tools/outlook-unsubscribe.js";
|
|
122
|
+
import * as outlookVacation from "./bundled-skills/outlook/tools/outlook-vacation.js";
|
|
123
|
+
// ── outlook-calendar ───────────────────────────────────────────────────────────
|
|
124
|
+
import * as outlookCalendarCheckAvailability from "./bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.js";
|
|
125
|
+
import * as outlookCalendarCreateEvent from "./bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.js";
|
|
126
|
+
import * as outlookCalendarGetEvent from "./bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.js";
|
|
127
|
+
import * as outlookCalendarListEvents from "./bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.js";
|
|
128
|
+
import * as outlookCalendarRsvp from "./bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.js";
|
|
110
129
|
// ── phone-calls ────────────────────────────────────────────────────────────────
|
|
111
130
|
import * as callEnd from "./bundled-skills/phone-calls/tools/call-end.js";
|
|
112
131
|
import * as callStart from "./bundled-skills/phone-calls/tools/call-start.js";
|
|
@@ -290,6 +309,39 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
|
|
|
290
309
|
// notifications
|
|
291
310
|
["notifications:tools/send-notification.ts", sendNotification],
|
|
292
311
|
|
|
312
|
+
// outlook
|
|
313
|
+
["outlook:tools/outlook-rules.ts", outlookRules],
|
|
314
|
+
["outlook:tools/outlook-vacation.ts", outlookVacation],
|
|
315
|
+
["outlook:tools/outlook-sender-digest.ts", outlookSenderDigest],
|
|
316
|
+
["outlook:tools/outlook-outreach-scan.ts", outlookOutreachScan],
|
|
317
|
+
["outlook:tools/outlook-draft.ts", outlookDraft],
|
|
318
|
+
["outlook:tools/outlook-send-draft.ts", outlookSendDraft],
|
|
319
|
+
["outlook:tools/outlook-forward.ts", outlookForward],
|
|
320
|
+
["outlook:tools/outlook-trash.ts", outlookTrash],
|
|
321
|
+
["outlook:tools/outlook-categories.ts", outlookCategories],
|
|
322
|
+
["outlook:tools/outlook-follow-up.ts", outlookFollowUp],
|
|
323
|
+
["outlook:tools/outlook-unsubscribe.ts", outlookUnsubscribe],
|
|
324
|
+
["outlook:tools/outlook-attachments.ts", outlookAttachments],
|
|
325
|
+
|
|
326
|
+
// outlook-calendar
|
|
327
|
+
[
|
|
328
|
+
"outlook-calendar:tools/outlook-calendar-list-events.ts",
|
|
329
|
+
outlookCalendarListEvents,
|
|
330
|
+
],
|
|
331
|
+
[
|
|
332
|
+
"outlook-calendar:tools/outlook-calendar-get-event.ts",
|
|
333
|
+
outlookCalendarGetEvent,
|
|
334
|
+
],
|
|
335
|
+
[
|
|
336
|
+
"outlook-calendar:tools/outlook-calendar-create-event.ts",
|
|
337
|
+
outlookCalendarCreateEvent,
|
|
338
|
+
],
|
|
339
|
+
[
|
|
340
|
+
"outlook-calendar:tools/outlook-calendar-check-availability.ts",
|
|
341
|
+
outlookCalendarCheckAvailability,
|
|
342
|
+
],
|
|
343
|
+
["outlook-calendar:tools/outlook-calendar-rsvp.ts", outlookCalendarRsvp],
|
|
344
|
+
|
|
293
345
|
// phone-calls
|
|
294
346
|
["phone-calls:tools/call-start.ts", callStart],
|
|
295
347
|
["phone-calls:tools/call-status.ts", callStatus],
|
|
@@ -322,12 +374,12 @@ export const bundledToolRegistry = new Map<string, SkillToolScript>([
|
|
|
322
374
|
["sequences:tools/sequence-analytics.ts", sequenceAnalytics],
|
|
323
375
|
|
|
324
376
|
// settings
|
|
325
|
-
["settings:tools/avatar-get.ts", avatarGet],
|
|
326
|
-
["settings:tools/avatar-update.ts", avatarUpdate],
|
|
327
|
-
["settings:tools/avatar-remove.ts", avatarRemove],
|
|
328
377
|
["settings:tools/voice-config-update.ts", voiceConfigUpdate],
|
|
329
378
|
["settings:tools/open-system-settings.ts", openSystemSettings],
|
|
330
379
|
["settings:tools/navigate-settings-tab.ts", navigateSettingsTab],
|
|
380
|
+
["settings:tools/avatar-update.ts", avatarUpdate],
|
|
381
|
+
["settings:tools/avatar-remove.ts", avatarRemove],
|
|
382
|
+
["settings:tools/avatar-get.ts", avatarGet],
|
|
331
383
|
|
|
332
384
|
// skill-management
|
|
333
385
|
["skill-management:tools/scaffold-managed.ts", scaffoldManaged],
|
|
@@ -45,17 +45,24 @@ export function getIsContainerized(): boolean {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
48
|
+
* IS_PLATFORM — boolean, default: false
|
|
49
|
+
* When true, indicates the assistant is running as a platform-managed
|
|
50
|
+
* remote instance. Controls platform-specific behaviors like webhook
|
|
51
|
+
* callback registration and blocking `platform disconnect`.
|
|
49
52
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
* Separate from IS_CONTAINERIZED because local Docker assistants are
|
|
54
|
+
* containerized (need CES sidecar, gateway trust store, etc.) but are
|
|
55
|
+
* not platform-managed.
|
|
56
|
+
*/
|
|
57
|
+
export function getIsPlatform(): boolean {
|
|
58
|
+
return flag("IS_PLATFORM");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Whether this assistant is running as a platform-managed remote instance.
|
|
56
63
|
*/
|
|
57
64
|
export function isPlatformRemote(): boolean {
|
|
58
|
-
return
|
|
65
|
+
return getIsPlatform();
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
/**
|
|
@@ -17,14 +17,6 @@
|
|
|
17
17
|
"description": "Enable user-hosted onboarding flow",
|
|
18
18
|
"defaultEnabled": false
|
|
19
19
|
},
|
|
20
|
-
{
|
|
21
|
-
"id": "platform-hosted-enabled",
|
|
22
|
-
"scope": "macos",
|
|
23
|
-
"key": "platform-hosted-enabled",
|
|
24
|
-
"label": "Platform Hosted Assistants",
|
|
25
|
-
"description": "Enable the Vellum Cloud hosting option on the Hosting screen",
|
|
26
|
-
"defaultEnabled": false
|
|
27
|
-
},
|
|
28
20
|
{
|
|
29
21
|
"id": "local-docker-enabled",
|
|
30
22
|
"scope": "macos",
|
|
@@ -33,14 +25,6 @@
|
|
|
33
25
|
"description": "When enabled, the Local hosting option uses Docker under the hood for sandboxed execution, hiding the separate Docker card",
|
|
34
26
|
"defaultEnabled": false
|
|
35
27
|
},
|
|
36
|
-
{
|
|
37
|
-
"id": "contacts",
|
|
38
|
-
"scope": "assistant",
|
|
39
|
-
"key": "contacts",
|
|
40
|
-
"label": "Contacts",
|
|
41
|
-
"description": "Show the Contacts tab in Settings for viewing and managing contacts",
|
|
42
|
-
"defaultEnabled": true
|
|
43
|
-
},
|
|
44
28
|
{
|
|
45
29
|
"id": "email-channel",
|
|
46
30
|
"scope": "assistant",
|
|
@@ -145,102 +129,6 @@
|
|
|
145
129
|
"description": "Enable managed (organization-hosted) sign-in flow in the onboarding experience",
|
|
146
130
|
"defaultEnabled": true
|
|
147
131
|
},
|
|
148
|
-
{
|
|
149
|
-
"id": "integration-twitter",
|
|
150
|
-
"scope": "assistant",
|
|
151
|
-
"key": "integration-twitter",
|
|
152
|
-
"label": "Twitter / X Integration",
|
|
153
|
-
"description": "Enable the Twitter / X OAuth setup skill for connecting to the Twitter API",
|
|
154
|
-
"defaultEnabled": false
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
"id": "integration-github",
|
|
158
|
-
"scope": "assistant",
|
|
159
|
-
"key": "integration-github",
|
|
160
|
-
"label": "GitHub Integration",
|
|
161
|
-
"description": "Enable the GitHub OAuth setup skill for connecting to GitHub",
|
|
162
|
-
"defaultEnabled": false
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
"id": "integration-linear",
|
|
166
|
-
"scope": "assistant",
|
|
167
|
-
"key": "integration-linear",
|
|
168
|
-
"label": "Linear Integration",
|
|
169
|
-
"description": "Enable the Linear OAuth setup skill for connecting to Linear",
|
|
170
|
-
"defaultEnabled": false
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
"id": "integration-spotify",
|
|
174
|
-
"scope": "assistant",
|
|
175
|
-
"key": "integration-spotify",
|
|
176
|
-
"label": "Spotify Integration",
|
|
177
|
-
"description": "Enable the Spotify OAuth setup skill for connecting to the Spotify API",
|
|
178
|
-
"defaultEnabled": false
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
"id": "integration-todoist",
|
|
182
|
-
"scope": "assistant",
|
|
183
|
-
"key": "integration-todoist",
|
|
184
|
-
"label": "Todoist Integration",
|
|
185
|
-
"description": "Enable the Todoist OAuth setup skill for connecting to Todoist",
|
|
186
|
-
"defaultEnabled": false
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
"id": "integration-discord",
|
|
190
|
-
"scope": "assistant",
|
|
191
|
-
"key": "integration-discord",
|
|
192
|
-
"label": "Discord Integration",
|
|
193
|
-
"description": "Enable the Discord OAuth setup skill for connecting to Discord",
|
|
194
|
-
"defaultEnabled": false
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
"id": "integration-dropbox",
|
|
198
|
-
"scope": "assistant",
|
|
199
|
-
"key": "integration-dropbox",
|
|
200
|
-
"label": "Dropbox Integration",
|
|
201
|
-
"description": "Enable the Dropbox OAuth setup skill for connecting to Dropbox",
|
|
202
|
-
"defaultEnabled": false
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
"id": "integration-asana",
|
|
206
|
-
"scope": "assistant",
|
|
207
|
-
"key": "integration-asana",
|
|
208
|
-
"label": "Asana Integration",
|
|
209
|
-
"description": "Enable the Asana OAuth setup skill for connecting to Asana",
|
|
210
|
-
"defaultEnabled": false
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
"id": "integration-airtable",
|
|
214
|
-
"scope": "assistant",
|
|
215
|
-
"key": "integration-airtable",
|
|
216
|
-
"label": "Airtable Integration",
|
|
217
|
-
"description": "Enable the Airtable OAuth setup skill for connecting to Airtable",
|
|
218
|
-
"defaultEnabled": false
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
"id": "integration-hubspot",
|
|
222
|
-
"scope": "assistant",
|
|
223
|
-
"key": "integration-hubspot",
|
|
224
|
-
"label": "HubSpot Integration",
|
|
225
|
-
"description": "Enable the HubSpot OAuth setup skill for connecting to HubSpot CRM",
|
|
226
|
-
"defaultEnabled": false
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
"id": "integration-figma",
|
|
230
|
-
"scope": "assistant",
|
|
231
|
-
"key": "integration-figma",
|
|
232
|
-
"label": "Figma Integration",
|
|
233
|
-
"description": "Enable the Figma OAuth setup skill for connecting to Figma",
|
|
234
|
-
"defaultEnabled": false
|
|
235
|
-
},
|
|
236
|
-
{
|
|
237
|
-
"id": "integration-notion",
|
|
238
|
-
"scope": "assistant",
|
|
239
|
-
"key": "integration-notion",
|
|
240
|
-
"label": "Notion Integration",
|
|
241
|
-
"description": "Enable the Notion setup skill for connecting to Notion",
|
|
242
|
-
"defaultEnabled": false
|
|
243
|
-
},
|
|
244
132
|
{
|
|
245
133
|
"id": "conversation-starters",
|
|
246
134
|
"scope": "assistant",
|
|
@@ -281,6 +169,14 @@
|
|
|
281
169
|
"description": "Show the Schedules tab in Settings for viewing and managing schedules",
|
|
282
170
|
"defaultEnabled": false
|
|
283
171
|
},
|
|
172
|
+
{
|
|
173
|
+
"id": "settings-integrations-grid",
|
|
174
|
+
"scope": "assistant",
|
|
175
|
+
"key": "settings-integrations-grid",
|
|
176
|
+
"label": "Integrations Grid",
|
|
177
|
+
"description": "Show the Integrations grid in Models & Services settings, replacing individual OAuth provider cards",
|
|
178
|
+
"defaultEnabled": false
|
|
179
|
+
},
|
|
284
180
|
{
|
|
285
181
|
"id": "quick-input",
|
|
286
182
|
"scope": "macos",
|
|
@@ -345,14 +241,6 @@
|
|
|
345
241
|
"description": "Show older versions in the version picker, allowing rollback to previous releases",
|
|
346
242
|
"defaultEnabled": true
|
|
347
243
|
},
|
|
348
|
-
{
|
|
349
|
-
"id": "show-background-conversations",
|
|
350
|
-
"scope": "assistant",
|
|
351
|
-
"key": "show-background-conversations",
|
|
352
|
-
"label": "Show Background Conversations",
|
|
353
|
-
"description": "Include background conversations (heartbeat, tasks) in the sidebar conversation list",
|
|
354
|
-
"defaultEnabled": false
|
|
355
|
-
},
|
|
356
244
|
{
|
|
357
245
|
"id": "voice-mode",
|
|
358
246
|
"scope": "assistant",
|
|
@@ -370,12 +258,21 @@
|
|
|
370
258
|
"defaultEnabled": false
|
|
371
259
|
},
|
|
372
260
|
{
|
|
373
|
-
"id": "
|
|
261
|
+
"id": "conversation-groups-ui",
|
|
374
262
|
"scope": "assistant",
|
|
375
|
-
"key": "
|
|
376
|
-
"label": "
|
|
377
|
-
"description": "Enable
|
|
263
|
+
"key": "conversation-groups-ui",
|
|
264
|
+
"label": "Conversation Groups",
|
|
265
|
+
"description": "Enable custom conversation group creation, move-to-group, and group management in the sidebar",
|
|
266
|
+
"defaultEnabled": false
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"id": "teleport",
|
|
270
|
+
"scope": "macos",
|
|
271
|
+
"key": "teleport",
|
|
272
|
+
"label": "Teleport",
|
|
273
|
+
"description": "Enable teleport UI in General settings for moving assistants between hosting environments",
|
|
378
274
|
"defaultEnabled": false
|
|
379
275
|
}
|
|
380
276
|
]
|
|
381
277
|
}
|
|
278
|
+
|
|
@@ -56,6 +56,14 @@ export const UiConfigSchema = z
|
|
|
56
56
|
.describe(
|
|
57
57
|
"IANA timezone identifier for displaying dates and times (e.g. 'America/New_York')",
|
|
58
58
|
),
|
|
59
|
+
greetingModelIntent: z
|
|
60
|
+
.enum(["latency-optimized", "quality-optimized"], {
|
|
61
|
+
error: "ui.greetingModelIntent must be 'latency-optimized' or 'quality-optimized'",
|
|
62
|
+
})
|
|
63
|
+
.default("latency-optimized")
|
|
64
|
+
.describe(
|
|
65
|
+
"Model intent for empty-state greeting generation (latency-optimized = fast/small model, quality-optimized = primary model)",
|
|
66
|
+
),
|
|
59
67
|
})
|
|
60
68
|
.describe("User interface display settings");
|
|
61
69
|
|
|
@@ -36,7 +36,7 @@ export const TimeoutConfigSchema = z
|
|
|
36
36
|
.number({ error: "timeouts.providerStreamTimeoutSec must be a number" })
|
|
37
37
|
.finite("timeouts.providerStreamTimeoutSec must be finite")
|
|
38
38
|
.positive("timeouts.providerStreamTimeoutSec must be a positive number")
|
|
39
|
-
.default(
|
|
39
|
+
.default(1800)
|
|
40
40
|
.describe(
|
|
41
41
|
"Timeout for waiting on the LLM provider's streaming response (seconds)",
|
|
42
42
|
),
|
package/src/config/skills.ts
CHANGED
|
@@ -73,7 +73,6 @@ export interface SkillSummary {
|
|
|
73
73
|
bundled?: boolean;
|
|
74
74
|
icon?: string;
|
|
75
75
|
emoji?: string;
|
|
76
|
-
homepage?: string;
|
|
77
76
|
source: SkillSource;
|
|
78
77
|
/** Parsed tool manifest metadata, if the skill has a valid TOOLS.json. */
|
|
79
78
|
toolManifest?: SkillToolManifestMeta;
|
|
@@ -962,8 +961,9 @@ function isEscapingSymlink(filePath: string, rootDir: string): boolean {
|
|
|
962
961
|
/**
|
|
963
962
|
* Check for a `references/` subdirectory within a skill directory and return
|
|
964
963
|
* a formatted listing of available `.md` reference files with full absolute
|
|
965
|
-
* paths. Returns `null` if no references exist. Files are
|
|
966
|
-
*
|
|
964
|
+
* paths. Returns `null` if no references exist. Files are discovered
|
|
965
|
+
* recursively through subdirectories and listed alphabetically within each
|
|
966
|
+
* directory level. Non-`.md` files are ignored. Symlinks that resolve
|
|
967
967
|
* outside the skill directory are skipped.
|
|
968
968
|
*/
|
|
969
969
|
export function listReferenceFiles(directoryPath: string): string | null {
|
|
@@ -977,10 +977,21 @@ export function listReferenceFiles(directoryPath: string): string | null {
|
|
|
977
977
|
return null;
|
|
978
978
|
}
|
|
979
979
|
|
|
980
|
-
const entries = readdirSync(refsDir);
|
|
980
|
+
const entries = readdirSync(refsDir, { recursive: true }) as string[];
|
|
981
981
|
const mdFiles = entries
|
|
982
982
|
.filter((f) => f.toLowerCase().endsWith(".md"))
|
|
983
|
-
.filter((f) =>
|
|
983
|
+
.filter((f) => {
|
|
984
|
+
// Check the file itself
|
|
985
|
+
if (isEscapingSymlink(join(refsDir, f), directoryPath)) return false;
|
|
986
|
+
// Check all intermediate directory components (e.g. for "sub/dir/file.md"
|
|
987
|
+
// check "sub" and "sub/dir") to prevent traversal through symlinked dirs.
|
|
988
|
+
const parts = f.split("/");
|
|
989
|
+
for (let i = 1; i < parts.length; i++) {
|
|
990
|
+
const ancestor = join(refsDir, ...parts.slice(0, i));
|
|
991
|
+
if (isEscapingSymlink(ancestor, directoryPath)) return false;
|
|
992
|
+
}
|
|
993
|
+
return true;
|
|
994
|
+
})
|
|
984
995
|
.sort((a, b) => a.localeCompare(b));
|
|
985
996
|
|
|
986
997
|
if (mdFiles.length === 0) return null;
|
|
@@ -991,8 +1002,8 @@ export function listReferenceFiles(directoryPath: string): string | null {
|
|
|
991
1002
|
"The following reference files are available in this skill's directory. Use `file_read` to load any that are relevant to the current task:",
|
|
992
1003
|
"",
|
|
993
1004
|
];
|
|
994
|
-
for (const
|
|
995
|
-
lines.push(`- \`${join(refsDir,
|
|
1005
|
+
for (const filepath of mdFiles) {
|
|
1006
|
+
lines.push(`- \`${join(refsDir, filepath)}\` (references/${filepath})`);
|
|
996
1007
|
}
|
|
997
1008
|
|
|
998
1009
|
return lines.join("\n");
|
|
@@ -9,7 +9,6 @@ const CHARS_PER_TOKEN = 4;
|
|
|
9
9
|
const MESSAGE_OVERHEAD_TOKENS = 4;
|
|
10
10
|
const TEXT_BLOCK_OVERHEAD_TOKENS = 2;
|
|
11
11
|
const TOOL_BLOCK_OVERHEAD_TOKENS = 16;
|
|
12
|
-
const IMAGE_BLOCK_TOKENS = 1024;
|
|
13
12
|
const IMAGE_BLOCK_OVERHEAD_TOKENS = 16;
|
|
14
13
|
const FILE_BLOCK_OVERHEAD_TOKENS = 48;
|
|
15
14
|
const WEB_SEARCH_RESULT_TOKENS = 800;
|
|
@@ -20,12 +19,15 @@ const GEMINI_INLINE_FILE_MIME_TYPES = new Set(["application/pdf"]);
|
|
|
20
19
|
// Anthropic scales images to fit within 1568x1568 maintaining aspect ratio,
|
|
21
20
|
// then charges ~(width * height) / 750 tokens.
|
|
22
21
|
const ANTHROPIC_IMAGE_MAX_DIMENSION = 1568;
|
|
22
|
+
// Anthropic caps images at ~1.2 megapixels in addition to the 1568px dimension limit.
|
|
23
|
+
// Images exceeding this are further scaled down. The docs state images above ~1,600 tokens
|
|
24
|
+
// are resized. 1,200,000 / 750 = 1,600 tokens, matching the documented threshold.
|
|
25
|
+
// Reference table (max sizes that won't be resized):
|
|
26
|
+
// 1:1 → 1092x1092 (~1,590 tokens) 1:2 → 784x1568 (~1,639 tokens)
|
|
27
|
+
// See: https://platform.claude.com/docs/en/build-with-claude/vision#evaluate-image-size
|
|
28
|
+
const ANTHROPIC_IMAGE_MAX_PIXELS = 1_200_000;
|
|
23
29
|
const ANTHROPIC_IMAGE_TOKENS_PER_PIXEL = 1 / 750;
|
|
24
|
-
const ANTHROPIC_IMAGE_MAX_TOKENS =
|
|
25
|
-
ANTHROPIC_IMAGE_MAX_DIMENSION *
|
|
26
|
-
ANTHROPIC_IMAGE_MAX_DIMENSION *
|
|
27
|
-
ANTHROPIC_IMAGE_TOKENS_PER_PIXEL,
|
|
28
|
-
); // ~3,277 tokens
|
|
30
|
+
const ANTHROPIC_IMAGE_MAX_TOKENS = 1_600;
|
|
29
31
|
|
|
30
32
|
// Anthropic renders each PDF page as an image (~1,568 tokens at standard
|
|
31
33
|
// resolution) plus any extracted text. Typical PDF pages are 50-150 KB.
|
|
@@ -85,17 +87,23 @@ function estimateFileDataTokens(
|
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
function estimateAnthropicImageTokens(width: number, height: number): number {
|
|
88
|
-
// Scale
|
|
89
|
-
const
|
|
90
|
+
// Step 1: Scale to fit within 1568px bounding box
|
|
91
|
+
const dimScale = Math.min(
|
|
90
92
|
1,
|
|
91
93
|
ANTHROPIC_IMAGE_MAX_DIMENSION / Math.max(width, height),
|
|
92
94
|
);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
)
|
|
95
|
+
let scaledWidth = Math.round(width * dimScale);
|
|
96
|
+
let scaledHeight = Math.round(height * dimScale);
|
|
97
|
+
|
|
98
|
+
// Step 2: Scale further if exceeds megapixel budget
|
|
99
|
+
const pixels = scaledWidth * scaledHeight;
|
|
100
|
+
if (pixels > ANTHROPIC_IMAGE_MAX_PIXELS) {
|
|
101
|
+
const mpScale = Math.sqrt(ANTHROPIC_IMAGE_MAX_PIXELS / pixels);
|
|
102
|
+
scaledWidth = Math.round(scaledWidth * mpScale);
|
|
103
|
+
scaledHeight = Math.round(scaledHeight * mpScale);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return Math.ceil(scaledWidth * scaledHeight * ANTHROPIC_IMAGE_TOKENS_PER_PIXEL);
|
|
99
107
|
}
|
|
100
108
|
|
|
101
109
|
function estimateImageTokens(
|
|
@@ -143,11 +151,10 @@ export function estimateContentBlockTokens(
|
|
|
143
151
|
return tokens;
|
|
144
152
|
}
|
|
145
153
|
case "image":
|
|
146
|
-
return
|
|
147
|
-
IMAGE_BLOCK_TOKENS,
|
|
154
|
+
return (
|
|
148
155
|
IMAGE_BLOCK_OVERHEAD_TOKENS +
|
|
149
|
-
|
|
150
|
-
|
|
156
|
+
estimateTextTokens(block.source.media_type) +
|
|
157
|
+
estimateImageTokens(block, options)
|
|
151
158
|
);
|
|
152
159
|
case "file":
|
|
153
160
|
return (
|
|
@@ -628,14 +628,18 @@ export class ContextWindowManager {
|
|
|
628
628
|
const excess = totalTokens - maxTranscriptTokens;
|
|
629
629
|
if (blockTokens > excess && result[i].type === "text") {
|
|
630
630
|
// Truncate this block to shed exactly the excess tokens.
|
|
631
|
-
|
|
631
|
+
// Subtract the cost of the "[...truncated] " prefix so the final
|
|
632
|
+
// block (prefix + kept text) stays within budget.
|
|
633
|
+
const truncationPrefix = "[...truncated] ";
|
|
634
|
+
const prefixTokens = estimateTextTokens(truncationPrefix);
|
|
635
|
+
const keepTokens = Math.max(1, blockTokens - excess - prefixTokens);
|
|
632
636
|
const text = (result[i] as { type: "text"; text: string }).text;
|
|
633
637
|
// Approximate: 1 token ≈ 4 characters for truncation purposes.
|
|
634
638
|
const keepChars = Math.max(1, Math.floor(keepTokens * 4));
|
|
635
639
|
const truncatedText = text.slice(-keepChars);
|
|
636
640
|
const truncatedBlock: ContentBlock = {
|
|
637
641
|
type: "text",
|
|
638
|
-
text:
|
|
642
|
+
text: `${truncationPrefix}${truncatedText}`,
|
|
639
643
|
};
|
|
640
644
|
const newBlockTokens = estimateBlockTokens(truncatedBlock);
|
|
641
645
|
droppedTokens += blockTokens - newBlockTokens;
|
|
@@ -31,6 +31,7 @@ import { StringDecoder } from "node:string_decoder";
|
|
|
31
31
|
import type { Subprocess } from "bun";
|
|
32
32
|
|
|
33
33
|
import type { AssistantConfig } from "../config/schema.js";
|
|
34
|
+
import { ensureBun } from "../util/bun-runtime.js";
|
|
34
35
|
import { getLogger } from "../util/logger.js";
|
|
35
36
|
import type { CesTransport } from "./client.js";
|
|
36
37
|
import {
|
|
@@ -266,8 +267,9 @@ export function createCesProcessManager(
|
|
|
266
267
|
"Spawning CES child process from source",
|
|
267
268
|
);
|
|
268
269
|
|
|
270
|
+
const bunPath = await ensureBun();
|
|
269
271
|
const proc = Bun.spawn({
|
|
270
|
-
cmd: [
|
|
272
|
+
cmd: [bunPath, "run", discovery.sourcePath],
|
|
271
273
|
stdin: "pipe",
|
|
272
274
|
stdout: "pipe",
|
|
273
275
|
stderr: "ignore",
|
|
@@ -17,7 +17,10 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import type { ContextWindowConfig } from "../config/types.js";
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
estimateContentBlockTokens,
|
|
22
|
+
estimatePromptTokens,
|
|
23
|
+
} from "../context/token-estimator.js";
|
|
21
24
|
import { truncateToolResultsAcrossHistory } from "../context/tool-result-truncation.js";
|
|
22
25
|
import type {
|
|
23
26
|
ContextWindowCompactOptions,
|
|
@@ -26,6 +29,7 @@ import type {
|
|
|
26
29
|
import type { Message } from "../providers/types.js";
|
|
27
30
|
import {
|
|
28
31
|
countMediaBlocks,
|
|
32
|
+
estimateUnconditionalStubTokens,
|
|
29
33
|
stripMediaPayloadsForRetry,
|
|
30
34
|
} from "./conversation-media-retry.js";
|
|
31
35
|
import type { InjectionMode } from "./conversation-runtime-assembly.js";
|
|
@@ -240,7 +244,47 @@ function applyMediaStubbing(
|
|
|
240
244
|
let nextMessages = messages;
|
|
241
245
|
|
|
242
246
|
if (mediaCount > 0) {
|
|
243
|
-
|
|
247
|
+
// Compute the token budget available for media content.
|
|
248
|
+
const totalTokens = estimatePromptTokens(messages, config.systemPrompt, {
|
|
249
|
+
providerName: config.providerName,
|
|
250
|
+
toolTokenBudget: config.toolTokenBudget,
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// Sum tokens for all image and file blocks (top-level and nested in tool_result).
|
|
254
|
+
let mediaTokens = 0;
|
|
255
|
+
for (const msg of messages) {
|
|
256
|
+
for (const block of msg.content) {
|
|
257
|
+
if (block.type === "image" || block.type === "file") {
|
|
258
|
+
mediaTokens += estimateContentBlockTokens(block, {
|
|
259
|
+
providerName: config.providerName,
|
|
260
|
+
});
|
|
261
|
+
} else if (block.type === "tool_result" && block.contentBlocks) {
|
|
262
|
+
for (const cb of block.contentBlocks) {
|
|
263
|
+
if (cb.type === "image" || cb.type === "file") {
|
|
264
|
+
mediaTokens += estimateContentBlockTokens(cb, {
|
|
265
|
+
providerName: config.providerName,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const nonMediaTokens = totalTokens - mediaTokens;
|
|
274
|
+
|
|
275
|
+
// Account for the token cost of text stubs that replace unconditionally
|
|
276
|
+
// stubbed media (non-latest-user images/files, tool_result-nested media).
|
|
277
|
+
// Without this adjustment the budget is systematically over-allocated.
|
|
278
|
+
const estimatedStubTokens = estimateUnconditionalStubTokens(messages, {
|
|
279
|
+
providerName: config.providerName,
|
|
280
|
+
});
|
|
281
|
+
const adjustedNonMediaTokens = nonMediaTokens + estimatedStubTokens;
|
|
282
|
+
const mediaTokenBudget = Math.max(0, config.targetTokens - adjustedNonMediaTokens);
|
|
283
|
+
|
|
284
|
+
const stripped = stripMediaPayloadsForRetry(messages, {
|
|
285
|
+
mediaTokenBudget,
|
|
286
|
+
providerName: config.providerName,
|
|
287
|
+
});
|
|
244
288
|
if (stripped.modified) {
|
|
245
289
|
nextMessages = stripped.messages;
|
|
246
290
|
}
|