@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
|
@@ -170,17 +170,39 @@ describe("Permission Checker", () => {
|
|
|
170
170
|
// ── classifyRisk ────────────────────────────────────────────────
|
|
171
171
|
|
|
172
172
|
describe("classifyRisk", () => {
|
|
173
|
-
// file_read is
|
|
173
|
+
// file_read is low risk except for signing-key material
|
|
174
174
|
describe("file_read", () => {
|
|
175
|
-
test("file_read is
|
|
175
|
+
test("file_read is low risk for regular files", async () => {
|
|
176
176
|
const risk = await classifyRisk("file_read", { path: "/etc/passwd" });
|
|
177
177
|
expect(risk).toBe(RiskLevel.Low);
|
|
178
178
|
});
|
|
179
179
|
|
|
180
|
-
test("file_read with
|
|
180
|
+
test("file_read with arbitrary non-key path is low risk", async () => {
|
|
181
181
|
const risk = await classifyRisk("file_read", { path: "/tmp/safe.txt" });
|
|
182
182
|
expect(risk).toBe(RiskLevel.Low);
|
|
183
183
|
});
|
|
184
|
+
|
|
185
|
+
test("file_read of workspace signing key path is high risk", async () => {
|
|
186
|
+
const workspaceDir = join(checkerTestDir, "workspace");
|
|
187
|
+
const risk = await classifyRisk(
|
|
188
|
+
"file_read",
|
|
189
|
+
{ path: "deprecated/actor-token-signing-key" },
|
|
190
|
+
workspaceDir,
|
|
191
|
+
);
|
|
192
|
+
expect(risk).toBe(RiskLevel.High);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test("file_read of legacy protected signing key path is high risk", async () => {
|
|
196
|
+
const risk = await classifyRisk("file_read", {
|
|
197
|
+
path: join(
|
|
198
|
+
homedir(),
|
|
199
|
+
".vellum",
|
|
200
|
+
"protected",
|
|
201
|
+
"actor-token-signing-key",
|
|
202
|
+
),
|
|
203
|
+
});
|
|
204
|
+
expect(risk).toBe(RiskLevel.High);
|
|
205
|
+
});
|
|
184
206
|
});
|
|
185
207
|
|
|
186
208
|
// file_write is always low (sandboxed)
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
mkdirSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
rmSync,
|
|
6
|
+
writeFileSync,
|
|
7
|
+
} from "node:fs";
|
|
2
8
|
import { join } from "node:path";
|
|
3
9
|
import { describe, expect, test } from "bun:test";
|
|
4
10
|
import { mock } from "bun:test";
|
|
@@ -15,9 +21,9 @@ mock.module("../util/logger.js", () => ({
|
|
|
15
21
|
import {
|
|
16
22
|
clawhubInspect,
|
|
17
23
|
clawhubInstall,
|
|
18
|
-
loadIntegrityManifest,
|
|
19
24
|
verifyAndRecordSkillHash,
|
|
20
25
|
} from "../skills/clawhub.js";
|
|
26
|
+
import type { SkillInstallMeta } from "../skills/install-meta.js";
|
|
21
27
|
|
|
22
28
|
// ---------------------------------------------------------------------------
|
|
23
29
|
// Slug validation (exercised through public API)
|
|
@@ -92,58 +98,65 @@ describe("clawhubInspect slug validation", () => {
|
|
|
92
98
|
});
|
|
93
99
|
|
|
94
100
|
// ---------------------------------------------------------------------------
|
|
95
|
-
//
|
|
96
|
-
// which
|
|
101
|
+
// Content hash verification — tested via verifyAndRecordSkillHash
|
|
102
|
+
// which reads legacy .integrity.json but always writes to install-meta.json.
|
|
97
103
|
// ---------------------------------------------------------------------------
|
|
98
104
|
|
|
99
|
-
describe("
|
|
105
|
+
describe("content hash verification", () => {
|
|
100
106
|
function createSkillFiles(slug: string): void {
|
|
101
107
|
const skillDir = join(TEST_DIR, "skills", slug);
|
|
102
108
|
mkdirSync(skillDir, { recursive: true });
|
|
103
109
|
writeFileSync(join(skillDir, "SKILL.md"), "# Test Skill\n", "utf-8");
|
|
104
110
|
}
|
|
105
111
|
|
|
112
|
+
function readSkillInstallMeta(slug: string): SkillInstallMeta {
|
|
113
|
+
const metaPath = join(TEST_DIR, "skills", slug, "install-meta.json");
|
|
114
|
+
return JSON.parse(readFileSync(metaPath, "utf-8")) as SkillInstallMeta;
|
|
115
|
+
}
|
|
116
|
+
|
|
106
117
|
test("malformed integrity JSON is handled gracefully", () => {
|
|
107
118
|
mkdirSync(join(TEST_DIR, "skills"), { recursive: true });
|
|
108
119
|
const integrityPath = join(TEST_DIR, "skills", ".integrity.json");
|
|
109
120
|
writeFileSync(integrityPath, "{not valid json!!!", "utf-8");
|
|
110
121
|
createSkillFiles("valid-slug");
|
|
111
122
|
|
|
112
|
-
// Should not throw — malformed manifest is
|
|
123
|
+
// Should not throw — malformed legacy manifest is ignored; install-meta.json is created
|
|
113
124
|
verifyAndRecordSkillHash("valid-slug");
|
|
114
125
|
|
|
115
|
-
//
|
|
116
|
-
const
|
|
117
|
-
expect(
|
|
118
|
-
expect(
|
|
126
|
+
// install-meta.json should now contain a valid hash
|
|
127
|
+
const meta = readSkillInstallMeta("valid-slug");
|
|
128
|
+
expect(meta.contentHash).toMatch(/^v2:[0-9a-f]{64}$/);
|
|
129
|
+
expect(meta.origin).toBe("clawhub");
|
|
130
|
+
expect(meta.slug).toBe("valid-slug");
|
|
119
131
|
});
|
|
120
132
|
|
|
121
|
-
test("
|
|
133
|
+
test("install-meta.json is created on first hash verification for skills without one", () => {
|
|
122
134
|
const skillsDir = join(TEST_DIR, "skills");
|
|
123
135
|
mkdirSync(skillsDir, { recursive: true });
|
|
124
|
-
const integrityPath = join(skillsDir, ".integrity.json");
|
|
125
|
-
// Remove any manifest left by earlier tests so we test the fresh-creation path
|
|
126
|
-
rmSync(integrityPath, { force: true });
|
|
127
|
-
expect(existsSync(integrityPath)).toBe(false);
|
|
128
136
|
createSkillFiles("new-skill");
|
|
137
|
+
const metaPath = join(skillsDir, "new-skill", "install-meta.json");
|
|
138
|
+
// Remove any install-meta left by earlier tests
|
|
139
|
+
rmSync(metaPath, { force: true });
|
|
140
|
+
expect(existsSync(metaPath)).toBe(false);
|
|
129
141
|
|
|
130
142
|
verifyAndRecordSkillHash("new-skill");
|
|
131
143
|
|
|
132
|
-
//
|
|
133
|
-
expect(existsSync(
|
|
134
|
-
const
|
|
135
|
-
expect(
|
|
136
|
-
expect(
|
|
144
|
+
// install-meta.json should now exist with the skill's hash
|
|
145
|
+
expect(existsSync(metaPath)).toBe(true);
|
|
146
|
+
const meta = readSkillInstallMeta("new-skill");
|
|
147
|
+
expect(meta.contentHash).toMatch(/^v2:[0-9a-f]{64}$/);
|
|
148
|
+
expect(meta.origin).toBe("clawhub");
|
|
149
|
+
expect(meta.slug).toBe("new-skill");
|
|
137
150
|
});
|
|
138
151
|
|
|
139
152
|
test("re-install with same content preserves hash", () => {
|
|
140
153
|
createSkillFiles("stable-skill");
|
|
141
154
|
|
|
142
155
|
verifyAndRecordSkillHash("stable-skill");
|
|
143
|
-
const first =
|
|
156
|
+
const first = readSkillInstallMeta("stable-skill").contentHash;
|
|
144
157
|
|
|
145
158
|
verifyAndRecordSkillHash("stable-skill");
|
|
146
|
-
const second =
|
|
159
|
+
const second = readSkillInstallMeta("stable-skill").contentHash;
|
|
147
160
|
|
|
148
161
|
expect(first).toBe(second);
|
|
149
162
|
});
|
|
@@ -151,7 +164,7 @@ describe("integrity manifest", () => {
|
|
|
151
164
|
test("re-install with changed content updates hash", () => {
|
|
152
165
|
createSkillFiles("changing-skill");
|
|
153
166
|
verifyAndRecordSkillHash("changing-skill");
|
|
154
|
-
const first =
|
|
167
|
+
const first = readSkillInstallMeta("changing-skill").contentHash;
|
|
155
168
|
|
|
156
169
|
// Modify skill content
|
|
157
170
|
writeFileSync(
|
|
@@ -160,8 +173,25 @@ describe("integrity manifest", () => {
|
|
|
160
173
|
"utf-8",
|
|
161
174
|
);
|
|
162
175
|
verifyAndRecordSkillHash("changing-skill");
|
|
163
|
-
const second =
|
|
176
|
+
const second = readSkillInstallMeta("changing-skill").contentHash;
|
|
164
177
|
|
|
165
178
|
expect(first).not.toBe(second);
|
|
166
179
|
});
|
|
180
|
+
|
|
181
|
+
test(".integrity.json is never written to", () => {
|
|
182
|
+
const skillsDir = join(TEST_DIR, "skills");
|
|
183
|
+
mkdirSync(skillsDir, { recursive: true });
|
|
184
|
+
const integrityPath = join(skillsDir, ".integrity.json");
|
|
185
|
+
// Remove any legacy manifest
|
|
186
|
+
rmSync(integrityPath, { force: true });
|
|
187
|
+
createSkillFiles("no-integrity-write");
|
|
188
|
+
|
|
189
|
+
verifyAndRecordSkillHash("no-integrity-write");
|
|
190
|
+
|
|
191
|
+
// .integrity.json should NOT have been created
|
|
192
|
+
expect(existsSync(integrityPath)).toBe(false);
|
|
193
|
+
// But install-meta.json should exist
|
|
194
|
+
const metaPath = join(skillsDir, "no-integrity-write", "install-meta.json");
|
|
195
|
+
expect(existsSync(metaPath)).toBe(true);
|
|
196
|
+
});
|
|
167
197
|
});
|
|
@@ -208,6 +208,20 @@ describe("CLI command risk guard: elevated assistant subcommands", () => {
|
|
|
208
208
|
}
|
|
209
209
|
});
|
|
210
210
|
|
|
211
|
+
test("--help used as option value does not downgrade credentials reveal risk", async () => {
|
|
212
|
+
const risk = await classifyRisk("bash", {
|
|
213
|
+
command: "assistant credentials reveal 123 --service --help",
|
|
214
|
+
});
|
|
215
|
+
expect(risk).toBe(RiskLevel.High);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("-h used as option value does not downgrade oauth mode --set risk", async () => {
|
|
219
|
+
const risk = await classifyRisk("bash", {
|
|
220
|
+
command: "assistant oauth mode --set -h",
|
|
221
|
+
});
|
|
222
|
+
expect(risk).toBe(RiskLevel.High);
|
|
223
|
+
});
|
|
224
|
+
|
|
211
225
|
test("non-sensitive oauth subcommands remain Low risk", async () => {
|
|
212
226
|
const lowRiskOauthCommands = [
|
|
213
227
|
"assistant oauth apps",
|
|
@@ -2,7 +2,7 @@ import { rmSync } from "node:fs";
|
|
|
2
2
|
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
3
3
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import { eq } from "drizzle-orm";
|
|
5
|
+
import { eq, like } from "drizzle-orm";
|
|
6
6
|
|
|
7
7
|
mock.module("../util/logger.js", () => ({
|
|
8
8
|
getLogger: () =>
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
upsertCliCapabilityMemory,
|
|
65
65
|
} from "../cli/cli-memory.js";
|
|
66
66
|
import { getDb, initializeDb, resetDb } from "../memory/db.js";
|
|
67
|
-
import {
|
|
67
|
+
import { memoryGraphNodes, memoryJobs } from "../memory/schema.js";
|
|
68
68
|
import { ensureDataDir, getDbPath } from "../util/platform.js";
|
|
69
69
|
|
|
70
70
|
ensureDataDir();
|
|
@@ -76,9 +76,8 @@ afterAll(() => {
|
|
|
76
76
|
|
|
77
77
|
function resetTables() {
|
|
78
78
|
const db = getDb();
|
|
79
|
-
db.run("DELETE FROM memory_item_sources");
|
|
80
79
|
db.run("DELETE FROM memory_embeddings");
|
|
81
|
-
db.run("DELETE FROM
|
|
80
|
+
db.run("DELETE FROM memory_graph_nodes");
|
|
82
81
|
db.run("DELETE FROM memory_jobs");
|
|
83
82
|
}
|
|
84
83
|
|
|
@@ -103,62 +102,62 @@ describe("buildCliCapabilityStatement", () => {
|
|
|
103
102
|
describe("upsertCliCapabilityMemory", () => {
|
|
104
103
|
beforeEach(resetTables);
|
|
105
104
|
|
|
106
|
-
test("inserts with correct
|
|
105
|
+
test("inserts with correct type, content, confidence, significance", () => {
|
|
107
106
|
upsertCliCapabilityMemory("doctor", "Run diagnostic checks");
|
|
108
107
|
|
|
109
108
|
const db = getDb();
|
|
110
|
-
const items = db.select().from(
|
|
109
|
+
const items = db.select().from(memoryGraphNodes).all();
|
|
111
110
|
expect(items).toHaveLength(1);
|
|
112
|
-
expect(items[0].
|
|
113
|
-
expect(items[0].
|
|
111
|
+
expect(items[0].type).toBe("procedural");
|
|
112
|
+
expect(items[0].content).toMatch(/^cli:doctor\n/);
|
|
114
113
|
expect(items[0].confidence).toBe(1.0);
|
|
115
|
-
expect(items[0].
|
|
116
|
-
expect(items[0].
|
|
114
|
+
expect(items[0].significance).toBe(0.7);
|
|
115
|
+
expect(items[0].fidelity).toBe("vivid");
|
|
117
116
|
expect(items[0].scopeId).toBe("default");
|
|
118
117
|
|
|
119
|
-
// Should also enqueue an
|
|
118
|
+
// Should also enqueue an embed_graph_node job
|
|
120
119
|
const jobs = db.select().from(memoryJobs).all();
|
|
121
120
|
expect(jobs).toHaveLength(1);
|
|
122
|
-
expect(jobs[0].type).toBe("
|
|
121
|
+
expect(jobs[0].type).toBe("embed_graph_node");
|
|
123
122
|
});
|
|
124
123
|
|
|
125
|
-
test("is idempotent (same entry only touches
|
|
124
|
+
test("is idempotent (same entry only touches lastAccessed)", () => {
|
|
126
125
|
upsertCliCapabilityMemory("doctor", "Run diagnostic checks");
|
|
127
126
|
|
|
128
127
|
const db = getDb();
|
|
129
|
-
const before = db.select().from(
|
|
128
|
+
const before = db.select().from(memoryGraphNodes).all();
|
|
130
129
|
expect(before).toHaveLength(1);
|
|
131
|
-
const
|
|
130
|
+
const originalLastAccessed = before[0].lastAccessed;
|
|
132
131
|
|
|
133
132
|
// Upsert again
|
|
134
133
|
upsertCliCapabilityMemory("doctor", "Run diagnostic checks");
|
|
135
134
|
|
|
136
|
-
const after = db.select().from(
|
|
135
|
+
const after = db.select().from(memoryGraphNodes).all();
|
|
137
136
|
expect(after).toHaveLength(1);
|
|
138
|
-
//
|
|
139
|
-
expect(after[0].
|
|
140
|
-
expect(after[0].
|
|
137
|
+
// Same content, so only lastAccessed changes
|
|
138
|
+
expect(after[0].content).toBe(before[0].content);
|
|
139
|
+
expect(after[0].lastAccessed).toBeGreaterThanOrEqual(originalLastAccessed);
|
|
141
140
|
|
|
142
141
|
// Should NOT enqueue a second embed job (only 1 from initial insert)
|
|
143
142
|
const jobs = db.select().from(memoryJobs).all();
|
|
144
143
|
expect(jobs).toHaveLength(1);
|
|
145
144
|
});
|
|
146
145
|
|
|
147
|
-
test("updates
|
|
146
|
+
test("updates content when description changes", () => {
|
|
148
147
|
upsertCliCapabilityMemory("doctor", "Original description");
|
|
149
148
|
|
|
150
149
|
const db = getDb();
|
|
151
|
-
const before = db.select().from(
|
|
150
|
+
const before = db.select().from(memoryGraphNodes).all();
|
|
152
151
|
expect(before).toHaveLength(1);
|
|
153
|
-
expect(before[0].
|
|
152
|
+
expect(before[0].content).toContain("Original description");
|
|
154
153
|
|
|
155
154
|
// Change description
|
|
156
155
|
upsertCliCapabilityMemory("doctor", "Updated description");
|
|
157
156
|
|
|
158
|
-
const after = db.select().from(
|
|
157
|
+
const after = db.select().from(memoryGraphNodes).all();
|
|
159
158
|
expect(after).toHaveLength(1);
|
|
160
|
-
expect(after[0].
|
|
161
|
-
expect(after[0].
|
|
159
|
+
expect(after[0].content).toContain("Updated description");
|
|
160
|
+
expect(after[0].content).not.toBe(before[0].content);
|
|
162
161
|
|
|
163
162
|
// Should enqueue a second embed job
|
|
164
163
|
const jobs = db.select().from(memoryJobs).all();
|
|
@@ -170,13 +169,13 @@ describe("upsertCliCapabilityMemory", () => {
|
|
|
170
169
|
|
|
171
170
|
const db = getDb();
|
|
172
171
|
// Soft-delete the item
|
|
173
|
-
db.update(
|
|
174
|
-
.set({
|
|
175
|
-
.where(
|
|
172
|
+
db.update(memoryGraphNodes)
|
|
173
|
+
.set({ fidelity: "gone" })
|
|
174
|
+
.where(like(memoryGraphNodes.content, "cli:doctor\n%"))
|
|
176
175
|
.run();
|
|
177
176
|
|
|
178
|
-
const deleted = db.select().from(
|
|
179
|
-
expect(deleted[0].
|
|
177
|
+
const deleted = db.select().from(memoryGraphNodes).all();
|
|
178
|
+
expect(deleted[0].fidelity).toBe("gone");
|
|
180
179
|
|
|
181
180
|
// Clear jobs from initial insert
|
|
182
181
|
db.run("DELETE FROM memory_jobs");
|
|
@@ -184,20 +183,20 @@ describe("upsertCliCapabilityMemory", () => {
|
|
|
184
183
|
// Upsert again — should reactivate
|
|
185
184
|
upsertCliCapabilityMemory("doctor", "Run diagnostic checks");
|
|
186
185
|
|
|
187
|
-
const reactivated = db.select().from(
|
|
186
|
+
const reactivated = db.select().from(memoryGraphNodes).all();
|
|
188
187
|
expect(reactivated).toHaveLength(1);
|
|
189
|
-
expect(reactivated[0].
|
|
188
|
+
expect(reactivated[0].fidelity).toBe("vivid");
|
|
190
189
|
|
|
191
190
|
// Should enqueue embed job for reactivated item
|
|
192
191
|
const jobs = db.select().from(memoryJobs).all();
|
|
193
192
|
expect(jobs).toHaveLength(1);
|
|
194
|
-
expect(jobs[0].type).toBe("
|
|
193
|
+
expect(jobs[0].type).toBe("embed_graph_node");
|
|
195
194
|
});
|
|
196
195
|
|
|
197
196
|
test("does not throw on DB error", () => {
|
|
198
197
|
resetDb();
|
|
199
198
|
const db = getDb();
|
|
200
|
-
db.run("DROP TABLE IF EXISTS
|
|
199
|
+
db.run("DROP TABLE IF EXISTS memory_graph_nodes");
|
|
201
200
|
|
|
202
201
|
expect(() => {
|
|
203
202
|
upsertCliCapabilityMemory("doctor", "Run diagnostic checks");
|
|
@@ -234,21 +233,21 @@ describe("seedCliCommandMemories", () => {
|
|
|
234
233
|
const db = getDb();
|
|
235
234
|
const items = db
|
|
236
235
|
.select()
|
|
237
|
-
.from(
|
|
238
|
-
.where(eq(
|
|
236
|
+
.from(memoryGraphNodes)
|
|
237
|
+
.where(eq(memoryGraphNodes.type, "procedural"))
|
|
239
238
|
.all();
|
|
240
239
|
expect(items).toHaveLength(3);
|
|
241
240
|
|
|
242
|
-
const
|
|
243
|
-
expect(
|
|
241
|
+
const contentPrefixes = items.map((i) => i.content.split("\n")[0]).sort();
|
|
242
|
+
expect(contentPrefixes).toEqual([
|
|
244
243
|
"cli:config",
|
|
245
244
|
"cli:doctor",
|
|
246
245
|
"cli:keys",
|
|
247
246
|
]);
|
|
248
247
|
|
|
249
|
-
// All should be
|
|
248
|
+
// All should be vivid
|
|
250
249
|
for (const item of items) {
|
|
251
|
-
expect(item.
|
|
250
|
+
expect(item.fidelity).toBe("vivid");
|
|
252
251
|
}
|
|
253
252
|
});
|
|
254
253
|
|
|
@@ -264,11 +263,11 @@ describe("seedCliCommandMemories", () => {
|
|
|
264
263
|
const db = getDb();
|
|
265
264
|
const beforeItems = db
|
|
266
265
|
.select()
|
|
267
|
-
.from(
|
|
268
|
-
.where(eq(
|
|
266
|
+
.from(memoryGraphNodes)
|
|
267
|
+
.where(eq(memoryGraphNodes.type, "procedural"))
|
|
269
268
|
.all();
|
|
270
269
|
expect(beforeItems).toHaveLength(3);
|
|
271
|
-
expect(beforeItems.every((i) => i.
|
|
270
|
+
expect(beforeItems.every((i) => i.fidelity === "vivid")).toBe(true);
|
|
272
271
|
|
|
273
272
|
// Now seed with only doctor — config and keys should be pruned
|
|
274
273
|
mockCommands = [
|
|
@@ -278,20 +277,20 @@ describe("seedCliCommandMemories", () => {
|
|
|
278
277
|
|
|
279
278
|
const afterItems = db
|
|
280
279
|
.select()
|
|
281
|
-
.from(
|
|
282
|
-
.where(eq(
|
|
280
|
+
.from(memoryGraphNodes)
|
|
281
|
+
.where(eq(memoryGraphNodes.type, "procedural"))
|
|
283
282
|
.all();
|
|
284
283
|
expect(afterItems).toHaveLength(3); // still 3 rows, but 2 are soft-deleted
|
|
285
284
|
|
|
286
|
-
const active = afterItems.filter((i) => i.
|
|
287
|
-
const deleted = afterItems.filter((i) => i.
|
|
285
|
+
const active = afterItems.filter((i) => i.fidelity === "vivid");
|
|
286
|
+
const deleted = afterItems.filter((i) => i.fidelity === "gone");
|
|
288
287
|
|
|
289
288
|
expect(active).toHaveLength(1);
|
|
290
|
-
expect(active[0].
|
|
289
|
+
expect(active[0].content).toMatch(/^cli:doctor\n/);
|
|
291
290
|
|
|
292
291
|
expect(deleted).toHaveLength(2);
|
|
293
|
-
const
|
|
294
|
-
expect(
|
|
292
|
+
const deletedPrefixes = deleted.map((i) => i.content.split("\n")[0]).sort();
|
|
293
|
+
expect(deletedPrefixes).toEqual(["cli:config", "cli:keys"]);
|
|
295
294
|
});
|
|
296
295
|
|
|
297
296
|
test("handles empty command list without errors", () => {
|
|
@@ -299,38 +298,44 @@ describe("seedCliCommandMemories", () => {
|
|
|
299
298
|
upsertCliCapabilityMemory("old-command", "An old command");
|
|
300
299
|
|
|
301
300
|
const db = getDb();
|
|
302
|
-
const beforeItems = db.select().from(
|
|
301
|
+
const beforeItems = db.select().from(memoryGraphNodes).all();
|
|
303
302
|
expect(beforeItems).toHaveLength(1);
|
|
304
|
-
expect(beforeItems[0].
|
|
303
|
+
expect(beforeItems[0].fidelity).toBe("vivid");
|
|
305
304
|
|
|
306
305
|
// Seed with empty commands
|
|
307
306
|
mockCommands = [];
|
|
308
307
|
seedCliCommandMemories();
|
|
309
308
|
|
|
310
309
|
// The existing command should be pruned (soft-deleted)
|
|
311
|
-
const afterItems = db.select().from(
|
|
310
|
+
const afterItems = db.select().from(memoryGraphNodes).all();
|
|
312
311
|
expect(afterItems).toHaveLength(1);
|
|
313
|
-
expect(afterItems[0].
|
|
312
|
+
expect(afterItems[0].fidelity).toBe("gone");
|
|
314
313
|
});
|
|
315
314
|
|
|
316
315
|
test("does not prune non-cli capability memories", () => {
|
|
317
316
|
// Pre-insert a skill capability memory directly into the DB
|
|
318
317
|
const db = getDb();
|
|
319
318
|
const now = Date.now();
|
|
320
|
-
db.insert(
|
|
319
|
+
db.insert(memoryGraphNodes)
|
|
321
320
|
.values({
|
|
322
321
|
id: "skill-test-item",
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
status: "active",
|
|
322
|
+
type: "procedural",
|
|
323
|
+
content: "skill:test-skill\nThe test skill does things.",
|
|
324
|
+
fidelity: "vivid",
|
|
327
325
|
confidence: 1.0,
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
sourceType: "extraction",
|
|
326
|
+
significance: 0.7,
|
|
327
|
+
sourceType: "inferred",
|
|
331
328
|
scopeId: "default",
|
|
332
|
-
|
|
333
|
-
|
|
329
|
+
created: now,
|
|
330
|
+
lastAccessed: now,
|
|
331
|
+
lastConsolidated: now,
|
|
332
|
+
emotionalCharge: '{"valence":0,"intensity":0.1,"decayCurve":"linear","decayRate":0.05,"originalIntensity":0.1}',
|
|
333
|
+
stability: 14,
|
|
334
|
+
reinforcementCount: 0,
|
|
335
|
+
lastReinforced: now,
|
|
336
|
+
sourceConversations: "[]",
|
|
337
|
+
narrativeRole: null,
|
|
338
|
+
partOfStory: null,
|
|
334
339
|
})
|
|
335
340
|
.run();
|
|
336
341
|
|
|
@@ -340,11 +345,11 @@ describe("seedCliCommandMemories", () => {
|
|
|
340
345
|
|
|
341
346
|
const item = db
|
|
342
347
|
.select()
|
|
343
|
-
.from(
|
|
344
|
-
.where(
|
|
348
|
+
.from(memoryGraphNodes)
|
|
349
|
+
.where(like(memoryGraphNodes.content, "skill:test-skill\n%"))
|
|
345
350
|
.get();
|
|
346
351
|
expect(item).toBeDefined();
|
|
347
|
-
expect(item!.
|
|
352
|
+
expect(item!.fidelity).toBe("vivid");
|
|
348
353
|
});
|
|
349
354
|
|
|
350
355
|
test("does not throw on error", () => {
|
|
@@ -352,10 +357,10 @@ describe("seedCliCommandMemories", () => {
|
|
|
352
357
|
{ name: "doctor", description: "Run diagnostic checks" },
|
|
353
358
|
];
|
|
354
359
|
|
|
355
|
-
// Drop
|
|
360
|
+
// Drop memory_graph_nodes to force a DB error during the prune phase
|
|
356
361
|
resetDb();
|
|
357
362
|
const db = getDb();
|
|
358
|
-
db.run("DROP TABLE IF EXISTS
|
|
363
|
+
db.run("DROP TABLE IF EXISTS memory_graph_nodes");
|
|
359
364
|
|
|
360
365
|
expect(() => {
|
|
361
366
|
seedCliCommandMemories();
|
|
@@ -105,7 +105,7 @@ describe("AssistantConfigSchema", () => {
|
|
|
105
105
|
shellMaxTimeoutSec: 600,
|
|
106
106
|
permissionTimeoutSec: 300,
|
|
107
107
|
toolExecutionTimeoutSec: 120,
|
|
108
|
-
providerStreamTimeoutSec:
|
|
108
|
+
providerStreamTimeoutSec: 1800,
|
|
109
109
|
});
|
|
110
110
|
expect(result.sandbox).toEqual({
|
|
111
111
|
enabled: false,
|