@vellumai/assistant 0.5.1 → 0.5.3
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 +163 -54
- package/docs/architecture/integrations.md +62 -67
- package/docs/credential-execution-service.md +3 -3
- package/docs/skills.md +100 -0
- package/package.json +1 -1
- package/src/__tests__/agent-loop.test.ts +111 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +3 -4
- package/src/__tests__/app-builder-tool-scripts.test.ts +13 -151
- package/src/__tests__/app-dir-path-guard.test.ts +78 -0
- package/src/__tests__/app-executors.test.ts +1 -291
- package/src/__tests__/app-git-history.test.ts +4 -4
- package/src/__tests__/app-routes-csp.test.ts +1 -0
- package/src/__tests__/app-store-dir-names.test.ts +426 -0
- package/src/__tests__/attachments-store.test.ts +169 -21
- package/src/__tests__/attachments.test.ts +115 -1
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/canonical-guardian-store.test.ts +38 -0
- package/src/__tests__/channel-reply-delivery.test.ts +55 -0
- package/src/__tests__/checker.test.ts +54 -0
- package/src/__tests__/claude-code-skill-regression.test.ts +2 -0
- package/src/__tests__/claude-code-tool-profiles.test.ts +2 -0
- package/src/__tests__/compaction.benchmark.test.ts +2 -1
- package/src/__tests__/config-schema-cmd.test.ts +68 -21
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +156 -5
- package/src/__tests__/conversation-agent-loop.test.ts +297 -2
- package/src/__tests__/conversation-attachments.test.ts +17 -19
- package/src/__tests__/conversation-disk-view-integration.test.ts +277 -0
- package/src/__tests__/conversation-disk-view.test.ts +810 -0
- package/src/__tests__/conversation-error.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +551 -0
- package/src/__tests__/conversation-fork-route.test.ts +386 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +130 -0
- package/src/__tests__/conversation-media-retry.test.ts +8 -2
- package/src/__tests__/conversation-memory-dirty-tail.test.ts +150 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +7 -0
- package/src/__tests__/conversation-queue.test.ts +36 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +439 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -7
- package/src/__tests__/conversation-runtime-assembly.test.ts +17 -2
- package/src/__tests__/conversation-skill-tools.test.ts +4 -9
- package/src/__tests__/conversation-slash-commands.test.ts +149 -0
- package/src/__tests__/conversation-store.test.ts +24 -21
- package/src/__tests__/conversation-surfaces-state-update.test.ts +246 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +1 -0
- package/src/__tests__/conversation-title-service.test.ts +137 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +25 -315
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-side-effect-flag.test.ts +1 -0
- package/src/__tests__/conversation-wipe.test.ts +226 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +44 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +11 -0
- package/src/__tests__/credential-security-invariants.test.ts +3 -0
- package/src/__tests__/credential-vault-unit.test.ts +5 -10
- package/src/__tests__/cu-unified-flow.test.ts +1 -0
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +241 -0
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +214 -0
- package/src/__tests__/db-memory-archive-migration.test.ts +372 -0
- package/src/__tests__/db-memory-brief-state-migration.test.ts +213 -0
- package/src/__tests__/db-memory-reducer-checkpoints.test.ts +273 -0
- package/src/__tests__/diagnostics-export.test.ts +70 -1
- package/src/__tests__/first-greeting.test.ts +80 -0
- package/src/__tests__/gateway-only-guard.test.ts +1 -0
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +3 -7
- package/src/__tests__/history-repair.test.ts +32 -10
- package/src/__tests__/http-conversation-lineage.test.ts +251 -0
- package/src/__tests__/image-source-path-reinject.test.ts +136 -0
- package/src/__tests__/inline-command-runner.test.ts +311 -0
- package/src/__tests__/inline-skill-authoring-guard.test.ts +220 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +435 -0
- package/src/__tests__/list-messages-attachments.test.ts +96 -0
- package/src/__tests__/llm-context-normalization.test.ts +1116 -0
- package/src/__tests__/llm-context-route-provider.test.ts +217 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +270 -0
- package/src/__tests__/media-generate-image.test.ts +47 -94
- package/src/__tests__/memory-brief-open-loops.test.ts +530 -0
- package/src/__tests__/memory-brief-time.test.ts +285 -0
- package/src/__tests__/memory-brief-wrapper.test.ts +311 -0
- package/src/__tests__/memory-chunk-archive.test.ts +400 -0
- package/src/__tests__/memory-chunk-dual-write.test.ts +453 -0
- package/src/__tests__/memory-episode-archive.test.ts +370 -0
- package/src/__tests__/memory-episode-dual-write.test.ts +626 -0
- package/src/__tests__/memory-lifecycle-e2e.test.ts +3 -1
- package/src/__tests__/memory-observation-archive.test.ts +375 -0
- package/src/__tests__/memory-observation-dual-write.test.ts +318 -0
- package/src/__tests__/memory-recall-quality.test.ts +7 -7
- package/src/__tests__/memory-reducer-store.test.ts +728 -0
- package/src/__tests__/memory-reducer-types.test.ts +699 -0
- package/src/__tests__/memory-reducer.test.ts +698 -0
- package/src/__tests__/memory-regressions.test.ts +6 -4
- package/src/__tests__/memory-simplified-config.test.ts +281 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +4 -1
- package/src/__tests__/migration-export-http.test.ts +3 -1
- package/src/__tests__/migration-import-commit-http.test.ts +18 -4
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -3
- package/src/__tests__/mime-builder.test.ts +3 -2
- package/src/__tests__/non-member-access-request.test.ts +12 -1
- package/src/__tests__/notification-decision-identity.test.ts +52 -0
- package/src/__tests__/oauth-apps-routes.test.ts +103 -0
- package/src/__tests__/oauth-store.test.ts +115 -0
- package/src/__tests__/parse-identity-fields.test.ts +129 -0
- package/src/__tests__/provider-error-scenarios.test.ts +1 -3
- package/src/__tests__/provider-failover-actual-provider.test.ts +66 -0
- package/src/__tests__/recording-handler.test.ts +17 -0
- package/src/__tests__/registry.test.ts +3 -8
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/runtime-attachment-metadata.test.ts +7 -3
- package/src/__tests__/schema-transforms.test.ts +165 -5
- package/src/__tests__/server-history-render.test.ts +2 -2
- package/src/__tests__/skill-load-inline-command.test.ts +598 -0
- package/src/__tests__/skill-load-inline-includes.test.ts +644 -0
- package/src/__tests__/skills-inline-command-expansions.test.ts +301 -0
- package/src/__tests__/skills-transitive-hash.test.ts +333 -0
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-inbound-verification.test.ts +2 -2
- package/src/__tests__/starter-task-flow.test.ts +1 -0
- package/src/__tests__/suggestion-routes.test.ts +443 -0
- package/src/__tests__/swarm-conversation-integration.test.ts +1 -0
- package/src/__tests__/swarm-recursion.test.ts +1 -0
- package/src/__tests__/swarm-tool.test.ts +1 -0
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -5
- package/src/__tests__/top-level-renderer.test.ts +22 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +243 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +320 -0
- package/src/__tests__/web-fetch.test.ts +6 -2
- package/src/__tests__/workspace-migration-006-services-config.test.ts +335 -0
- package/src/__tests__/workspace-migration-007-web-search-provider-rename.test.ts +312 -0
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +278 -0
- package/src/__tests__/workspace-migration-010-app-dir-rename.test.ts +275 -0
- package/src/__tests__/workspace-migration-012-rename-conversation-disk-view-dirs.test.ts +77 -0
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +401 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +328 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +6 -10
- package/src/agent/attachments.ts +27 -1
- package/src/agent/loop.ts +29 -1
- package/src/avatar/traits-png-sync.ts +80 -25
- package/src/bundler/app-bundler.ts +4 -4
- package/src/calls/call-domain.ts +1 -0
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/cli/commands/auth.ts +92 -0
- package/src/cli/commands/avatar.ts +7 -6
- package/src/cli/commands/config.ts +2 -0
- package/src/cli/commands/oauth/providers.ts +29 -0
- package/src/cli/program.ts +12 -0
- package/src/cli.ts +15 -48
- package/src/config/bundled-skills/app-builder/SKILL.md +103 -28
- package/src/config/bundled-skills/app-builder/TOOLS.json +5 -199
- package/src/config/bundled-skills/app-builder/tools/{app-query.ts → app-refresh.ts} +2 -2
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +6 -9
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +4 -6
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +4 -6
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +2 -3
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +1 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -2
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +45 -72
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +19 -3
- package/src/config/bundled-skills/skill-management/SKILL.md +1 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
- package/src/config/bundled-skills/slack/tools/shared.ts +19 -4
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +2 -3
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -1
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -6
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +19 -83
- package/src/config/bundled-tool-registry.ts +2 -14
- package/src/config/feature-flag-registry.json +24 -0
- package/src/config/loader.ts +65 -0
- package/src/config/raw-config-utils.ts +58 -0
- package/src/config/schema-utils.ts +28 -7
- package/src/config/schema.ts +20 -0
- package/src/config/schemas/elevenlabs.ts +18 -0
- package/src/config/schemas/memory-lifecycle.ts +4 -2
- package/src/config/schemas/memory-simplified.ts +101 -0
- package/src/config/schemas/memory-storage.ts +1 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +8 -6
- package/src/config/skills.ts +50 -4
- package/src/contacts/contact-store.ts +13 -6
- package/src/contacts/contacts-write.ts +0 -1
- package/src/context/window-manager.ts +13 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +54 -8
- package/src/daemon/conversation-agent-loop.ts +127 -20
- package/src/daemon/conversation-attachments.ts +18 -36
- package/src/daemon/conversation-error.ts +2 -1
- package/src/daemon/conversation-history.ts +18 -4
- package/src/daemon/conversation-lifecycle.ts +50 -16
- package/src/daemon/conversation-messaging.ts +70 -26
- package/src/daemon/conversation-process.ts +58 -34
- package/src/daemon/conversation-runtime-assembly.ts +22 -38
- package/src/daemon/conversation-slash.ts +121 -256
- package/src/daemon/conversation-surfaces.ts +170 -24
- package/src/daemon/conversation-tool-setup.ts +0 -6
- package/src/daemon/conversation-workspace.ts +21 -1
- package/src/daemon/conversation.ts +69 -30
- package/src/daemon/first-greeting.ts +35 -0
- package/src/daemon/handlers/config-embeddings.ts +156 -0
- package/src/daemon/handlers/config-model.ts +62 -26
- package/src/daemon/handlers/conversations.ts +0 -23
- package/src/daemon/handlers/identity.ts +12 -1
- package/src/daemon/handlers/recording.ts +26 -21
- package/src/daemon/host-cu-proxy.ts +2 -2
- package/src/daemon/lifecycle.ts +115 -65
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/conversations.ts +18 -0
- package/src/daemon/message-types/messages.ts +1 -0
- package/src/daemon/message-types/shared.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/upgrades.ts +23 -0
- package/src/daemon/server.ts +83 -12
- package/src/daemon/shutdown-handlers.ts +8 -5
- package/src/daemon/startup-error.ts +9 -0
- package/src/daemon/tool-side-effects.ts +11 -28
- package/src/events/tool-permission-telemetry-listener.ts +1 -3
- package/src/followups/followup-store.ts +47 -1
- package/src/instrument.ts +0 -4
- package/src/media/app-icon-generator.ts +2 -2
- package/src/memory/app-git-service.ts +28 -16
- package/src/memory/app-store.ts +230 -41
- package/src/memory/archive-store.ts +400 -0
- package/src/memory/attachments-store.ts +558 -130
- package/src/memory/brief-formatting.ts +33 -0
- package/src/memory/brief-open-loops.ts +266 -0
- package/src/memory/brief-time.ts +161 -0
- package/src/memory/brief.ts +75 -0
- package/src/memory/conversation-attention-store.ts +70 -0
- package/src/memory/conversation-crud.ts +591 -8
- package/src/memory/conversation-directories.ts +125 -0
- package/src/memory/conversation-disk-view.ts +390 -0
- package/src/memory/conversation-key-store.ts +17 -5
- package/src/memory/conversation-queries.ts +5 -1
- package/src/memory/conversation-title-service.ts +21 -49
- package/src/memory/db-init.ts +40 -0
- package/src/memory/embedding-backend.ts +42 -53
- package/src/memory/embedding-gemini.test.ts +4 -4
- package/src/memory/embedding-local.ts +1 -3
- package/src/memory/embedding-ollama.ts +1 -3
- package/src/memory/embedding-openai.ts +1 -3
- package/src/memory/indexer.ts +114 -21
- package/src/memory/items-extractor.ts +42 -13
- package/src/memory/job-handlers/conversation-starters.ts +6 -1
- package/src/memory/job-handlers/embedding.test.ts +2 -4
- package/src/memory/job-handlers/embedding.ts +83 -0
- package/src/memory/job-utils.ts +1 -1
- package/src/memory/jobs-store.ts +6 -0
- package/src/memory/jobs-worker.ts +12 -0
- package/src/memory/llm-request-log-store.ts +100 -1
- package/src/memory/migrations/102-alter-table-columns.ts +5 -0
- package/src/memory/migrations/146-schedule-oneshot-routing.ts +3 -3
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +66 -70
- package/src/memory/migrations/148-drop-reminders-table.ts +5 -9
- package/src/memory/migrations/160-drop-loopback-port-column.ts +1 -3
- package/src/memory/migrations/174-rename-thread-starters-table.ts +0 -7
- package/src/memory/migrations/178-oauth-providers-managed-service-config-key.ts +15 -0
- package/src/memory/migrations/179-llm-request-log-message-id.ts +16 -0
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +66 -0
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +46 -0
- package/src/memory/migrations/182-oauth-providers-display-metadata.ts +20 -0
- package/src/memory/migrations/183-add-conversation-fork-lineage.ts +22 -0
- package/src/memory/migrations/184-llm-request-log-provider.ts +12 -0
- package/src/memory/migrations/185-memory-brief-state.ts +52 -0
- package/src/memory/migrations/186-memory-archive.ts +109 -0
- package/src/memory/migrations/187-memory-reducer-checkpoints.ts +19 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +13 -0
- package/src/memory/qdrant-client.ts +23 -4
- package/src/memory/reducer-store.ts +271 -0
- package/src/memory/reducer-types.ts +99 -0
- package/src/memory/reducer.ts +453 -0
- package/src/memory/retriever.test.ts +601 -2
- package/src/memory/retriever.ts +85 -9
- package/src/memory/schema/conversations.ts +9 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/infrastructure.ts +13 -7
- package/src/memory/schema/memory-archive.ts +121 -0
- package/src/memory/schema/memory-brief.ts +55 -0
- package/src/memory/schema/oauth.ts +6 -0
- package/src/memory/search/semantic.ts +17 -4
- package/src/messaging/providers/gmail/mime-builder.ts +3 -1
- package/src/notifications/copy-composer.ts +26 -0
- package/src/notifications/decision-engine.ts +14 -1
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/signal.ts +36 -0
- package/src/oauth/byo-connection.test.ts +1 -45
- package/src/oauth/byo-connection.ts +2 -8
- package/src/oauth/connect-orchestrator.ts +15 -11
- package/src/oauth/connection-resolver.test.ts +191 -0
- package/src/oauth/connection-resolver.ts +66 -38
- package/src/oauth/connection.ts +0 -1
- package/src/oauth/oauth-store.ts +99 -47
- package/src/oauth/platform-connection.test.ts +0 -1
- package/src/oauth/platform-connection.ts +11 -3
- package/src/oauth/seed-providers.ts +78 -3
- package/src/oauth/token-persistence.ts +16 -10
- package/src/permissions/checker.ts +160 -14
- package/src/permissions/defaults.ts +14 -0
- package/src/prompts/templates/BOOTSTRAP.md +2 -0
- package/src/providers/anthropic/client.ts +8 -1
- package/src/providers/failover.ts +4 -1
- package/src/providers/gemini/client.ts +50 -0
- package/src/providers/model-catalog.ts +92 -0
- package/src/providers/model-intents.ts +29 -20
- package/src/providers/openai/client.ts +49 -0
- package/src/providers/types.ts +2 -0
- package/src/runtime/access-request-helper.ts +16 -7
- package/src/runtime/auth/credential-service.ts +3 -1
- package/src/runtime/auth/route-policy.ts +14 -1
- package/src/runtime/btw-sidechain.ts +101 -0
- package/src/runtime/channel-reply-delivery.ts +17 -1
- package/src/runtime/http-router.ts +3 -1
- package/src/runtime/http-server.ts +196 -141
- package/src/runtime/http-types.ts +1 -0
- package/src/runtime/migrations/vbundle-builder.ts +5 -1
- package/src/runtime/routes/access-request-decision.ts +41 -0
- package/src/runtime/routes/app-management-routes.ts +6 -3
- package/src/runtime/routes/app-routes.ts +7 -3
- package/src/runtime/routes/approval-routes.ts +1 -0
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +34 -2
- package/src/runtime/routes/attachment-routes.ts +45 -15
- package/src/runtime/routes/btw-routes.ts +21 -61
- package/src/runtime/routes/conversation-management-routes.ts +74 -0
- package/src/runtime/routes/conversation-query-routes.ts +187 -10
- package/src/runtime/routes/conversation-routes.ts +269 -28
- package/src/runtime/routes/conversation-starter-routes.ts +9 -11
- package/src/runtime/routes/diagnostics-routes.ts +1 -0
- package/src/runtime/routes/identity-routes.ts +2 -35
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -2
- package/src/runtime/routes/llm-context-normalization.ts +1212 -0
- package/src/runtime/routes/log-export-routes.ts +3 -0
- package/src/runtime/routes/memory-item-routes.test.ts +34 -0
- package/src/runtime/routes/memory-item-routes.ts +94 -5
- package/src/runtime/routes/migration-routes.ts +4 -1
- package/src/runtime/routes/oauth-apps.ts +291 -0
- package/src/runtime/routes/secret-routes.ts +30 -1
- package/src/runtime/routes/settings-routes.ts +14 -0
- package/src/runtime/routes/surface-action-routes.ts +68 -1
- package/src/runtime/routes/trace-event-routes.ts +4 -1
- package/src/schedule/schedule-store.ts +30 -21
- package/src/security/secure-keys.ts +21 -0
- package/src/signals/bash.ts +1 -1
- package/src/skills/inline-command-expansions.ts +204 -0
- package/src/skills/inline-command-render.ts +127 -0
- package/src/skills/inline-command-runner.ts +242 -0
- package/src/skills/transitive-version-hash.ts +88 -0
- package/src/swarm/backend-claude-code.ts +3 -6
- package/src/tasks/task-store.ts +43 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -2
- package/src/telemetry/usage-telemetry-reporter.ts +3 -1
- package/src/tools/AGENTS.md +6 -10
- package/src/tools/apps/executors.ts +17 -232
- package/src/tools/claude-code/claude-code.ts +2 -3
- package/src/tools/credentials/vault.ts +7 -12
- package/src/tools/host-filesystem/read.ts +13 -10
- package/src/tools/network/__tests__/web-search.test.ts +4 -2
- package/src/tools/permission-checker.ts +8 -1
- package/src/tools/schedule/list.ts +2 -7
- package/src/tools/schema-transforms.ts +5 -0
- package/src/tools/shared/filesystem/format-diff.ts +2 -7
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/load.ts +140 -6
- package/src/tools/tool-manifest.ts +0 -6
- package/src/tools/ui-surface/definitions.ts +2 -2
- package/src/util/device-id.ts +28 -5
- package/src/util/platform.ts +24 -0
- package/src/util/pricing.ts +1 -0
- package/src/util/retry.ts +1 -3
- package/src/workspace/migrations/003-seed-device-id.ts +3 -4
- package/src/workspace/migrations/006-services-config.ts +5 -0
- package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +12 -0
- package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +10 -0
- package/src/workspace/migrations/010-app-dir-rename.ts +223 -0
- package/src/workspace/migrations/{002-backfill-installation-id.ts → 011-backfill-installation-id.ts} +24 -13
- package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +64 -0
- package/src/workspace/migrations/013-repair-conversation-disk-view.ts +11 -0
- package/src/workspace/migrations/rebuild-conversation-disk-view.ts +186 -0
- package/src/workspace/migrations/registry.ts +11 -1
- package/src/workspace/top-level-renderer.ts +12 -0
- package/src/__tests__/asset-materialize-tool.test.ts +0 -523
- package/src/__tests__/asset-search-tool.test.ts +0 -536
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +0 -56
- package/src/__tests__/media-reuse-story.e2e.test.ts +0 -762
- package/src/__tests__/media-visibility-policy.test.ts +0 -190
- package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +0 -14
- package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +0 -13
- package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +0 -21
- package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +0 -14
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +0 -13
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +0 -23
- package/src/daemon/media-visibility-policy.ts +0 -59
- package/src/tools/assets/materialize.ts +0 -248
- package/src/tools/assets/search.ts +0 -400
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getConfig,
|
|
3
|
+
loadRawConfig,
|
|
4
|
+
saveRawConfig,
|
|
5
|
+
} from "../../config/loader.js";
|
|
6
|
+
import {
|
|
7
|
+
deleteMemoryEmbeddingField,
|
|
8
|
+
setMemoryEmbeddingField,
|
|
9
|
+
} from "../../config/raw-config-utils.js";
|
|
10
|
+
import { VALID_MEMORY_EMBEDDING_PROVIDERS } from "../../config/schemas/memory-storage.js";
|
|
11
|
+
import {
|
|
12
|
+
clearEmbeddingBackendCache,
|
|
13
|
+
getMemoryBackendStatus,
|
|
14
|
+
} from "../../memory/embedding-backend.js";
|
|
15
|
+
import type { ModelSetContext } from "./config-model.js";
|
|
16
|
+
import { CONFIG_RELOAD_DEBOUNCE_MS, log } from "./shared.js";
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Embedding provider catalog
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
const EMBEDDING_PROVIDER_CATALOG = [
|
|
23
|
+
{
|
|
24
|
+
id: "auto",
|
|
25
|
+
displayName: "Auto (Best Available)",
|
|
26
|
+
defaultModel: "",
|
|
27
|
+
requiresKey: false,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "local",
|
|
31
|
+
displayName: "Local (In-Process)",
|
|
32
|
+
defaultModel: "Xenova/bge-small-en-v1.5",
|
|
33
|
+
requiresKey: false,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "openai",
|
|
37
|
+
displayName: "OpenAI",
|
|
38
|
+
defaultModel: "text-embedding-3-small",
|
|
39
|
+
requiresKey: true,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "gemini",
|
|
43
|
+
displayName: "Gemini",
|
|
44
|
+
defaultModel: "gemini-embedding-2-preview",
|
|
45
|
+
requiresKey: true,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: "ollama",
|
|
49
|
+
displayName: "Ollama",
|
|
50
|
+
defaultModel: "nomic-embed-text",
|
|
51
|
+
requiresKey: false,
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Provider-specific model field names
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
const PROVIDER_MODEL_FIELD: Record<string, string> = {
|
|
60
|
+
local: "localModel",
|
|
61
|
+
openai: "openaiModel",
|
|
62
|
+
gemini: "geminiModel",
|
|
63
|
+
ollama: "ollamaModel",
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// GET — return current embedding config + resolved status
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
|
|
70
|
+
export async function getEmbeddingConfigInfo(): Promise<{
|
|
71
|
+
provider: string;
|
|
72
|
+
model: string | null;
|
|
73
|
+
activeProvider: string | null;
|
|
74
|
+
activeModel: string | null;
|
|
75
|
+
availableProviders: typeof EMBEDDING_PROVIDER_CATALOG;
|
|
76
|
+
status: { enabled: boolean; degraded: boolean; reason: string | null };
|
|
77
|
+
}> {
|
|
78
|
+
const config = getConfig();
|
|
79
|
+
const embeddingConfig = config.memory.embeddings;
|
|
80
|
+
const backendStatus = await getMemoryBackendStatus(config);
|
|
81
|
+
|
|
82
|
+
// Derive the provider-specific model from config
|
|
83
|
+
const fieldName = PROVIDER_MODEL_FIELD[embeddingConfig.provider];
|
|
84
|
+
const model = fieldName
|
|
85
|
+
? (embeddingConfig as Record<string, unknown>)[fieldName]
|
|
86
|
+
: null;
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
provider: embeddingConfig.provider,
|
|
90
|
+
model: typeof model === "string" ? model : null,
|
|
91
|
+
activeProvider: backendStatus.provider,
|
|
92
|
+
activeModel: backendStatus.model,
|
|
93
|
+
availableProviders: EMBEDDING_PROVIDER_CATALOG,
|
|
94
|
+
status: {
|
|
95
|
+
enabled: backendStatus.enabled,
|
|
96
|
+
degraded: backendStatus.degraded,
|
|
97
|
+
reason: backendStatus.reason,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// PUT — persist embedding provider/model to config
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
export async function setEmbeddingConfig(
|
|
107
|
+
provider: string,
|
|
108
|
+
model: string | undefined,
|
|
109
|
+
ctx: ModelSetContext,
|
|
110
|
+
): Promise<ReturnType<typeof getEmbeddingConfigInfo>> {
|
|
111
|
+
const validProviders = new Set<string>(VALID_MEMORY_EMBEDDING_PROVIDERS);
|
|
112
|
+
if (!validProviders.has(provider)) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
`Invalid embedding provider "${provider}". Valid providers: ${[...validProviders].join(", ")}`,
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const raw = loadRawConfig();
|
|
119
|
+
setMemoryEmbeddingField(raw, "provider", provider);
|
|
120
|
+
|
|
121
|
+
if (model !== undefined) {
|
|
122
|
+
const fieldName = PROVIDER_MODEL_FIELD[provider];
|
|
123
|
+
if (fieldName) {
|
|
124
|
+
if (model === "") {
|
|
125
|
+
// Empty string means "clear override — use schema default"
|
|
126
|
+
deleteMemoryEmbeddingField(raw, fieldName);
|
|
127
|
+
} else {
|
|
128
|
+
setMemoryEmbeddingField(raw, fieldName, model);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Suppress the file watcher callback — we handle the reload ourselves.
|
|
134
|
+
const wasSuppressed = ctx.suppressConfigReload;
|
|
135
|
+
ctx.setSuppressConfigReload(true);
|
|
136
|
+
try {
|
|
137
|
+
saveRawConfig(raw);
|
|
138
|
+
} catch (err) {
|
|
139
|
+
ctx.setSuppressConfigReload(wasSuppressed);
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
ctx.debounceTimers.schedule(
|
|
143
|
+
"__suppress_reset__",
|
|
144
|
+
() => {
|
|
145
|
+
ctx.setSuppressConfigReload(false);
|
|
146
|
+
},
|
|
147
|
+
CONFIG_RELOAD_DEBOUNCE_MS,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
clearEmbeddingBackendCache();
|
|
151
|
+
ctx.updateConfigFingerprint();
|
|
152
|
+
|
|
153
|
+
log.info({ provider, model }, "Embedding config updated");
|
|
154
|
+
|
|
155
|
+
return getEmbeddingConfigInfo();
|
|
156
|
+
}
|
|
@@ -4,12 +4,18 @@ import {
|
|
|
4
4
|
saveRawConfig,
|
|
5
5
|
} from "../../config/loader.js";
|
|
6
6
|
import { setServiceField } from "../../config/raw-config-utils.js";
|
|
7
|
+
import { VALID_INFERENCE_PROVIDERS } from "../../config/schemas/services.js";
|
|
8
|
+
import type { ProviderCatalogEntry } from "../../providers/model-catalog.js";
|
|
9
|
+
import {
|
|
10
|
+
isModelInCatalog,
|
|
11
|
+
PROVIDER_CATALOG,
|
|
12
|
+
} from "../../providers/model-catalog.js";
|
|
13
|
+
import { getProviderDefaultModel } from "../../providers/model-intents.js";
|
|
7
14
|
import {
|
|
8
15
|
getConfiguredProviders,
|
|
9
16
|
isProviderAvailable,
|
|
10
17
|
} from "../../providers/provider-availability.js";
|
|
11
18
|
import { initializeProviders } from "../../providers/registry.js";
|
|
12
|
-
import { MODEL_TO_PROVIDER } from "../conversation-slash.js";
|
|
13
19
|
import type {
|
|
14
20
|
ImageGenModelSetRequest,
|
|
15
21
|
ModelSetRequest,
|
|
@@ -20,6 +26,13 @@ import {
|
|
|
20
26
|
log,
|
|
21
27
|
} from "./shared.js";
|
|
22
28
|
|
|
29
|
+
/** Reverse lookup: model ID → provider, derived from PROVIDER_CATALOG. */
|
|
30
|
+
export const MODEL_TO_PROVIDER: Record<string, string> = Object.fromEntries(
|
|
31
|
+
PROVIDER_CATALOG.flatMap((provider) =>
|
|
32
|
+
provider.models.map(({ id }) => [id, provider.id]),
|
|
33
|
+
),
|
|
34
|
+
);
|
|
35
|
+
|
|
23
36
|
// ---------------------------------------------------------------------------
|
|
24
37
|
// Shared business logic (transport-agnostic)
|
|
25
38
|
// ---------------------------------------------------------------------------
|
|
@@ -28,15 +41,21 @@ export interface ModelInfo {
|
|
|
28
41
|
model: string;
|
|
29
42
|
provider: string;
|
|
30
43
|
configuredProviders?: string[];
|
|
44
|
+
availableModels?: Array<{ id: string; displayName: string }>;
|
|
45
|
+
allProviders?: ProviderCatalogEntry[];
|
|
31
46
|
}
|
|
32
47
|
|
|
33
48
|
/** Return current model configuration. */
|
|
34
49
|
export async function getModelInfo(): Promise<ModelInfo> {
|
|
35
50
|
const config = getConfig();
|
|
51
|
+
const provider = config.services.inference.provider;
|
|
52
|
+
|
|
36
53
|
return {
|
|
37
54
|
model: config.services.inference.model,
|
|
38
|
-
provider
|
|
55
|
+
provider,
|
|
39
56
|
configuredProviders: await getConfiguredProviders(),
|
|
57
|
+
availableModels: PROVIDER_CATALOG.find((p) => p.id === provider)?.models,
|
|
58
|
+
allProviders: PROVIDER_CATALOG,
|
|
40
59
|
};
|
|
41
60
|
}
|
|
42
61
|
|
|
@@ -58,28 +77,52 @@ export interface ModelSetContext {
|
|
|
58
77
|
/**
|
|
59
78
|
* Set the active model. Returns the resulting ModelInfo, or throws on failure.
|
|
60
79
|
* The caller is responsible for sending the response to the client.
|
|
80
|
+
*
|
|
81
|
+
* When `explicitProvider` is supplied, it takes precedence over automatic
|
|
82
|
+
* provider inference from the model ID. If the provider changes and the
|
|
83
|
+
* current model doesn't belong to the new provider's catalog, the model
|
|
84
|
+
* is auto-reset to the provider's default.
|
|
61
85
|
*/
|
|
62
86
|
export async function setModel(
|
|
63
87
|
modelId: string,
|
|
64
88
|
ctx: ModelSetContext,
|
|
89
|
+
explicitProvider?: string,
|
|
65
90
|
): Promise<ModelInfo> {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
//
|
|
69
|
-
{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
91
|
+
const validProviders = new Set<string>(VALID_INFERENCE_PROVIDERS);
|
|
92
|
+
|
|
93
|
+
// Validate explicit provider against allowlist
|
|
94
|
+
if (explicitProvider && !validProviders.has(explicitProvider)) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Invalid provider "${explicitProvider}". Valid providers: ${[...validProviders].join(", ")}`,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Resolve provider: explicit > MODEL_TO_PROVIDER lookup > current
|
|
101
|
+
const current = getConfig();
|
|
102
|
+
const resolvedProvider =
|
|
103
|
+
explicitProvider ??
|
|
104
|
+
MODEL_TO_PROVIDER[modelId] ??
|
|
105
|
+
current.services.inference.provider;
|
|
106
|
+
|
|
107
|
+
// Auto-reset model when provider changes and current modelId doesn't
|
|
108
|
+
// belong to the new provider's catalog.
|
|
109
|
+
if (
|
|
110
|
+
resolvedProvider !== current.services.inference.provider &&
|
|
111
|
+
!isModelInCatalog(resolvedProvider, modelId)
|
|
112
|
+
) {
|
|
113
|
+
modelId = getProviderDefaultModel(resolvedProvider);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// No-op guard: skip expensive reinitialization when nothing changed
|
|
117
|
+
if (
|
|
118
|
+
modelId === current.services.inference.model &&
|
|
119
|
+
resolvedProvider === current.services.inference.provider
|
|
120
|
+
) {
|
|
121
|
+
return await getModelInfo();
|
|
78
122
|
}
|
|
79
123
|
|
|
80
124
|
// Validate provider availability (secure key, env var, or managed proxy) before switching
|
|
81
|
-
|
|
82
|
-
if (provider && !(await isProviderAvailable(provider))) {
|
|
125
|
+
if (!(await isProviderAvailable(resolvedProvider))) {
|
|
83
126
|
// Return current model_info so the client resyncs its optimistic state
|
|
84
127
|
return await getModelInfo();
|
|
85
128
|
}
|
|
@@ -87,10 +130,7 @@ export async function setModel(
|
|
|
87
130
|
// Use raw config to avoid persisting env-var API keys to disk
|
|
88
131
|
const raw = loadRawConfig();
|
|
89
132
|
setServiceField(raw, "inference", "model", modelId);
|
|
90
|
-
|
|
91
|
-
if (provider) {
|
|
92
|
-
setServiceField(raw, "inference", "provider", provider);
|
|
93
|
-
}
|
|
133
|
+
setServiceField(raw, "inference", "provider", resolvedProvider);
|
|
94
134
|
|
|
95
135
|
// Suppress the file watcher callback — setModel already does
|
|
96
136
|
// the full reload sequence; a redundant watcher-triggered reload
|
|
@@ -128,11 +168,7 @@ export async function setModel(
|
|
|
128
168
|
|
|
129
169
|
ctx.updateConfigFingerprint();
|
|
130
170
|
|
|
131
|
-
return
|
|
132
|
-
model: config.services.inference.model,
|
|
133
|
-
provider: config.services.inference.provider,
|
|
134
|
-
configuredProviders: await getConfiguredProviders(),
|
|
135
|
-
};
|
|
171
|
+
return await getModelInfo();
|
|
136
172
|
}
|
|
137
173
|
|
|
138
174
|
/**
|
|
@@ -179,7 +215,7 @@ export async function handleModelSet(
|
|
|
179
215
|
ctx: HandlerContext,
|
|
180
216
|
): Promise<void> {
|
|
181
217
|
try {
|
|
182
|
-
const info = await setModel(msg.model, ctx);
|
|
218
|
+
const info = await setModel(msg.model, ctx, msg.provider);
|
|
183
219
|
ctx.send({ type: "model_info", ...info });
|
|
184
220
|
} catch (err) {
|
|
185
221
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -9,7 +9,6 @@ import { getConfig } from "../../config/loader.js";
|
|
|
9
9
|
import {
|
|
10
10
|
createCanonicalGuardianRequest,
|
|
11
11
|
generateCanonicalRequestCode,
|
|
12
|
-
resolveCanonicalGuardianRequest,
|
|
13
12
|
} from "../../memory/canonical-guardian-store.js";
|
|
14
13
|
import {
|
|
15
14
|
batchSetDisplayOrders,
|
|
@@ -50,27 +49,6 @@ import {
|
|
|
50
49
|
pendingStandaloneSecrets,
|
|
51
50
|
} from "./shared.js";
|
|
52
51
|
|
|
53
|
-
export function syncCanonicalStatusFromConfirmationDecision(
|
|
54
|
-
requestId: string,
|
|
55
|
-
decision: ConfirmationResponse["decision"],
|
|
56
|
-
): void {
|
|
57
|
-
const targetStatus =
|
|
58
|
-
decision === "deny" || decision === "always_deny"
|
|
59
|
-
? ("denied" as const)
|
|
60
|
-
: ("approved" as const);
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
resolveCanonicalGuardianRequest(requestId, "pending", {
|
|
64
|
-
status: targetStatus,
|
|
65
|
-
});
|
|
66
|
-
} catch (err) {
|
|
67
|
-
log.debug(
|
|
68
|
-
{ err, requestId, targetStatus },
|
|
69
|
-
"Failed to resolve canonical request from local confirmation response",
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
52
|
export function makeEventSender(params: {
|
|
75
53
|
ctx: HandlerContext;
|
|
76
54
|
conversation: Conversation;
|
|
@@ -165,7 +143,6 @@ export function handleConfirmationResponse(
|
|
|
165
143
|
undefined,
|
|
166
144
|
{ source: "button" },
|
|
167
145
|
);
|
|
168
|
-
syncCanonicalStatusFromConfirmationDecision(msg.requestId, msg.decision);
|
|
169
146
|
pendingInteractions.resolve(msg.requestId);
|
|
170
147
|
return;
|
|
171
148
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true when the value is a template placeholder that should be treated
|
|
3
|
+
* as empty/unset. Placeholders follow the pattern `_(…)_`, e.g.
|
|
4
|
+
* `_(not yet chosen)_` or `_(not yet established)_`.
|
|
5
|
+
*/
|
|
6
|
+
export function isTemplatePlaceholder(value: string): boolean {
|
|
7
|
+
return value.startsWith("_(") && value.endsWith(")_");
|
|
8
|
+
}
|
|
9
|
+
|
|
1
10
|
export interface IdentityFields {
|
|
2
11
|
name: string;
|
|
3
12
|
role: string;
|
|
@@ -14,7 +23,9 @@ export function parseIdentityFields(content: string): IdentityFields {
|
|
|
14
23
|
const lower = trimmed.toLowerCase();
|
|
15
24
|
const extract = (prefix: string): string | null => {
|
|
16
25
|
if (!lower.startsWith(prefix)) return null;
|
|
17
|
-
|
|
26
|
+
const value = trimmed.split(":**").pop()?.trim() ?? null;
|
|
27
|
+
if (value && isTemplatePlaceholder(value)) return null;
|
|
28
|
+
return value;
|
|
18
29
|
};
|
|
19
30
|
|
|
20
31
|
const name = extract("- **name:**");
|
|
@@ -4,10 +4,10 @@ import * as path from "node:path";
|
|
|
4
4
|
import { v4 as uuid } from "uuid";
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
uploadFileBackedAttachment,
|
|
7
|
+
attachFileBackedAttachmentToMessage,
|
|
9
8
|
} from "../../memory/attachments-store.js";
|
|
10
|
-
import { addMessage } from "../../memory/conversation-crud.js";
|
|
9
|
+
import { addMessage, getConversation } from "../../memory/conversation-crud.js";
|
|
10
|
+
import { syncMessageToDisk } from "../../memory/conversation-disk-view.js";
|
|
11
11
|
import type { RecordingOptions, RecordingStatus } from "../message-protocol.js";
|
|
12
12
|
import { type HandlerContext, log } from "./shared.js";
|
|
13
13
|
|
|
@@ -616,23 +616,6 @@ export async function finalizeAndPublishRecording(params: {
|
|
|
616
616
|
const ext = filename.split(".").pop()?.toLowerCase();
|
|
617
617
|
const mimeType = (ext && RECORDING_MIME_TYPES.get(ext)) || "video/mp4";
|
|
618
618
|
|
|
619
|
-
// Store as file-backed attachment (avoids reading large files into memory)
|
|
620
|
-
const attachment = uploadFileBackedAttachment(
|
|
621
|
-
filename,
|
|
622
|
-
mimeType,
|
|
623
|
-
resolvedPath,
|
|
624
|
-
sizeBytes,
|
|
625
|
-
);
|
|
626
|
-
log.info(
|
|
627
|
-
{
|
|
628
|
-
recordingId,
|
|
629
|
-
attachmentId: attachment.id,
|
|
630
|
-
sizeBytes,
|
|
631
|
-
filePath: resolvedPath,
|
|
632
|
-
},
|
|
633
|
-
"Created attachment for standalone recording",
|
|
634
|
-
);
|
|
635
|
-
|
|
636
619
|
// Always create a new assistant message for the recording attachment.
|
|
637
620
|
// Reusing the last assistant message would attach the recording to an
|
|
638
621
|
// unrelated older message after reload.
|
|
@@ -648,12 +631,34 @@ export async function finalizeAndPublishRecording(params: {
|
|
|
648
631
|
"Created assistant message for recording attachment",
|
|
649
632
|
);
|
|
650
633
|
|
|
651
|
-
|
|
634
|
+
const attachment = attachFileBackedAttachmentToMessage(
|
|
635
|
+
messageId,
|
|
636
|
+
0,
|
|
637
|
+
filename,
|
|
638
|
+
mimeType,
|
|
639
|
+
resolvedPath,
|
|
640
|
+
sizeBytes,
|
|
641
|
+
);
|
|
642
|
+
log.info(
|
|
643
|
+
{
|
|
644
|
+
recordingId,
|
|
645
|
+
attachmentId: attachment.id,
|
|
646
|
+
sizeBytes,
|
|
647
|
+
filePath: resolvedPath,
|
|
648
|
+
},
|
|
649
|
+
"Created attachment for standalone recording",
|
|
650
|
+
);
|
|
652
651
|
log.info(
|
|
653
652
|
{ recordingId, messageId, attachmentId: attachment.id },
|
|
654
653
|
"Linked recording attachment to assistant message",
|
|
655
654
|
);
|
|
656
655
|
|
|
656
|
+
// Sync the recording message (with attachment) to the disk view
|
|
657
|
+
const convForDisk = getConversation(conversationId);
|
|
658
|
+
if (convForDisk) {
|
|
659
|
+
syncMessageToDisk(conversationId, messageId, convForDisk.createdAt);
|
|
660
|
+
}
|
|
661
|
+
|
|
657
662
|
// Skip server-side thumbnail generation for recordings — the client
|
|
658
663
|
// generates thumbnails natively from the local file path using
|
|
659
664
|
// AVAssetImageGenerator, which is faster and doesn't depend on ffmpeg.
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { v4 as uuid } from "uuid";
|
|
11
11
|
|
|
12
12
|
import { escapeAxTreeContent } from "../agent/loop.js";
|
|
13
|
+
import { loadConfig } from "../config/loader.js";
|
|
13
14
|
import type { ContentBlock } from "../providers/types.js";
|
|
14
15
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
15
16
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
@@ -23,7 +24,6 @@ const log = getLogger("host-cu-proxy");
|
|
|
23
24
|
// ---------------------------------------------------------------------------
|
|
24
25
|
|
|
25
26
|
const REQUEST_TIMEOUT_SEC = 60;
|
|
26
|
-
const MAX_STEPS = 50;
|
|
27
27
|
const MAX_HISTORY_ENTRIES = 10;
|
|
28
28
|
const LOOP_DETECTION_WINDOW = 3;
|
|
29
29
|
const CONSECUTIVE_UNCHANGED_WARNING_THRESHOLD = 2;
|
|
@@ -79,7 +79,7 @@ export class HostCuProxy {
|
|
|
79
79
|
constructor(
|
|
80
80
|
sendToClient: (msg: ServerMessage) => void,
|
|
81
81
|
onInternalResolve?: (requestId: string) => void,
|
|
82
|
-
maxSteps =
|
|
82
|
+
maxSteps = loadConfig().maxStepsPerSession,
|
|
83
83
|
) {
|
|
84
84
|
this.sendToClient = sendToClient;
|
|
85
85
|
this.onInternalResolve = onInternalResolve;
|