@vellumai/assistant 0.5.16 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -0
- package/ARCHITECTURE.md +69 -16
- package/Dockerfile +2 -5
- package/bun.lock +6 -2
- package/docker-entrypoint.sh +32 -1
- package/docs/architecture/integrations.md +1 -1
- package/docs/architecture/memory.md +21 -24
- package/knip.json +2 -1
- package/openapi.yaml +1198 -83
- package/package.json +5 -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 +217 -98
- package/src/__tests__/app-compiler.test.ts +120 -0
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +47 -1
- package/src/__tests__/app-source-watcher.test.ts +159 -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 +63 -9
- package/src/__tests__/clawhub.test.ts +54 -24
- package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
- package/src/__tests__/config-schema.test.ts +6 -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 +13 -6
- package/src/__tests__/conversation-agent-loop.test.ts +13 -51
- 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 +6 -1
- 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-runtime-assembly.test.ts +653 -832
- package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
- package/src/__tests__/conversation-starter-routes.test.ts +20 -11
- package/src/__tests__/conversation-store.test.ts +2 -6
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
- package/src/__tests__/conversation-usage.test.ts +2 -6
- package/src/__tests__/conversation-wipe.test.ts +13 -414
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
- package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
- 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__/date-context.test.ts +76 -210
- package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
- package/src/__tests__/file-list-tool.test.ts +219 -0
- package/src/__tests__/first-greeting.test.ts +1 -1
- 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__/heartbeat-service.test.ts +180 -3
- package/src/__tests__/identity-routes.test.ts +328 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
- package/src/__tests__/injection-block.test.ts +178 -0
- package/src/__tests__/install-meta.test.ts +506 -0
- package/src/__tests__/install-skill-routing.test.ts +293 -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 +17 -28
- package/src/__tests__/list-messages-attachments.test.ts +2 -6
- package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
- package/src/__tests__/llm-context-normalization.test.ts +18 -18
- package/src/__tests__/llm-context-route-provider.test.ts +103 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +164 -6
- package/src/__tests__/llm-usage-store.test.ts +2 -6
- package/src/__tests__/log-export-workspace.test.ts +74 -111
- package/src/__tests__/managed-store.test.ts +38 -11
- package/src/__tests__/mcp-abort-signal.test.ts +5 -0
- package/src/__tests__/mcp-client-auth.test.ts +5 -0
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
- package/src/__tests__/memory-recall-log-store.test.ts +134 -6
- package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
- package/src/__tests__/migration-export-streaming.test.ts +304 -0
- package/src/__tests__/migration-import-commit-http.test.ts +11 -10
- package/src/__tests__/mock-fetch.ts +87 -0
- package/src/__tests__/non-member-access-request.test.ts +2 -6
- package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
- 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__/onboarding-template-contract.test.ts +62 -14
- 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__/parser.test.ts +32 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
- package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
- package/src/__tests__/permission-mode-sse.test.ts +418 -0
- package/src/__tests__/permission-mode-store.test.ts +277 -0
- package/src/__tests__/permission-mode.test.ts +101 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +359 -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__/profiler-routes.test.ts +502 -0
- package/src/__tests__/profiler-run-store.test.ts +441 -0
- package/src/__tests__/provider-error-scenarios.test.ts +21 -0
- package/src/__tests__/proxy-approval-callback.test.ts +4 -75
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
- package/src/__tests__/registry.test.ts +3 -3
- 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__/sandbox-host-parity.test.ts +5 -4
- 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__/scheduler-reuse-conversation.test.ts +368 -0
- package/src/__tests__/scoped-approval-grants.test.ts +2 -6
- package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
- package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
- package/src/__tests__/search-skills-unified.test.ts +422 -0
- package/src/__tests__/secret-onetime-send.test.ts +2 -0
- package/src/__tests__/send-endpoint-busy.test.ts +44 -9
- package/src/__tests__/sequence-store.test.ts +2 -6
- package/src/__tests__/server-history-render.test.ts +2 -6
- package/src/__tests__/set-permission-mode.test.ts +274 -0
- 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 +23 -11
- package/src/__tests__/skill-memory.test.ts +2 -741
- 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__/strip-memory-injections.test.ts +187 -0
- package/src/__tests__/subagent-detail.test.ts +84 -0
- package/src/__tests__/subagent-disposal.test.ts +308 -0
- package/src/__tests__/subagent-manager-notify.test.ts +19 -10
- package/src/__tests__/subagent-notify-parent.test.ts +390 -0
- package/src/__tests__/subagent-role-registry.test.ts +108 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
- package/src/__tests__/subagent-tools.test.ts +464 -4
- package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
- 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 +185 -241
- package/src/__tests__/task-runner.test.ts +2 -6
- package/src/__tests__/task-scheduler.test.ts +2 -6
- package/src/__tests__/terminal-tools.test.ts +17 -27
- package/src/__tests__/test-preload.ts +7 -0
- package/src/__tests__/tool-approval-handler.test.ts +2 -6
- package/src/__tests__/tool-executor.test.ts +4 -26
- package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +277 -0
- package/src/__tests__/top-level-renderer.test.ts +10 -13
- 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 +118 -8
- 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-migration-028-recover-conversations-from-disk-view.test.ts +387 -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 +7 -15
- package/src/approvals/guardian-request-resolvers.ts +24 -0
- package/src/avatar/traits-png-sync.ts +3 -3
- 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/__tests__/run-assistant-command.ts +29 -0
- package/src/cli/commands/__tests__/email-download.test.ts +245 -0
- package/src/cli/commands/__tests__/email-list.test.ts +192 -0
- package/src/cli/commands/__tests__/email-register.test.ts +186 -0
- package/src/cli/commands/__tests__/email-send.test.ts +291 -0
- package/src/cli/commands/__tests__/email-status.test.ts +181 -0
- package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
- package/src/cli/commands/__tests__/routes.test.ts +562 -0
- package/src/cli/commands/avatar.ts +3 -3
- package/src/cli/commands/config.ts +26 -13
- package/src/cli/commands/conversations.ts +1 -8
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/email.ts +584 -835
- package/src/cli/commands/memory.ts +37 -84
- package/src/cli/commands/notifications.ts +7 -2
- 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 +25 -11
- 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/routes.ts +396 -0
- package/src/cli/commands/skills.ts +218 -36
- package/src/cli/commands/trust.ts +2 -2
- package/src/cli/lib/daemon-credential-client.ts +2 -3
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +1 -120
- package/src/config/bundled-skills/acp/TOOLS.json +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +4 -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 +4 -12
- package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
- package/src/config/bundled-skills/messaging/SKILL.md +17 -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/schedule/SKILL.md +22 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
- package/src/config/bundled-skills/slack/SKILL.md +3 -7
- package/src/config/bundled-skills/subagent/SKILL.md +43 -3
- package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
- package/src/config/bundled-tool-registry.ts +56 -4
- package/src/config/env-registry.ts +78 -8
- package/src/config/feature-flag-registry.json +38 -125
- package/src/config/schema.ts +8 -0
- package/src/config/schemas/filing.ts +51 -0
- package/src/config/schemas/heartbeat.ts +15 -12
- package/src/config/schemas/memory-lifecycle.ts +12 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/security.ts +14 -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/app-source-watcher.ts +93 -0
- package/src/daemon/config-watcher.ts +79 -1
- package/src/daemon/context-overflow-reducer.ts +46 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +143 -82
- package/src/daemon/conversation-agent-loop.ts +236 -108
- package/src/daemon/conversation-error.ts +31 -8
- package/src/daemon/conversation-history.ts +4 -19
- package/src/daemon/conversation-lifecycle.ts +36 -9
- package/src/daemon/conversation-media-retry.ts +85 -7
- package/src/daemon/conversation-notifiers.ts +4 -1
- package/src/daemon/conversation-process.ts +13 -7
- package/src/daemon/conversation-runtime-assembly.ts +305 -306
- package/src/daemon/conversation-tool-setup.ts +44 -14
- package/src/daemon/conversation-workspace.ts +1 -2
- package/src/daemon/conversation.ts +59 -2
- package/src/daemon/daemon-control.ts +8 -2
- package/src/daemon/date-context.ts +26 -53
- package/src/daemon/first-greeting.ts +1 -1
- package/src/daemon/handlers/conversations.ts +4 -7
- package/src/daemon/handlers/shared.test.ts +143 -0
- package/src/daemon/handlers/shared.ts +85 -17
- package/src/daemon/handlers/skills.ts +416 -209
- package/src/daemon/lifecycle.ts +212 -131
- package/src/daemon/main.ts +5 -1
- package/src/daemon/message-types/conversations.ts +29 -7
- package/src/daemon/message-types/messages.ts +12 -2
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/settings.ts +6 -0
- package/src/daemon/message-types/skills.ts +97 -36
- package/src/daemon/profiler-run-store.ts +557 -0
- package/src/daemon/providers-setup.ts +5 -0
- package/src/daemon/server.ts +100 -11
- package/src/daemon/shutdown-handlers.ts +5 -0
- package/src/daemon/tool-side-effects.ts +50 -8
- package/src/export/transcript-formatter.ts +148 -0
- package/src/filing/filing-service.ts +228 -0
- package/src/heartbeat/heartbeat-service.ts +97 -7
- 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/mcp/client.ts +6 -0
- package/src/mcp/mcp-oauth-provider.ts +149 -27
- package/src/memory/admin.ts +42 -75
- package/src/memory/app-store.ts +69 -0
- package/src/memory/conversation-bootstrap.ts +3 -1
- package/src/memory/conversation-crud.ts +211 -288
- package/src/memory/conversation-group-migration.ts +157 -0
- package/src/memory/conversation-queries.ts +61 -13
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/db-init.ts +194 -361
- 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 +521 -0
- package/src/memory/graph/capability-seed.ts +449 -0
- package/src/memory/graph/consolidation.ts +725 -0
- package/src/memory/graph/conversation-graph-memory.ts +659 -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 +74 -0
- package/src/memory/graph/extraction.test.ts +936 -0
- package/src/memory/graph/extraction.ts +1297 -0
- package/src/memory/graph/graph-memory-state-store.ts +37 -0
- package/src/memory/graph/graph-search.ts +280 -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 +469 -0
- package/src/memory/graph/inspect.ts +543 -0
- package/src/memory/graph/narrative.ts +267 -0
- package/src/memory/graph/pattern-scan.ts +269 -0
- package/src/memory/graph/retriever.ts +1111 -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 +1098 -0
- package/src/memory/graph/store.ts +838 -0
- package/src/memory/graph/tool-handlers.ts +301 -0
- package/src/memory/graph/tools.ts +97 -0
- package/src/memory/graph/triggers.test.ts +487 -0
- package/src/memory/graph/triggers.ts +223 -0
- package/src/memory/graph/types.ts +295 -0
- package/src/memory/group-crud.ts +191 -0
- package/src/memory/indexer.ts +37 -19
- package/src/memory/job-handlers/cleanup.ts +32 -42
- 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 +21 -31
- package/src/memory/jobs-worker.ts +180 -129
- package/src/memory/llm-request-log-store.ts +96 -12
- package/src/memory/memory-recall-log-store.ts +49 -5
- 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 +55 -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/206-memory-graph-node-edits.ts +19 -0
- package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
- package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
- package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
- package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
- package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
- package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
- package/src/memory/migrations/index.ts +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-client.ts +44 -17
- package/src/memory/schema/conversations.ts +14 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/infrastructure.ts +8 -1
- package/src/memory/schema/memory-core.ts +0 -51
- package/src/memory/schema/memory-graph.ts +154 -0
- package/src/memory/search/semantic.ts +47 -91
- package/src/memory/task-memory-cleanup.ts +58 -61
- 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 +95 -0
- package/src/notifications/decision-engine.ts +35 -0
- package/src/notifications/signal.ts +16 -0
- package/src/oauth/seed-providers.ts +2 -1
- package/src/permissions/checker.ts +36 -4
- package/src/permissions/defaults.ts +4 -4
- package/src/permissions/permission-mode-store.ts +180 -0
- package/src/permissions/permission-mode.ts +31 -0
- package/src/permissions/workspace-policy.ts +10 -1
- package/src/playbooks/playbook-compiler.ts +19 -18
- package/src/playbooks/types.ts +4 -3
- package/src/prompts/system-prompt.ts +62 -36
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
- package/src/prompts/templates/BOOTSTRAP.md +70 -165
- package/src/prompts/templates/HEARTBEAT.md +3 -1
- package/src/prompts/templates/SOUL.md +25 -4
- package/src/prompts/templates/UPDATES.md +8 -0
- package/src/providers/anthropic/client.ts +136 -220
- 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 +30 -0
- package/src/runtime/guardian-reply-router.ts +5 -1
- package/src/runtime/http-server.ts +55 -5
- package/src/runtime/http-types.ts +12 -1
- package/src/runtime/middleware/auth.ts +20 -0
- package/src/runtime/migrations/vbundle-builder.ts +389 -3
- package/src/runtime/migrations/vbundle-importer.ts +8 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
- package/src/runtime/routes/app-management-routes.ts +1 -11
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
- package/src/runtime/routes/archive-utils.ts +29 -0
- package/src/runtime/routes/attachment-routes.test.ts +106 -0
- package/src/runtime/routes/attachment-routes.ts +106 -16
- package/src/runtime/routes/avatar-routes.ts +2 -9
- package/src/runtime/routes/brain-graph-routes.ts +21 -22
- package/src/runtime/routes/btw-routes.ts +22 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +173 -0
- package/src/runtime/routes/conversation-management-routes.ts +3 -14
- package/src/runtime/routes/conversation-query-routes.ts +49 -3
- package/src/runtime/routes/conversation-routes.ts +264 -44
- 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/heartbeat-routes.ts +4 -10
- package/src/runtime/routes/identity-routes.ts +53 -18
- 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/llm-context-normalization.ts +14 -10
- package/src/runtime/routes/log-export-routes.ts +23 -275
- package/src/runtime/routes/memory-item-routes.test.ts +170 -247
- package/src/runtime/routes/memory-item-routes.ts +341 -388
- package/src/runtime/routes/migration-routes.ts +18 -7
- package/src/runtime/routes/profiler-routes.ts +350 -0
- package/src/runtime/routes/schedule-routes.ts +28 -11
- package/src/runtime/routes/settings-routes.ts +95 -8
- package/src/runtime/routes/skills-routes.ts +103 -37
- package/src/runtime/routes/subagents-routes.ts +28 -7
- package/src/runtime/routes/user-route-dispatcher.ts +223 -0
- package/src/runtime/routes/user-routes.ts +41 -0
- package/src/runtime/routes/work-items-routes.test.ts +2 -6
- package/src/runtime/routes/workspace-routes.ts +0 -1
- package/src/schedule/schedule-store.ts +30 -0
- package/src/schedule/scheduler.ts +52 -18
- 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 +25 -16
- package/src/skills/clawhub.ts +134 -154
- package/src/skills/install-meta.ts +208 -0
- package/src/skills/managed-store.ts +29 -18
- package/src/skills/skill-memory.ts +12 -229
- package/src/skills/skillssh-registry.ts +19 -17
- package/src/subagent/index.ts +13 -3
- package/src/subagent/manager.ts +308 -29
- package/src/subagent/types.ts +68 -0
- package/src/tasks/task-runner.ts +7 -5
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
- package/src/tools/apps/executors.ts +29 -4
- package/src/tools/browser/runtime-check.ts +3 -1
- package/src/tools/filesystem/list.ts +93 -0
- package/src/tools/memory/register.ts +63 -46
- package/src/tools/permission-checker.ts +85 -1
- package/src/tools/registry.ts +4 -0
- package/src/tools/schedule/create.ts +3 -0
- package/src/tools/schedule/list.ts +1 -0
- package/src/tools/schedule/update.ts +6 -0
- package/src/tools/shared/filesystem/errors.ts +5 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
- package/src/tools/shared/filesystem/image-read.ts +22 -85
- package/src/tools/shared/filesystem/types.ts +17 -0
- package/src/tools/shared/shell-output.ts +31 -2
- package/src/tools/subagent/abort.ts +12 -2
- package/src/tools/subagent/message.ts +9 -2
- package/src/tools/subagent/notify-parent.ts +79 -0
- package/src/tools/subagent/read.ts +29 -8
- package/src/tools/subagent/resolve.ts +21 -0
- package/src/tools/subagent/spawn.ts +2 -0
- package/src/tools/subagent/status.ts +11 -1
- package/src/tools/system/avatar-generator.ts +3 -3
- package/src/tools/system/register.ts +23 -0
- package/src/tools/system/set-permission-mode.ts +103 -0
- package/src/tools/terminal/parser.ts +30 -5
- package/src/tools/terminal/safe-env.ts +17 -1
- package/src/tools/tool-manifest.ts +9 -3
- package/src/tools/types.ts +2 -0
- package/src/util/browser.ts +25 -10
- package/src/util/bun-runtime.ts +172 -0
- package/src/util/logger.ts +1 -1
- package/src/util/platform.ts +50 -17
- package/src/watcher/providers/outlook-calendar.ts +343 -0
- package/src/watcher/providers/outlook.ts +198 -0
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
- 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/028-recover-conversations-from-disk-view.ts +270 -0
- package/src/workspace/migrations/029-seed-pkb.ts +84 -0
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/top-level-renderer.ts +5 -9
- package/src/__tests__/cli-memory.test.ts +0 -372
- package/src/__tests__/clipboard.test.ts +0 -88
- 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/cli/cli-memory.ts +0 -176
- 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
- package/src/util/clipboard.ts +0 -34
|
@@ -42,17 +42,16 @@ import {
|
|
|
42
42
|
provenanceFromTrustContext,
|
|
43
43
|
updateConversationContextWindow,
|
|
44
44
|
updateConversationTitle,
|
|
45
|
+
updateMessageMetadata,
|
|
45
46
|
} from "../memory/conversation-crud.js";
|
|
46
|
-
import {
|
|
47
|
-
rebuildConversationDiskViewFromDbState,
|
|
48
|
-
syncMessageToDisk,
|
|
49
|
-
} from "../memory/conversation-disk-view.js";
|
|
47
|
+
import { syncMessageToDisk } from "../memory/conversation-disk-view.js";
|
|
50
48
|
import {
|
|
51
49
|
isReplaceableTitle,
|
|
52
50
|
queueGenerateConversationTitle,
|
|
53
51
|
queueRegenerateConversationTitle,
|
|
54
52
|
UNTITLED_FALLBACK,
|
|
55
53
|
} from "../memory/conversation-title-service.js";
|
|
54
|
+
import type { ConversationGraphMemory } from "../memory/graph/conversation-graph-memory.js";
|
|
56
55
|
import { recordMemoryRecallLog } from "../memory/memory-recall-log-store.js";
|
|
57
56
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
58
57
|
import type { ContentBlock, Message } from "../providers/types.js";
|
|
@@ -89,34 +88,30 @@ import {
|
|
|
89
88
|
classifyConversationError,
|
|
90
89
|
isUserCancellation,
|
|
91
90
|
} from "./conversation-error.js";
|
|
92
|
-
import { consolidateAssistantMessages } from "./conversation-history.js";
|
|
93
91
|
import { raceWithTimeout } from "./conversation-media-retry.js";
|
|
94
|
-
import { prepareMemoryContext } from "./conversation-memory.js";
|
|
95
92
|
import type { MessageQueue } from "./conversation-queue-manager.js";
|
|
96
93
|
import type { QueueDrainReason } from "./conversation-queue-manager.js";
|
|
97
94
|
import type {
|
|
98
95
|
ActiveSurfaceContext,
|
|
99
96
|
ChannelCapabilities,
|
|
100
|
-
ChannelTurnContextParams,
|
|
101
97
|
InboundActorContext,
|
|
102
98
|
InjectionMode,
|
|
103
|
-
InterfaceTurnContextParams,
|
|
104
99
|
TrustContext,
|
|
105
100
|
} from "./conversation-runtime-assembly.js";
|
|
106
101
|
import {
|
|
107
102
|
applyRuntimeInjections,
|
|
103
|
+
buildUnifiedTurnContextBlock,
|
|
104
|
+
findLastInjectedNowContent,
|
|
108
105
|
inboundActorContextFromTrust,
|
|
109
106
|
inboundActorContextFromTrustContext,
|
|
110
107
|
readNowScratchpad,
|
|
111
|
-
|
|
108
|
+
readPkbContext,
|
|
109
|
+
stripInjectionsForCompaction,
|
|
112
110
|
} from "./conversation-runtime-assembly.js";
|
|
113
111
|
import type { SkillProjectionCache } from "./conversation-skill-tools.js";
|
|
114
112
|
import { resolveTrustClass } from "./conversation-tool-setup.js";
|
|
115
113
|
import { recordUsage } from "./conversation-usage.js";
|
|
116
|
-
import {
|
|
117
|
-
buildTemporalContext,
|
|
118
|
-
extractUserTimeZoneFromRecall,
|
|
119
|
-
} from "./date-context.js";
|
|
114
|
+
import { formatTurnTimestamp } from "./date-context.js";
|
|
120
115
|
import { deepRepairHistory, repairHistory } from "./history-repair.js";
|
|
121
116
|
import type {
|
|
122
117
|
DynamicPageSurfaceData,
|
|
@@ -125,6 +120,7 @@ import type {
|
|
|
125
120
|
SurfaceType,
|
|
126
121
|
UsageStats,
|
|
127
122
|
} from "./message-protocol.js";
|
|
123
|
+
import type { MemoryRecalled } from "./message-types/memory.js";
|
|
128
124
|
import type { TraceEmitter } from "./trace-emitter.js";
|
|
129
125
|
|
|
130
126
|
const log = getLogger("conversation-agent-loop");
|
|
@@ -205,6 +201,7 @@ export interface AgentLoopConversationContext {
|
|
|
205
201
|
contextCompactedAt: number | null;
|
|
206
202
|
|
|
207
203
|
readonly memoryPolicy: { scopeId: string; includeDefaultFallback: boolean };
|
|
204
|
+
readonly graphMemory: ConversationGraphMemory;
|
|
208
205
|
|
|
209
206
|
currentActiveSurfaceId?: string;
|
|
210
207
|
currentPage?: string;
|
|
@@ -503,6 +500,7 @@ export async function runAgentLoopImpl(
|
|
|
503
500
|
}
|
|
504
501
|
|
|
505
502
|
const isFirstMessage = ctx.messages.length === 1;
|
|
503
|
+
let shouldInjectWorkspace = isFirstMessage;
|
|
506
504
|
|
|
507
505
|
const compactCheck = ctx.contextWindowManager.shouldCompact(ctx.messages);
|
|
508
506
|
if (compactCheck.needed) {
|
|
@@ -525,6 +523,9 @@ export async function runAgentLoopImpl(
|
|
|
525
523
|
ctx.messages = compacted.messages;
|
|
526
524
|
ctx.contextCompactedMessageCount += compacted.compactedPersistedMessages;
|
|
527
525
|
ctx.contextCompactedAt = Date.now();
|
|
526
|
+
// Notify memory graph that compaction happened — triggers full context
|
|
527
|
+
// reload on the next turn to replenish lost memory context.
|
|
528
|
+
ctx.graphMemory.onCompacted(compacted.compactedPersistedMessages);
|
|
528
529
|
updateConversationContextWindow(
|
|
529
530
|
ctx.conversationId,
|
|
530
531
|
compacted.summaryText,
|
|
@@ -554,6 +555,7 @@ export async function runAgentLoopImpl(
|
|
|
554
555
|
compacted.summaryCacheReadInputTokens ?? 0,
|
|
555
556
|
collapseRawResponses(compacted.summaryRawResponses),
|
|
556
557
|
);
|
|
558
|
+
shouldInjectWorkspace = true;
|
|
557
559
|
}
|
|
558
560
|
|
|
559
561
|
const state = createEventHandlerState();
|
|
@@ -597,50 +599,94 @@ export async function runAgentLoopImpl(
|
|
|
597
599
|
|
|
598
600
|
let runMessages = ctx.messages;
|
|
599
601
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
602
|
+
// Memory graph retrieval — dispatches to context-load / per-turn based on
|
|
603
|
+
// conversation state.
|
|
604
|
+
const isTrustedActor = resolveTrustClass(ctx.trustContext) === "guardian";
|
|
605
|
+
if (isTrustedActor) {
|
|
606
|
+
const graphResult = await ctx.graphMemory.prepareMemory(
|
|
607
|
+
ctx.messages,
|
|
608
|
+
getConfig(),
|
|
609
|
+
abortController.signal,
|
|
610
|
+
onEvent,
|
|
611
|
+
);
|
|
612
|
+
runMessages = graphResult.runMessages;
|
|
613
|
+
|
|
614
|
+
// Persist the injected block text in message metadata so it survives
|
|
615
|
+
// conversation reloads (eviction, restart, fork). loadFromDb re-injects
|
|
616
|
+
// from metadata.
|
|
617
|
+
if (graphResult.injectedBlockText) {
|
|
618
|
+
try {
|
|
619
|
+
updateMessageMetadata(userMessageId, {
|
|
620
|
+
memoryInjectedBlock: graphResult.injectedBlockText,
|
|
621
|
+
});
|
|
622
|
+
} catch (err) {
|
|
623
|
+
rlog.warn(
|
|
624
|
+
{ err },
|
|
625
|
+
"Failed to persist memory injection to metadata (non-fatal)",
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
615
629
|
|
|
616
|
-
|
|
630
|
+
const m = graphResult.metrics;
|
|
617
631
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
632
|
+
try {
|
|
633
|
+
recordMemoryRecallLog({
|
|
634
|
+
conversationId: ctx.conversationId,
|
|
635
|
+
enabled: true,
|
|
636
|
+
degraded: false,
|
|
637
|
+
provider: m?.embeddingProvider ?? undefined,
|
|
638
|
+
model: m?.embeddingModel ?? undefined,
|
|
639
|
+
semanticHits: m?.semanticHits ?? 0,
|
|
640
|
+
mergedCount: m?.mergedCount ?? 0,
|
|
641
|
+
selectedCount: m?.selectedCount ?? 0,
|
|
642
|
+
tier1Count: m?.tier1Count ?? 0,
|
|
643
|
+
tier2Count: m?.tier2Count ?? 0,
|
|
644
|
+
hybridSearchLatencyMs: m?.hybridSearchLatencyMs ?? 0,
|
|
645
|
+
sparseVectorUsed: m?.sparseVectorUsed ?? false,
|
|
646
|
+
injectedTokens: graphResult.injectedTokens,
|
|
647
|
+
latencyMs: graphResult.latencyMs,
|
|
648
|
+
topCandidatesJson: (m?.topCandidates ?? []).map((c) => ({
|
|
649
|
+
key: c.nodeId,
|
|
650
|
+
type: c.type,
|
|
651
|
+
kind: "graph",
|
|
652
|
+
finalScore: c.score,
|
|
653
|
+
semantic: c.semanticSimilarity,
|
|
654
|
+
recency: c.recencyBoost,
|
|
655
|
+
})),
|
|
656
|
+
injectedText: graphResult.injectedBlockText ?? undefined,
|
|
657
|
+
reason: `graph:${graphResult.mode}`,
|
|
658
|
+
queryContext: m?.queryContext ?? undefined,
|
|
659
|
+
});
|
|
660
|
+
} catch (err) {
|
|
661
|
+
log.warn({ err }, "Failed to persist memory recall log (non-fatal)");
|
|
662
|
+
}
|
|
642
663
|
|
|
643
|
-
|
|
664
|
+
if (m) {
|
|
665
|
+
const memoryRecalledEvent: MemoryRecalled = {
|
|
666
|
+
type: "memory_recalled",
|
|
667
|
+
provider: m.embeddingProvider ?? "unknown",
|
|
668
|
+
model: m.embeddingModel ?? "unknown",
|
|
669
|
+
semanticHits: m.semanticHits,
|
|
670
|
+
mergedCount: m.mergedCount,
|
|
671
|
+
selectedCount: m.selectedCount,
|
|
672
|
+
tier1Count: m.tier1Count,
|
|
673
|
+
tier2Count: m.tier2Count,
|
|
674
|
+
hybridSearchLatencyMs: m.hybridSearchLatencyMs,
|
|
675
|
+
sparseVectorUsed: m.sparseVectorUsed,
|
|
676
|
+
injectedTokens: graphResult.injectedTokens,
|
|
677
|
+
latencyMs: graphResult.latencyMs,
|
|
678
|
+
topCandidates: m.topCandidates.map((c) => ({
|
|
679
|
+
key: c.nodeId,
|
|
680
|
+
type: c.type,
|
|
681
|
+
kind: "graph",
|
|
682
|
+
finalScore: c.score,
|
|
683
|
+
semantic: c.semanticSimilarity,
|
|
684
|
+
recency: c.recencyBoost,
|
|
685
|
+
})),
|
|
686
|
+
};
|
|
687
|
+
onEvent(memoryRecalledEvent);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
644
690
|
|
|
645
691
|
// Build active surface context
|
|
646
692
|
let activeSurface: ActiveSurfaceContext | null = null;
|
|
@@ -671,39 +717,20 @@ export async function runAgentLoopImpl(
|
|
|
671
717
|
|
|
672
718
|
ctx.refreshWorkspaceTopLevelContextIfNeeded();
|
|
673
719
|
|
|
674
|
-
// Compute fresh
|
|
720
|
+
// Compute fresh turn timestamp for date grounding.
|
|
675
721
|
// Absolute "now" is always anchored to assistant host clock, while local
|
|
676
722
|
// date semantics prefer configured user timezone, then recalled memory.
|
|
677
723
|
const hostTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
678
724
|
const configuredUserTimeZone = getConfig().ui.userTimezone ?? null;
|
|
679
|
-
const recalledUserTimeZone =
|
|
680
|
-
|
|
681
|
-
);
|
|
682
|
-
const temporalContext = buildTemporalContext({
|
|
725
|
+
const recalledUserTimeZone = null;
|
|
726
|
+
const timestamp = formatTurnTimestamp({
|
|
683
727
|
hostTimeZone,
|
|
684
728
|
configuredUserTimeZone,
|
|
685
729
|
userTimeZone: recalledUserTimeZone,
|
|
686
730
|
});
|
|
687
731
|
|
|
688
|
-
//
|
|
689
|
-
//
|
|
690
|
-
// message, even if a newer message from a different channel arrived since.
|
|
691
|
-
const channelTurnContext: ChannelTurnContextParams = {
|
|
692
|
-
turnContext: capturedTurnChannelContext,
|
|
693
|
-
conversationOriginChannel: getConversationOriginChannel(
|
|
694
|
-
ctx.conversationId,
|
|
695
|
-
),
|
|
696
|
-
};
|
|
697
|
-
|
|
698
|
-
const interfaceTurnContext: InterfaceTurnContextParams = {
|
|
699
|
-
turnContext: capturedTurnInterfaceContext,
|
|
700
|
-
conversationOriginInterface: getConversationOriginInterface(
|
|
701
|
-
ctx.conversationId,
|
|
702
|
-
),
|
|
703
|
-
};
|
|
704
|
-
|
|
705
|
-
// Resolve the inbound actor context for the model's <inbound_actor_context>
|
|
706
|
-
// block. When the conversation carries enough identity info, use the unified
|
|
732
|
+
// Resolve the inbound actor context for the unified <turn_context> block.
|
|
733
|
+
// When the conversation carries enough identity info, use the unified
|
|
707
734
|
// actor trust resolver so member status/policy and guardian binding details
|
|
708
735
|
// are fresh for this turn. The conversation runtime context remains the source
|
|
709
736
|
// for policy gating; this block is model-facing grounding metadata.
|
|
@@ -724,29 +751,52 @@ export async function runAgentLoopImpl(
|
|
|
724
751
|
}
|
|
725
752
|
}
|
|
726
753
|
|
|
727
|
-
//
|
|
728
|
-
//
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
754
|
+
// Build unified turn context block that replaces the separate temporal,
|
|
755
|
+
// channel, interface, and actor context blocks.
|
|
756
|
+
const interfaceName =
|
|
757
|
+
capturedTurnInterfaceContext.userMessageInterface ?? undefined;
|
|
758
|
+
const channelName =
|
|
759
|
+
capturedTurnChannelContext?.userMessageChannel ?? undefined;
|
|
760
|
+
const isGuardian =
|
|
761
|
+
resolvedInboundActorContext?.trustClass === "guardian" ||
|
|
762
|
+
!resolvedInboundActorContext;
|
|
763
|
+
const unifiedTurnContextStr = buildUnifiedTurnContextBlock(
|
|
764
|
+
isGuardian
|
|
765
|
+
? { timestamp, interfaceName, channelName }
|
|
766
|
+
: {
|
|
767
|
+
timestamp,
|
|
768
|
+
interfaceName,
|
|
769
|
+
channelName,
|
|
770
|
+
actorContext: resolvedInboundActorContext,
|
|
771
|
+
},
|
|
772
|
+
);
|
|
773
|
+
|
|
774
|
+
// The `remember` tool handles scratchpad-style memory writes directly to the graph.
|
|
736
775
|
|
|
737
776
|
const isInteractiveResolved =
|
|
738
777
|
options?.isInteractive ?? (!ctx.hasNoClient && !ctx.headlessLock);
|
|
739
778
|
|
|
779
|
+
// Only inject NOW.md if it changed since the last injection in the
|
|
780
|
+
// conversation. Keeping the previous injection in place avoids mutating
|
|
781
|
+
// historical user messages and preserves the cached prefix.
|
|
782
|
+
const currentNowContent = readNowScratchpad();
|
|
783
|
+
const lastInjectedNow = findLastInjectedNowContent(ctx.messages);
|
|
784
|
+
const nowScratchpad =
|
|
785
|
+
currentNowContent !== lastInjectedNow ? currentNowContent : null;
|
|
786
|
+
|
|
787
|
+
// Read PKB always-loaded files (INDEX, essentials, threads, buffer)
|
|
788
|
+
const currentPkbContent = readPkbContext();
|
|
789
|
+
|
|
740
790
|
// Shared injection options — reused whenever we need to re-inject after reduction.
|
|
741
791
|
const injectionOpts = {
|
|
742
792
|
activeSurface,
|
|
743
|
-
workspaceTopLevelContext:
|
|
793
|
+
workspaceTopLevelContext: shouldInjectWorkspace
|
|
794
|
+
? ctx.workspaceTopLevelContext
|
|
795
|
+
: null,
|
|
744
796
|
channelCapabilities: ctx.channelCapabilities ?? null,
|
|
745
797
|
channelCommandContext: ctx.commandIntent ?? null,
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
inboundActorContext: resolvedInboundActorContext,
|
|
749
|
-
temporalContext,
|
|
798
|
+
unifiedTurnContext: unifiedTurnContextStr,
|
|
799
|
+
pkbContext: currentPkbContent,
|
|
750
800
|
nowScratchpad,
|
|
751
801
|
voiceCallControlPrompt: ctx.voiceCallControlPrompt ?? null,
|
|
752
802
|
transportHints: ctx.transportHints ?? null,
|
|
@@ -860,13 +910,29 @@ export async function runAgentLoopImpl(
|
|
|
860
910
|
step.compactionResult.summaryCacheReadInputTokens ?? 0,
|
|
861
911
|
collapseRawResponses(step.compactionResult.summaryRawResponses),
|
|
862
912
|
);
|
|
913
|
+
ctx.graphMemory.onCompacted(
|
|
914
|
+
step.compactionResult.compactedPersistedMessages,
|
|
915
|
+
);
|
|
916
|
+
shouldInjectWorkspace = true;
|
|
863
917
|
}
|
|
864
918
|
|
|
865
|
-
// Re-inject with potentially downgraded injection mode
|
|
919
|
+
// Re-inject with potentially downgraded injection mode.
|
|
920
|
+
// When compaction ran it strips existing NOW.md / PKB blocks, so we
|
|
921
|
+
// must re-inject the current content. Otherwise rely on the deduplicated
|
|
922
|
+
// value from injectionOpts to avoid duplicate injection.
|
|
866
923
|
runMessages = applyRuntimeInjections(ctx.messages, {
|
|
867
924
|
...injectionOpts,
|
|
925
|
+
pkbContext: currentPkbContent,
|
|
926
|
+
...(step.compactionResult?.compacted && { nowScratchpad: currentNowContent }),
|
|
927
|
+
workspaceTopLevelContext: shouldInjectWorkspace
|
|
928
|
+
? ctx.workspaceTopLevelContext
|
|
929
|
+
: null,
|
|
868
930
|
mode: currentInjectionMode,
|
|
869
931
|
});
|
|
932
|
+
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
933
|
+
const memResult = ctx.graphMemory.reinjectCachedMemory(runMessages);
|
|
934
|
+
runMessages = memResult.runMessages;
|
|
935
|
+
}
|
|
870
936
|
|
|
871
937
|
// Re-estimate with injections included — step.estimatedTokens was
|
|
872
938
|
// computed on bare history (ctx.messages) and doesn't account for
|
|
@@ -990,7 +1056,7 @@ export async function runAgentLoopImpl(
|
|
|
990
1056
|
|
|
991
1057
|
// Strip injected context from updated history before compacting,
|
|
992
1058
|
// so we compact the "raw" persistent messages.
|
|
993
|
-
const rawHistory =
|
|
1059
|
+
const rawHistory = stripInjectionsForCompaction(updatedHistory);
|
|
994
1060
|
ctx.messages = rawHistory;
|
|
995
1061
|
|
|
996
1062
|
ctx.emitActivityState(
|
|
@@ -1044,13 +1110,27 @@ export async function runAgentLoopImpl(
|
|
|
1044
1110
|
midLoopCompact.summaryCacheReadInputTokens ?? 0,
|
|
1045
1111
|
collapseRawResponses(midLoopCompact.summaryRawResponses),
|
|
1046
1112
|
);
|
|
1113
|
+
ctx.graphMemory.onCompacted(midLoopCompact.compactedPersistedMessages);
|
|
1114
|
+
shouldInjectWorkspace = true;
|
|
1047
1115
|
}
|
|
1048
1116
|
|
|
1049
|
-
// Re-inject runtime context and re-enter the agent loop
|
|
1117
|
+
// Re-inject runtime context and re-enter the agent loop.
|
|
1118
|
+
// stripInjectionsForCompaction() unconditionally removed the existing
|
|
1119
|
+
// NOW.md block from ctx.messages above, so we must always re-inject
|
|
1120
|
+
// the current content regardless of whether compaction actually ran.
|
|
1050
1121
|
runMessages = applyRuntimeInjections(ctx.messages, {
|
|
1051
1122
|
...injectionOpts,
|
|
1123
|
+
pkbContext: currentPkbContent,
|
|
1124
|
+
nowScratchpad: currentNowContent,
|
|
1125
|
+
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1126
|
+
? ctx.workspaceTopLevelContext
|
|
1127
|
+
: null,
|
|
1052
1128
|
mode: currentInjectionMode,
|
|
1053
1129
|
});
|
|
1130
|
+
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
1131
|
+
const memResult = ctx.graphMemory.reinjectCachedMemory(runMessages);
|
|
1132
|
+
runMessages = memResult.runMessages;
|
|
1133
|
+
}
|
|
1054
1134
|
preRepairMessages = runMessages;
|
|
1055
1135
|
preRunHistoryLength = runMessages.length;
|
|
1056
1136
|
|
|
@@ -1123,7 +1203,7 @@ export async function runAgentLoopImpl(
|
|
|
1123
1203
|
// convergence loop operates on the full (larger) history.
|
|
1124
1204
|
if (state.contextTooLargeDetected) {
|
|
1125
1205
|
if (updatedHistory.length > preRunHistoryLength) {
|
|
1126
|
-
ctx.messages =
|
|
1206
|
+
ctx.messages = stripInjectionsForCompaction(updatedHistory);
|
|
1127
1207
|
preRepairMessages = updatedHistory;
|
|
1128
1208
|
preRunHistoryLength = updatedHistory.length;
|
|
1129
1209
|
}
|
|
@@ -1240,12 +1320,27 @@ export async function runAgentLoopImpl(
|
|
|
1240
1320
|
step.compactionResult.summaryCacheReadInputTokens ?? 0,
|
|
1241
1321
|
collapseRawResponses(step.compactionResult.summaryRawResponses),
|
|
1242
1322
|
);
|
|
1323
|
+
ctx.graphMemory.onCompacted(
|
|
1324
|
+
step.compactionResult.compactedPersistedMessages,
|
|
1325
|
+
);
|
|
1326
|
+
shouldInjectWorkspace = true;
|
|
1243
1327
|
}
|
|
1244
1328
|
|
|
1329
|
+
// ctx.messages has been stripped (line 1206/1373) so NOW.md must
|
|
1330
|
+
// always be re-injected regardless of whether compaction ran.
|
|
1245
1331
|
runMessages = applyRuntimeInjections(ctx.messages, {
|
|
1246
1332
|
...injectionOpts,
|
|
1333
|
+
pkbContext: currentPkbContent,
|
|
1334
|
+
nowScratchpad: currentNowContent,
|
|
1335
|
+
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1336
|
+
? ctx.workspaceTopLevelContext
|
|
1337
|
+
: null,
|
|
1247
1338
|
mode: currentInjectionMode,
|
|
1248
1339
|
});
|
|
1340
|
+
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
1341
|
+
const memResult = ctx.graphMemory.reinjectCachedMemory(runMessages);
|
|
1342
|
+
runMessages = memResult.runMessages;
|
|
1343
|
+
}
|
|
1249
1344
|
preRepairMessages = runMessages;
|
|
1250
1345
|
preRunHistoryLength = runMessages.length;
|
|
1251
1346
|
state.contextTooLargeDetected = false;
|
|
@@ -1277,7 +1372,7 @@ export async function runAgentLoopImpl(
|
|
|
1277
1372
|
// tier operates on up-to-date history instead of stale
|
|
1278
1373
|
// pre-rerun messages.
|
|
1279
1374
|
if (updatedHistory.length > preRunHistoryLength) {
|
|
1280
|
-
ctx.messages =
|
|
1375
|
+
ctx.messages = stripInjectionsForCompaction(updatedHistory);
|
|
1281
1376
|
preRepairMessages = updatedHistory;
|
|
1282
1377
|
preRunHistoryLength = updatedHistory.length;
|
|
1283
1378
|
}
|
|
@@ -1347,12 +1442,28 @@ export async function runAgentLoopImpl(
|
|
|
1347
1442
|
emergencyCompact.summaryCacheReadInputTokens ?? 0,
|
|
1348
1443
|
collapseRawResponses(emergencyCompact.summaryRawResponses),
|
|
1349
1444
|
);
|
|
1445
|
+
ctx.graphMemory.onCompacted(
|
|
1446
|
+
emergencyCompact.compactedPersistedMessages,
|
|
1447
|
+
);
|
|
1448
|
+
shouldInjectWorkspace = true;
|
|
1350
1449
|
}
|
|
1351
1450
|
|
|
1451
|
+
// ctx.messages was already stripped before the convergence
|
|
1452
|
+
// loop, so NOW.md must always be re-injected here.
|
|
1352
1453
|
runMessages = applyRuntimeInjections(ctx.messages, {
|
|
1353
1454
|
...injectionOpts,
|
|
1455
|
+
pkbContext: currentPkbContent,
|
|
1456
|
+
nowScratchpad: currentNowContent,
|
|
1457
|
+
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1458
|
+
? ctx.workspaceTopLevelContext
|
|
1459
|
+
: null,
|
|
1354
1460
|
mode: currentInjectionMode,
|
|
1355
1461
|
});
|
|
1462
|
+
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
1463
|
+
const memResult =
|
|
1464
|
+
ctx.graphMemory.reinjectCachedMemory(runMessages);
|
|
1465
|
+
runMessages = memResult.runMessages;
|
|
1466
|
+
}
|
|
1356
1467
|
preRepairMessages = runMessages;
|
|
1357
1468
|
preRunHistoryLength = runMessages.length;
|
|
1358
1469
|
state.contextTooLargeDetected = false;
|
|
@@ -1451,12 +1562,27 @@ export async function runAgentLoopImpl(
|
|
|
1451
1562
|
emergencyCompact.summaryCacheReadInputTokens ?? 0,
|
|
1452
1563
|
collapseRawResponses(emergencyCompact.summaryRawResponses),
|
|
1453
1564
|
);
|
|
1565
|
+
ctx.graphMemory.onCompacted(
|
|
1566
|
+
emergencyCompact.compactedPersistedMessages,
|
|
1567
|
+
);
|
|
1568
|
+
shouldInjectWorkspace = true;
|
|
1454
1569
|
}
|
|
1455
1570
|
|
|
1571
|
+
// ctx.messages was already stripped before the convergence
|
|
1572
|
+
// loop, so NOW.md must always be re-injected here.
|
|
1456
1573
|
runMessages = applyRuntimeInjections(ctx.messages, {
|
|
1457
1574
|
...injectionOpts,
|
|
1575
|
+
pkbContext: currentPkbContent,
|
|
1576
|
+
nowScratchpad: currentNowContent,
|
|
1577
|
+
workspaceTopLevelContext: shouldInjectWorkspace
|
|
1578
|
+
? ctx.workspaceTopLevelContext
|
|
1579
|
+
: null,
|
|
1458
1580
|
mode: currentInjectionMode,
|
|
1459
1581
|
});
|
|
1582
|
+
if (isTrustedActor && currentInjectionMode !== "minimal") {
|
|
1583
|
+
const memResult = ctx.graphMemory.reinjectCachedMemory(runMessages);
|
|
1584
|
+
runMessages = memResult.runMessages;
|
|
1585
|
+
}
|
|
1460
1586
|
preRepairMessages = runMessages;
|
|
1461
1587
|
preRunHistoryLength = runMessages.length;
|
|
1462
1588
|
state.contextTooLargeDetected = false;
|
|
@@ -1594,7 +1720,11 @@ export async function runAgentLoopImpl(
|
|
|
1594
1720
|
{ providerName: ctx.provider.name, toolTokenBudget },
|
|
1595
1721
|
);
|
|
1596
1722
|
|
|
1597
|
-
|
|
1723
|
+
// Persist injections in history: runtime-injected context stays on
|
|
1724
|
+
// historical user messages so the conversation prefix is stable for
|
|
1725
|
+
// Anthropic's prefix caching. Stripping only happens during
|
|
1726
|
+
// compaction/overflow recovery (where a cache miss is expected).
|
|
1727
|
+
ctx.messages = restoredHistory;
|
|
1598
1728
|
|
|
1599
1729
|
emitUsage(
|
|
1600
1730
|
ctx,
|
|
@@ -1609,7 +1739,10 @@ export async function runAgentLoopImpl(
|
|
|
1609
1739
|
collapseRawResponses(state.exchangeRawResponses),
|
|
1610
1740
|
state.exchangeProviderName,
|
|
1611
1741
|
state.exchangeLlmCallCount,
|
|
1612
|
-
{
|
|
1742
|
+
{
|
|
1743
|
+
tokens: postLoopContextEstimate,
|
|
1744
|
+
maxTokens: config.contextWindow.maxInputTokens,
|
|
1745
|
+
},
|
|
1613
1746
|
);
|
|
1614
1747
|
|
|
1615
1748
|
void getHookManager().trigger("post-message", {
|
|
@@ -1842,15 +1975,10 @@ export async function runAgentLoopImpl(
|
|
|
1842
1975
|
// Clear at turn end so they never leak into subsequent unrelated messages.
|
|
1843
1976
|
ctx.commandIntent = undefined;
|
|
1844
1977
|
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
);
|
|
1850
|
-
if (didMutateHistory) {
|
|
1851
|
-
rebuildConversationDiskViewFromDbState(ctx.conversationId);
|
|
1852
|
-
}
|
|
1853
|
-
}
|
|
1978
|
+
// Consolidation deferred to compaction: keeping assistant + tool_result
|
|
1979
|
+
// messages unconsolidated preserves the exact message structure sent to
|
|
1980
|
+
// the API, enabling stable prefix caching across turns. Compaction
|
|
1981
|
+
// consolidates when it summarizes old messages (cache miss is expected).
|
|
1854
1982
|
|
|
1855
1983
|
ctx.drainQueue(yieldedForHandoff ? "checkpoint_handoff" : "loop_complete");
|
|
1856
1984
|
|
|
@@ -33,12 +33,10 @@ const NETWORK_PATTERNS = [
|
|
|
33
33
|
];
|
|
34
34
|
|
|
35
35
|
// Rate limit patterns (HTTP 429 or explicit rate limit messages)
|
|
36
|
-
const RATE_LIMIT_PATTERNS = [
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
/overloaded/i,
|
|
41
|
-
];
|
|
36
|
+
const RATE_LIMIT_PATTERNS = [/429/, /rate.?limit/i, /too many requests/i];
|
|
37
|
+
|
|
38
|
+
// Overloaded patterns — provider is capacity-constrained (distinct from rate limiting)
|
|
39
|
+
const OVERLOADED_PATTERNS = [/overloaded/i];
|
|
42
40
|
|
|
43
41
|
// Context-too-large patterns (request exceeds the model's context window)
|
|
44
42
|
const CONTEXT_TOO_LARGE_PATTERNS = [
|
|
@@ -249,11 +247,22 @@ function classifyCore(
|
|
|
249
247
|
if (error.statusCode === 429) {
|
|
250
248
|
return {
|
|
251
249
|
code: "PROVIDER_RATE_LIMIT",
|
|
252
|
-
userMessage:
|
|
250
|
+
userMessage:
|
|
251
|
+
"You are being rate limited by the AI provider. Please try again in a moment.",
|
|
253
252
|
retryable: true,
|
|
254
253
|
errorCategory: "rate_limit",
|
|
255
254
|
};
|
|
256
255
|
}
|
|
256
|
+
// Anthropic uses 529 for overloaded_error
|
|
257
|
+
if (error.statusCode === 529) {
|
|
258
|
+
return {
|
|
259
|
+
code: "PROVIDER_OVERLOADED",
|
|
260
|
+
userMessage:
|
|
261
|
+
"The AI provider is temporarily overloaded. Please try again in a moment.",
|
|
262
|
+
retryable: true,
|
|
263
|
+
errorCategory: "provider_overloaded",
|
|
264
|
+
};
|
|
265
|
+
}
|
|
257
266
|
if (error.statusCode >= 500) {
|
|
258
267
|
return {
|
|
259
268
|
code: "PROVIDER_API",
|
|
@@ -363,13 +372,27 @@ function classifyByMessage(
|
|
|
363
372
|
if (pattern.test(message)) {
|
|
364
373
|
return {
|
|
365
374
|
code: "PROVIDER_RATE_LIMIT",
|
|
366
|
-
userMessage:
|
|
375
|
+
userMessage:
|
|
376
|
+
"You are being rate limited by the AI provider. Please try again in a moment.",
|
|
367
377
|
retryable: true,
|
|
368
378
|
errorCategory: "rate_limit",
|
|
369
379
|
};
|
|
370
380
|
}
|
|
371
381
|
}
|
|
372
382
|
|
|
383
|
+
// Overloaded — provider is capacity-constrained (not the user's fault)
|
|
384
|
+
for (const pattern of OVERLOADED_PATTERNS) {
|
|
385
|
+
if (pattern.test(message)) {
|
|
386
|
+
return {
|
|
387
|
+
code: "PROVIDER_OVERLOADED",
|
|
388
|
+
userMessage:
|
|
389
|
+
"The AI provider is temporarily overloaded. Please try again in a moment.",
|
|
390
|
+
retryable: true,
|
|
391
|
+
errorCategory: "provider_overloaded",
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
373
396
|
// Web-search ordering errors (before general ordering errors)
|
|
374
397
|
if (isWebSearchOrderingError(message)) {
|
|
375
398
|
return {
|