@vellumai/assistant 0.5.16 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +1 -1
- package/Dockerfile +0 -3
- package/knip.json +2 -1
- package/openapi.yaml +660 -80
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +68 -0
- package/src/__tests__/agent-loop.test.ts +0 -32
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/anthropic-provider.test.ts +57 -3
- package/src/__tests__/app-compiler.test.ts +120 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/call-conversation-messages.test.ts +2 -6
- package/src/__tests__/call-domain.test.ts +2 -6
- package/src/__tests__/call-pointer-messages.test.ts +2 -14
- package/src/__tests__/call-recovery.test.ts +2 -6
- package/src/__tests__/call-routes-http.test.ts +2 -6
- package/src/__tests__/call-store.test.ts +2 -6
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
- package/src/__tests__/canonical-guardian-store.test.ts +2 -6
- package/src/__tests__/channel-delivery-store.test.ts +2 -6
- package/src/__tests__/channel-retry-sweep.test.ts +2 -6
- package/src/__tests__/checker.test.ts +25 -3
- package/src/__tests__/clawhub.test.ts +54 -24
- package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
- package/src/__tests__/cli-memory.test.ts +74 -69
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/config-set-platform-guard.test.ts +302 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
- package/src/__tests__/contacts-tools.test.ts +31 -0
- package/src/__tests__/context-overflow-reducer.test.ts +86 -0
- package/src/__tests__/context-token-estimator.test.ts +175 -10
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +9 -0
- package/src/__tests__/conversation-agent-loop.test.ts +9 -0
- package/src/__tests__/conversation-attachments.test.ts +2 -6
- package/src/__tests__/conversation-attention-store.test.ts +2 -6
- package/src/__tests__/conversation-clear-safety.test.ts +2 -6
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
- package/src/__tests__/conversation-disk-view.test.ts +2 -6
- package/src/__tests__/conversation-error.test.ts +33 -2
- package/src/__tests__/conversation-fork-crud.test.ts +2 -6
- package/src/__tests__/conversation-history-web-search.test.ts +5 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
- package/src/__tests__/conversation-media-retry.test.ts +91 -0
- package/src/__tests__/conversation-starter-routes.test.ts +20 -11
- package/src/__tests__/conversation-store.test.ts +2 -6
- package/src/__tests__/conversation-usage.test.ts +2 -6
- package/src/__tests__/conversation-wipe.test.ts +11 -408
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
- package/src/__tests__/credential-security-e2e.test.ts +2 -0
- package/src/__tests__/followup-tools.test.ts +2 -6
- package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
- package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
- package/src/__tests__/guardian-action-store.test.ts +2 -6
- package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
- package/src/__tests__/guardian-dispatch.test.ts +2 -6
- package/src/__tests__/guardian-grant-minting.test.ts +2 -14
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
- package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
- package/src/__tests__/guardian-routing-state.test.ts +2 -6
- package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
- package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
- package/src/__tests__/injection-block.test.ts +154 -0
- package/src/__tests__/install-meta.test.ts +506 -0
- package/src/__tests__/install-skill-routing.test.ts +292 -0
- package/src/__tests__/invite-redemption-service.test.ts +2 -6
- package/src/__tests__/invite-routes-http.test.ts +2 -6
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -14
- package/src/__tests__/list-messages-attachments.test.ts +2 -6
- package/src/__tests__/llm-context-route-provider.test.ts +2 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
- package/src/__tests__/llm-usage-store.test.ts +2 -6
- package/src/__tests__/log-export-workspace.test.ts +2 -6
- package/src/__tests__/managed-store.test.ts +38 -11
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
- package/src/__tests__/memory-recall-log-store.test.ts +2 -6
- package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
- package/src/__tests__/non-member-access-request.test.ts +2 -6
- package/src/__tests__/notification-guardian-path.test.ts +2 -6
- package/src/__tests__/oauth-cli.test.ts +364 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
- package/src/__tests__/outlook-attachments.test.ts +301 -0
- package/src/__tests__/outlook-automation-tools.test.ts +425 -0
- package/src/__tests__/outlook-categories.test.ts +212 -0
- package/src/__tests__/outlook-client-automation.test.ts +246 -0
- package/src/__tests__/outlook-compose-tools.test.ts +325 -0
- package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
- package/src/__tests__/outlook-email-watcher.test.ts +322 -0
- package/src/__tests__/outlook-follow-up.test.ts +196 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
- package/src/__tests__/outlook-trash.test.ts +77 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
- package/src/__tests__/platform-callback-registration.test.ts +4 -4
- package/src/__tests__/playbook-execution.test.ts +76 -80
- package/src/__tests__/playbook-tools.test.ts +5 -7
- package/src/__tests__/provider-error-scenarios.test.ts +21 -0
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
- package/src/__tests__/registry.test.ts +2 -2
- package/src/__tests__/require-fresh-approval.test.ts +64 -2
- package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
- package/src/__tests__/runtime-events-sse.test.ts +2 -6
- package/src/__tests__/schedule-store.test.ts +2 -6
- package/src/__tests__/schedule-tools.test.ts +2 -6
- package/src/__tests__/scheduler-recurrence.test.ts +1 -5
- package/src/__tests__/scoped-approval-grants.test.ts +2 -6
- package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
- package/src/__tests__/search-skills-unified.test.ts +421 -0
- package/src/__tests__/secret-onetime-send.test.ts +2 -0
- package/src/__tests__/send-endpoint-busy.test.ts +2 -6
- package/src/__tests__/sequence-store.test.ts +2 -6
- package/src/__tests__/server-history-render.test.ts +2 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +11 -11
- package/src/__tests__/skill-memory.test.ts +140 -98
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/skills.test.ts +1 -1
- package/src/__tests__/slack-inbound-verification.test.ts +2 -6
- package/src/__tests__/task-compiler.test.ts +2 -6
- package/src/__tests__/task-management-tools.test.ts +2 -6
- package/src/__tests__/task-memory-cleanup.test.ts +173 -229
- package/src/__tests__/task-runner.test.ts +2 -6
- package/src/__tests__/task-scheduler.test.ts +2 -6
- package/src/__tests__/test-preload.ts +3 -0
- package/src/__tests__/tool-approval-handler.test.ts +2 -6
- package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
- package/src/__tests__/trust-store.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
- package/src/__tests__/trusted-contact-verification.test.ts +2 -6
- package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
- package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
- package/src/__tests__/usage-routes.test.ts +2 -6
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +2 -6
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
- package/src/__tests__/voice-session-bridge.test.ts +2 -6
- package/src/__tests__/volume-security-guard.test.ts +2 -0
- package/src/__tests__/workspace-lifecycle.test.ts +29 -1
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
- package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
- package/src/__tests__/workspace-policy.test.ts +1 -1
- package/src/agent/attachments.ts +7 -2
- package/src/agent/image-optimize.ts +165 -0
- package/src/agent/loop.ts +1 -15
- package/src/bundler/app-compiler.ts +179 -2
- package/src/bundler/package-resolver.ts +3 -5
- package/src/cli/__tests__/notifications.test.ts +1 -2
- package/src/cli/cli-memory.ts +67 -64
- package/src/cli/commands/avatar.ts +3 -3
- package/src/cli/commands/config.ts +26 -13
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/memory.ts +41 -55
- package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
- package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
- package/src/cli/commands/oauth/connect.ts +11 -6
- package/src/cli/commands/oauth/mode.ts +7 -0
- package/src/cli/commands/oauth/shared.ts +39 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
- package/src/cli/commands/platform/index.ts +16 -16
- package/src/cli/commands/skills.ts +88 -16
- package/src/cli/commands/trust.ts +2 -2
- package/src/cli/lib/daemon-credential-client.ts +2 -3
- package/src/config/bundled-skills/acp/TOOLS.json +1 -1
- package/src/config/bundled-skills/contacts/SKILL.md +0 -1
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
- package/src/config/bundled-skills/gmail/SKILL.md +2 -10
- package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
- package/src/config/bundled-skills/messaging/SKILL.md +10 -18
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
- package/src/config/bundled-skills/outlook/SKILL.md +189 -0
- package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
- package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
- package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
- package/src/config/bundled-skills/slack/SKILL.md +1 -7
- package/src/config/bundled-tool-registry.ts +56 -4
- package/src/config/env-registry.ts +15 -8
- package/src/config/feature-flag-registry.json +21 -124
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/config/skills.ts +18 -7
- package/src/context/token-estimator.ts +25 -18
- package/src/context/window-manager.ts +6 -2
- package/src/credential-execution/process-manager.ts +3 -1
- package/src/daemon/context-overflow-reducer.ts +46 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
- package/src/daemon/conversation-agent-loop.ts +96 -61
- package/src/daemon/conversation-error.ts +31 -8
- package/src/daemon/conversation-lifecycle.ts +33 -0
- package/src/daemon/conversation-media-retry.ts +85 -7
- package/src/daemon/conversation-notifiers.ts +4 -1
- package/src/daemon/conversation-runtime-assembly.ts +5 -0
- package/src/daemon/conversation.ts +41 -2
- package/src/daemon/daemon-control.ts +8 -2
- package/src/daemon/handlers/shared.ts +22 -12
- package/src/daemon/handlers/skills.ts +416 -202
- package/src/daemon/lifecycle.ts +40 -1
- package/src/daemon/main.ts +5 -1
- package/src/daemon/message-types/conversations.ts +4 -1
- package/src/daemon/message-types/messages.ts +3 -1
- package/src/daemon/message-types/skills.ts +97 -36
- package/src/daemon/providers-setup.ts +5 -0
- package/src/daemon/server.ts +11 -2
- package/src/daemon/tool-side-effects.ts +27 -5
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/hooks/cli.ts +2 -2
- package/src/hooks/runner.ts +15 -38
- package/src/inbound/platform-callback-registration.ts +14 -14
- package/src/memory/admin.ts +11 -45
- package/src/memory/conversation-bootstrap.ts +2 -0
- package/src/memory/conversation-crud.ts +242 -348
- package/src/memory/conversation-group-migration.ts +157 -0
- package/src/memory/conversation-queries.ts +4 -2
- package/src/memory/db-init.ts +30 -3
- package/src/memory/embed.ts +73 -0
- package/src/memory/embedding-backend.ts +8 -14
- package/src/memory/embedding-runtime-manager.ts +12 -114
- package/src/memory/fingerprint.ts +2 -2
- package/src/memory/graph/bootstrap.ts +512 -0
- package/src/memory/graph/capability-seed.ts +297 -0
- package/src/memory/graph/consolidation.ts +691 -0
- package/src/memory/graph/conversation-graph-memory.ts +630 -0
- package/src/memory/graph/decay.test.ts +208 -0
- package/src/memory/graph/decay.ts +195 -0
- package/src/memory/graph/extraction-job.ts +69 -0
- package/src/memory/graph/extraction.test.ts +936 -0
- package/src/memory/graph/extraction.ts +1254 -0
- package/src/memory/graph/graph-search.ts +266 -0
- package/src/memory/graph/image-ref-utils.ts +29 -0
- package/src/memory/graph/injection.test.ts +513 -0
- package/src/memory/graph/injection.ts +439 -0
- package/src/memory/graph/inspect.ts +534 -0
- package/src/memory/graph/narrative.ts +267 -0
- package/src/memory/graph/pattern-scan.ts +269 -0
- package/src/memory/graph/retriever.ts +1008 -0
- package/src/memory/graph/scoring.test.ts +548 -0
- package/src/memory/graph/scoring.ts +232 -0
- package/src/memory/graph/serendipity.ts +65 -0
- package/src/memory/graph/store.test.ts +1050 -0
- package/src/memory/graph/store.ts +699 -0
- package/src/memory/graph/tool-handlers.ts +426 -0
- package/src/memory/graph/tools.ts +141 -0
- package/src/memory/graph/triggers.test.ts +487 -0
- package/src/memory/graph/triggers.ts +223 -0
- package/src/memory/graph/types.ts +271 -0
- package/src/memory/group-crud.ts +191 -0
- package/src/memory/indexer.ts +37 -19
- package/src/memory/job-handlers/cleanup.ts +0 -53
- package/src/memory/job-handlers/conversation-starters.ts +91 -53
- package/src/memory/job-handlers/embedding.ts +5 -31
- package/src/memory/job-handlers/index-maintenance.ts +23 -11
- package/src/memory/job-handlers/summarization.ts +32 -17
- package/src/memory/job-utils.ts +1 -1
- package/src/memory/jobs-store.ts +50 -70
- package/src/memory/jobs-worker.ts +147 -112
- package/src/memory/message-content.ts +1 -0
- package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
- package/src/memory/migrations/203-drop-memory-items-tables.ts +23 -0
- package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
- package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/qdrant-client.ts +44 -17
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/memory-graph.ts +139 -0
- package/src/memory/search/semantic.ts +47 -91
- package/src/memory/task-memory-cleanup.ts +28 -50
- package/src/messaging/providers/outlook/adapter.ts +8 -1
- package/src/messaging/providers/outlook/client.ts +299 -0
- package/src/messaging/providers/outlook/types.ts +118 -0
- package/src/notifications/adapters/macos.ts +1 -0
- package/src/notifications/copy-composer.ts +9 -0
- package/src/notifications/signal.ts +16 -0
- package/src/oauth/seed-providers.ts +2 -1
- package/src/permissions/checker.ts +24 -3
- package/src/permissions/defaults.ts +4 -4
- package/src/permissions/workspace-policy.ts +1 -1
- package/src/playbooks/playbook-compiler.ts +19 -18
- package/src/playbooks/types.ts +4 -3
- package/src/prompts/system-prompt.ts +3 -29
- package/src/providers/anthropic/client.ts +47 -19
- package/src/providers/gemini/client.ts +1 -1
- package/src/providers/openai/client.ts +1 -1
- package/src/providers/registry.ts +1 -1
- package/src/providers/retry.ts +19 -3
- package/src/runtime/actor-trust-resolver.ts +5 -1
- package/src/runtime/auth/route-policy.ts +7 -0
- package/src/runtime/guardian-reply-router.ts +5 -1
- package/src/runtime/http-server.ts +23 -3
- package/src/runtime/middleware/auth.ts +20 -0
- package/src/runtime/routes/attachment-routes.test.ts +106 -0
- package/src/runtime/routes/attachment-routes.ts +106 -16
- package/src/runtime/routes/brain-graph-routes.ts +21 -22
- package/src/runtime/routes/btw-routes.ts +8 -0
- package/src/runtime/routes/conversation-management-routes.ts +2 -0
- package/src/runtime/routes/conversation-starter-routes.ts +2 -2
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/global-search-routes.ts +21 -19
- package/src/runtime/routes/group-routes.ts +207 -0
- package/src/runtime/routes/guardian-action-routes.ts +21 -10
- package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
- package/src/runtime/routes/inbound-message-handler.ts +19 -0
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
- package/src/runtime/routes/memory-item-routes.test.ts +2 -14
- package/src/runtime/routes/memory-item-routes.ts +341 -388
- package/src/runtime/routes/schedule-routes.ts +2 -0
- package/src/runtime/routes/skills-routes.ts +103 -37
- package/src/runtime/routes/work-items-routes.test.ts +2 -6
- package/src/schedule/scheduler.ts +8 -1
- package/src/security/oauth2.ts +1 -1
- package/src/security/secure-keys.ts +4 -8
- package/src/shared/provider-env-vars.ts +19 -0
- package/src/skills/catalog-cache.ts +5 -0
- package/src/skills/catalog-install.ts +15 -14
- package/src/skills/clawhub.ts +134 -154
- package/src/skills/install-meta.ts +208 -0
- package/src/skills/managed-store.ts +27 -16
- package/src/skills/skill-memory.ts +152 -77
- package/src/skills/skillssh-registry.ts +19 -17
- package/src/tasks/task-runner.ts +3 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
- package/src/tools/browser/runtime-check.ts +3 -1
- package/src/tools/memory/register.ts +63 -46
- package/src/tools/permission-checker.ts +7 -1
- package/src/tools/shared/filesystem/image-read.ts +22 -85
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/tool-manifest.ts +3 -3
- package/src/util/browser.ts +25 -10
- package/src/util/bun-runtime.ts +172 -0
- package/src/watcher/providers/outlook-calendar.ts +343 -0
- package/src/watcher/providers/outlook.ts +198 -0
- package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
- package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
- package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/context-memory-e2e.test.ts +0 -415
- package/src/__tests__/journal-context.test.ts +0 -268
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
- package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
- package/src/__tests__/memory-query-builder.test.ts +0 -59
- package/src/__tests__/memory-recall-quality.test.ts +0 -1046
- package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
- package/src/__tests__/memory-regressions.test.ts +0 -3696
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
- package/src/daemon/conversation-memory.ts +0 -207
- package/src/memory/conversation-starters-cadence.ts +0 -74
- package/src/memory/items-extractor.ts +0 -860
- package/src/memory/job-handlers/batch-extraction.ts +0 -753
- package/src/memory/job-handlers/extraction.ts +0 -40
- package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
- package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
- package/src/memory/journal-memory.ts +0 -224
- package/src/memory/query-builder.ts +0 -47
- package/src/memory/query-expansion.ts +0 -83
- package/src/memory/retriever.test.ts +0 -1592
- package/src/memory/retriever.ts +0 -1331
- package/src/memory/search/formatting.test.ts +0 -140
- package/src/memory/search/formatting.ts +0 -262
- package/src/memory/search/mmr.ts +0 -139
- package/src/memory/search/ranking.ts +0 -15
- package/src/memory/search/staleness.ts +0 -40
- package/src/memory/search/tier-classifier.ts +0 -18
- package/src/memory/search/types.ts +0 -121
- package/src/prompts/journal-context.ts +0 -154
- package/src/tools/memory/definitions.ts +0 -69
- package/src/tools/memory/handlers.test.ts +0 -562
- package/src/tools/memory/handlers.ts +0 -434
|
@@ -6,13 +6,25 @@
|
|
|
6
6
|
* text stubs to shrink the payload before retrying.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { estimateContentBlockTokens } from "../context/token-estimator.js";
|
|
9
10
|
import { getSummaryFromContextMessage } from "../context/window-manager.js";
|
|
10
11
|
import type { ContentBlock, Message } from "../providers/types.js";
|
|
11
12
|
|
|
13
|
+
export interface StripMediaOptions {
|
|
14
|
+
/** Token budget available for media in the latest user message. Keeps as
|
|
15
|
+
* many images as fit within this budget instead of the hardcoded limit. */
|
|
16
|
+
mediaTokenBudget?: number;
|
|
17
|
+
/** Provider name for per-image token estimation. */
|
|
18
|
+
providerName?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
12
21
|
const RETRY_KEEP_LATEST_MEDIA_BLOCKS = 3;
|
|
13
22
|
const MAX_MEDIA_STUB_TEXT = 2_000;
|
|
14
23
|
|
|
15
|
-
export function stripMediaPayloadsForRetry(
|
|
24
|
+
export function stripMediaPayloadsForRetry(
|
|
25
|
+
messages: Message[],
|
|
26
|
+
options?: StripMediaOptions,
|
|
27
|
+
): {
|
|
16
28
|
messages: Message[];
|
|
17
29
|
modified: boolean;
|
|
18
30
|
replacedBlocks: number;
|
|
@@ -31,6 +43,8 @@ export function stripMediaPayloadsForRetry(messages: Message[]): {
|
|
|
31
43
|
let modified = false;
|
|
32
44
|
let replacedBlocks = 0;
|
|
33
45
|
let keptLatestMediaBlocks = 0;
|
|
46
|
+
let cumulativeMediaTokens = 0;
|
|
47
|
+
const useBudget = options?.mediaTokenBudget != null;
|
|
34
48
|
|
|
35
49
|
const nextMessages = messages.map((msg, msgIndex) => {
|
|
36
50
|
const nextContent: ContentBlock[] = [];
|
|
@@ -39,9 +53,20 @@ export function stripMediaPayloadsForRetry(messages: Message[]): {
|
|
|
39
53
|
// few (in the most recent user message) and strip older ones so the
|
|
40
54
|
// retry can actually reduce context size when images are the cause.
|
|
41
55
|
if (block.type === "image") {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
let keep = false;
|
|
57
|
+
if (latestUserIndex === msgIndex) {
|
|
58
|
+
if (useBudget) {
|
|
59
|
+
const cost = estimateContentBlockTokens(block, {
|
|
60
|
+
providerName: options!.providerName,
|
|
61
|
+
});
|
|
62
|
+
if (cumulativeMediaTokens + cost <= options!.mediaTokenBudget!) {
|
|
63
|
+
cumulativeMediaTokens += cost;
|
|
64
|
+
keep = true;
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
keep = keptLatestMediaBlocks < RETRY_KEEP_LATEST_MEDIA_BLOCKS;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
45
70
|
if (keep) {
|
|
46
71
|
keptLatestMediaBlocks += 1;
|
|
47
72
|
nextContent.push(block);
|
|
@@ -54,9 +79,20 @@ export function stripMediaPayloadsForRetry(messages: Message[]): {
|
|
|
54
79
|
}
|
|
55
80
|
|
|
56
81
|
if (block.type === "file") {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
82
|
+
let keep = false;
|
|
83
|
+
if (latestUserIndex === msgIndex) {
|
|
84
|
+
if (useBudget) {
|
|
85
|
+
const cost = estimateContentBlockTokens(block, {
|
|
86
|
+
providerName: options!.providerName,
|
|
87
|
+
});
|
|
88
|
+
if (cumulativeMediaTokens + cost <= options!.mediaTokenBudget!) {
|
|
89
|
+
cumulativeMediaTokens += cost;
|
|
90
|
+
keep = true;
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
keep = keptLatestMediaBlocks < RETRY_KEEP_LATEST_MEDIA_BLOCKS;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
60
96
|
if (keep) {
|
|
61
97
|
keptLatestMediaBlocks += 1;
|
|
62
98
|
nextContent.push(block);
|
|
@@ -112,6 +148,48 @@ export function stripMediaPayloadsForRetry(messages: Message[]): {
|
|
|
112
148
|
};
|
|
113
149
|
}
|
|
114
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Estimate the total token cost of stubs that will replace unconditionally
|
|
153
|
+
* stubbed media blocks (non-latest-user-message images/files and all
|
|
154
|
+
* tool_result-nested media). This lets callers account for stub overhead
|
|
155
|
+
* when computing the available media token budget.
|
|
156
|
+
*/
|
|
157
|
+
export function estimateUnconditionalStubTokens(
|
|
158
|
+
messages: Message[],
|
|
159
|
+
options?: { providerName?: string },
|
|
160
|
+
): number {
|
|
161
|
+
let latestUserIndex: number | null = null;
|
|
162
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
163
|
+
const msg = messages[i];
|
|
164
|
+
if (msg.role !== "user") continue;
|
|
165
|
+
if (isToolResultOnlyMessage(msg)) continue;
|
|
166
|
+
if (getSummaryFromContextMessage(msg) != null) continue;
|
|
167
|
+
latestUserIndex = i;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let stubTokens = 0;
|
|
172
|
+
for (let msgIndex = 0; msgIndex < messages.length; msgIndex++) {
|
|
173
|
+
const msg = messages[msgIndex];
|
|
174
|
+
for (const block of msg.content) {
|
|
175
|
+
if (block.type === "image" && msgIndex !== latestUserIndex) {
|
|
176
|
+
stubTokens += estimateContentBlockTokens(imageBlockToStub(block), options);
|
|
177
|
+
} else if (block.type === "file" && msgIndex !== latestUserIndex) {
|
|
178
|
+
stubTokens += estimateContentBlockTokens(fileBlockToStub(block), options);
|
|
179
|
+
} else if (block.type === "tool_result" && block.contentBlocks) { // guard:allow-tool-result-only — web_search_tool_result has no contentBlocks
|
|
180
|
+
for (const cb of block.contentBlocks) {
|
|
181
|
+
if (cb.type === "image") {
|
|
182
|
+
stubTokens += estimateContentBlockTokens(imageBlockToStub(cb), options);
|
|
183
|
+
} else if (cb.type === "file") {
|
|
184
|
+
stubTokens += estimateContentBlockTokens(fileBlockToStub(cb), options);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return stubTokens;
|
|
191
|
+
}
|
|
192
|
+
|
|
115
193
|
function imageBlockToStub(
|
|
116
194
|
block: Extract<ContentBlock, { type: "image" }>,
|
|
117
195
|
): Extract<ContentBlock, { type: "text" }> {
|
|
@@ -99,6 +99,7 @@ export function registerConversationNotifiers(
|
|
|
99
99
|
ctx.sendToClient({
|
|
100
100
|
type: "message_complete",
|
|
101
101
|
conversationId: conversationId,
|
|
102
|
+
messageId: msg.id,
|
|
102
103
|
});
|
|
103
104
|
}
|
|
104
105
|
},
|
|
@@ -133,6 +134,7 @@ export function registerConversationNotifiers(
|
|
|
133
134
|
ctx.sendToClient({
|
|
134
135
|
type: "message_complete",
|
|
135
136
|
conversationId: conversationId,
|
|
137
|
+
messageId: msg.id,
|
|
136
138
|
});
|
|
137
139
|
}
|
|
138
140
|
},
|
|
@@ -145,7 +147,7 @@ export function registerConversationNotifiers(
|
|
|
145
147
|
const callee = callSession?.toNumber ?? "the caller";
|
|
146
148
|
const questionText = `**Live call question** (to ${callee}):\n\n${question}\n\n_Use the call answer API to respond._`;
|
|
147
149
|
|
|
148
|
-
await addMessage(
|
|
150
|
+
const msg = await addMessage(
|
|
149
151
|
conversationId,
|
|
150
152
|
"assistant",
|
|
151
153
|
JSON.stringify([{ type: "text", text: questionText }]),
|
|
@@ -168,6 +170,7 @@ export function registerConversationNotifiers(
|
|
|
168
170
|
ctx.sendToClient({
|
|
169
171
|
type: "message_complete",
|
|
170
172
|
conversationId: conversationId,
|
|
173
|
+
messageId: msg.id,
|
|
171
174
|
});
|
|
172
175
|
},
|
|
173
176
|
);
|
|
@@ -1049,6 +1049,11 @@ const RUNTIME_INJECTION_PREFIXES = [
|
|
|
1049
1049
|
"<turn_context>",
|
|
1050
1050
|
"<memory_context __injected>",
|
|
1051
1051
|
"<memory_context>", // backward-compat: strip legacy blocks from pre-__injected history
|
|
1052
|
+
// NOTE: <memory __injected> is intentionally NOT stripped — memory
|
|
1053
|
+
// injections persist in history so the assistant can reference them.
|
|
1054
|
+
// Context compaction handles these blocks during history reduction, and
|
|
1055
|
+
// the InContextTracker deduplicates nodes across turns, so accumulation
|
|
1056
|
+
// does not cause unbounded context growth.
|
|
1052
1057
|
"<voice_call_control>",
|
|
1053
1058
|
"<workspace_top_level>",
|
|
1054
1059
|
TEMPORAL_INJECTED_PREFIX,
|
|
@@ -44,6 +44,7 @@ import { registerToolTraceListener } from "../events/tool-trace-listener.js";
|
|
|
44
44
|
import { getHookManager } from "../hooks/manager.js";
|
|
45
45
|
import { resolveCanonicalGuardianRequest } from "../memory/canonical-guardian-store.js";
|
|
46
46
|
import { updateConversationContextWindow } from "../memory/conversation-crud.js";
|
|
47
|
+
import { ConversationGraphMemory } from "../memory/graph/conversation-graph-memory.js";
|
|
47
48
|
import { PermissionPrompter } from "../permissions/prompter.js";
|
|
48
49
|
import { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
49
50
|
import { patternMatchesCandidate } from "../permissions/trust-store.js";
|
|
@@ -57,6 +58,7 @@ import type { AuthContext } from "../runtime/auth/types.js";
|
|
|
57
58
|
import * as approvalOverrides from "../runtime/conversation-approval-overrides.js";
|
|
58
59
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
59
60
|
import { ToolExecutor } from "../tools/executor.js";
|
|
61
|
+
import { getLogger } from "../util/logger.js";
|
|
60
62
|
import type { AssistantAttachmentDraft } from "./assistant-attachments.js";
|
|
61
63
|
import { runAgentLoopImpl } from "./conversation-agent-loop.js";
|
|
62
64
|
import type { HistoryConversationContext } from "./conversation-history.js";
|
|
@@ -118,6 +120,8 @@ import type {
|
|
|
118
120
|
} from "./message-types/messages.js";
|
|
119
121
|
import { TraceEmitter } from "./trace-emitter.js";
|
|
120
122
|
|
|
123
|
+
const log = getLogger("conversation");
|
|
124
|
+
|
|
121
125
|
export interface ConversationMemoryPolicy {
|
|
122
126
|
scopeId: string;
|
|
123
127
|
includeDefaultFallback: boolean;
|
|
@@ -243,6 +247,7 @@ export class Conversation {
|
|
|
243
247
|
public readonly traceEmitter: TraceEmitter;
|
|
244
248
|
public readonly hasSystemPromptOverride: boolean;
|
|
245
249
|
public memoryPolicy: ConversationMemoryPolicy;
|
|
250
|
+
/** @internal */ readonly graphMemory: ConversationGraphMemory;
|
|
246
251
|
/** @internal */ streamThinking: boolean;
|
|
247
252
|
/** @internal */ turnCount = 0;
|
|
248
253
|
public lastAssistantAttachments: AssistantAttachmentDraft[] = [];
|
|
@@ -251,6 +256,8 @@ export class Conversation {
|
|
|
251
256
|
/** @internal */ currentTurnInterfaceContext: TurnInterfaceContext | null =
|
|
252
257
|
null;
|
|
253
258
|
/** @internal */ activityVersion = 0;
|
|
259
|
+
/** Last emitted activity state message, retained for replay on SSE reconnection. */
|
|
260
|
+
/** @internal */ lastActivityStateMsg: ServerMessage | null = null;
|
|
254
261
|
/** Set by the agent loop to track confirmation outcomes for persistence. */
|
|
255
262
|
onConfirmationOutcome?: (
|
|
256
263
|
requestId: string,
|
|
@@ -280,6 +287,10 @@ export class Conversation {
|
|
|
280
287
|
this.memoryPolicy = memoryPolicy
|
|
281
288
|
? { ...memoryPolicy }
|
|
282
289
|
: { ...DEFAULT_MEMORY_POLICY };
|
|
290
|
+
this.graphMemory = new ConversationGraphMemory(
|
|
291
|
+
this.memoryPolicy.scopeId,
|
|
292
|
+
conversationId,
|
|
293
|
+
);
|
|
283
294
|
this.traceEmitter = new TraceEmitter(conversationId, sendToClient);
|
|
284
295
|
this.prompter = new PermissionPrompter(sendToClient);
|
|
285
296
|
this.prompter.setOnStateChanged((requestId, state, source, toolUseId) => {
|
|
@@ -486,6 +497,19 @@ export class Conversation {
|
|
|
486
497
|
this.hostCuProxy?.updateSender(sendToClient, !hasNoClient);
|
|
487
498
|
this.hostFileProxy?.updateSender(sendToClient, !hasNoClient);
|
|
488
499
|
}
|
|
500
|
+
|
|
501
|
+
// Replay last activity state so a reconnecting client sees the current phase
|
|
502
|
+
// instead of being stuck on the last state it received before disconnection.
|
|
503
|
+
if (!hasNoClient && this.lastActivityStateMsg) {
|
|
504
|
+
try {
|
|
505
|
+
sendToClient(this.lastActivityStateMsg);
|
|
506
|
+
} catch (err) {
|
|
507
|
+
log.warn(
|
|
508
|
+
{ err, conversationId: this.conversationId },
|
|
509
|
+
"Failed to replay activity state on client reconnection",
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
489
513
|
}
|
|
490
514
|
|
|
491
515
|
/** Returns the current sendToClient reference for identity comparison. */
|
|
@@ -862,7 +886,14 @@ export class Conversation {
|
|
|
862
886
|
type: "confirmation_state_changed",
|
|
863
887
|
...params,
|
|
864
888
|
} as ServerMessage;
|
|
865
|
-
|
|
889
|
+
try {
|
|
890
|
+
this.sendToClient(msg);
|
|
891
|
+
} catch (err) {
|
|
892
|
+
log.warn(
|
|
893
|
+
{ err, conversationId: this.conversationId },
|
|
894
|
+
"sendToClient threw in emitConfirmationStateChanged",
|
|
895
|
+
);
|
|
896
|
+
}
|
|
866
897
|
}
|
|
867
898
|
|
|
868
899
|
emitActivityState(
|
|
@@ -883,7 +914,15 @@ export class Conversation {
|
|
|
883
914
|
reason,
|
|
884
915
|
...(statusText ? { statusText } : {}),
|
|
885
916
|
} as ServerMessage;
|
|
886
|
-
this.
|
|
917
|
+
this.lastActivityStateMsg = msg;
|
|
918
|
+
try {
|
|
919
|
+
this.sendToClient(msg);
|
|
920
|
+
} catch (err) {
|
|
921
|
+
log.warn(
|
|
922
|
+
{ err, conversationId: this.conversationId },
|
|
923
|
+
"sendToClient threw in emitActivityState",
|
|
924
|
+
);
|
|
925
|
+
}
|
|
887
926
|
}
|
|
888
927
|
|
|
889
928
|
async forceCompact(): Promise<ContextWindowResult> {
|
|
@@ -12,12 +12,14 @@ import { resolve } from "node:path";
|
|
|
12
12
|
import { getRuntimeHttpHost, getRuntimeHttpPort } from "../config/env.js";
|
|
13
13
|
import { getIsContainerized } from "../config/env-registry.js";
|
|
14
14
|
import { loadOrCreateSigningKey } from "../runtime/auth/token-service.js";
|
|
15
|
+
import { ensureBun } from "../util/bun-runtime.js";
|
|
15
16
|
import { DaemonError } from "../util/errors.js";
|
|
16
17
|
import { getLogger } from "../util/logger.js";
|
|
17
18
|
import {
|
|
18
19
|
ensureDataDir,
|
|
19
20
|
getDaemonStartupLockPath,
|
|
20
21
|
getDaemonStderrLogPath,
|
|
22
|
+
getDataDir,
|
|
21
23
|
getPidPath,
|
|
22
24
|
getWorkspaceConfigPath,
|
|
23
25
|
} from "../util/platform.js";
|
|
@@ -371,6 +373,10 @@ async function startDaemonLocked(): Promise<{
|
|
|
371
373
|
}
|
|
372
374
|
}
|
|
373
375
|
|
|
376
|
+
// Resolve bun before opening stderrFd to avoid leaking the file
|
|
377
|
+
// descriptor if ensureBun() throws (same pattern as loadOrCreateSigningKey).
|
|
378
|
+
const bunPath = await ensureBun();
|
|
379
|
+
|
|
374
380
|
// Redirect the child's stderr to a file instead of piping it back to the
|
|
375
381
|
// parent. A pipe's read end is destroyed when the parent exits, leaving
|
|
376
382
|
// fd 2 broken in the child. Bun (unlike Node.js) does not ignore SIGPIPE,
|
|
@@ -378,7 +384,7 @@ async function startDaemonLocked(): Promise<{
|
|
|
378
384
|
const stderrPath = getDaemonStderrLogPath();
|
|
379
385
|
const stderrFd = openSync(stderrPath, "w");
|
|
380
386
|
|
|
381
|
-
const child = spawn(
|
|
387
|
+
const child = spawn(bunPath, ["run", mainPath], {
|
|
382
388
|
detached: true,
|
|
383
389
|
stdio: ["ignore", "ignore", stderrFd],
|
|
384
390
|
env: spawnEnv,
|
|
@@ -413,7 +419,7 @@ async function startDaemonLocked(): Promise<{
|
|
|
413
419
|
const stderr = readFileSync(stderrPath, "utf-8").trim();
|
|
414
420
|
const detail = stderr
|
|
415
421
|
? `\n${stderr}`
|
|
416
|
-
: `\nCheck logs at
|
|
422
|
+
: `\nCheck logs at ${getDataDir()}/logs/ for details.`;
|
|
417
423
|
throw new DaemonError(
|
|
418
424
|
`Daemon exited immediately (code ${
|
|
419
425
|
childExitCode ?? "unknown"
|
|
@@ -60,8 +60,10 @@ export interface HistoryToolCall {
|
|
|
60
60
|
input: Record<string, unknown>;
|
|
61
61
|
result?: string;
|
|
62
62
|
isError?: boolean;
|
|
63
|
-
/** Base64-encoded image data from tool contentBlocks (e.g. browser_screenshot). */
|
|
63
|
+
/** Base64-encoded image data from tool contentBlocks (e.g. browser_screenshot). @deprecated Use imageDataList. */
|
|
64
64
|
imageData?: string;
|
|
65
|
+
/** Base64-encoded image data from tool contentBlocks (e.g. browser_screenshot, image generation). */
|
|
66
|
+
imageDataList?: string[];
|
|
65
67
|
/** Unix ms when the tool started executing. */
|
|
66
68
|
startedAt?: number;
|
|
67
69
|
/** Unix ms when the tool completed. */
|
|
@@ -341,16 +343,19 @@ export function renderHistoryContent(content: unknown): RenderedHistoryContent {
|
|
|
341
343
|
const resultContent =
|
|
342
344
|
typeof block.content === "string" ? block.content : "";
|
|
343
345
|
const isError = block.is_error === true;
|
|
344
|
-
// Extract base64 image data from persisted contentBlocks (e.g. browser_screenshot)
|
|
345
|
-
|
|
346
|
+
// Extract base64 image data from persisted contentBlocks (e.g. browser_screenshot, image generation)
|
|
347
|
+
const imageDataList: string[] = [];
|
|
346
348
|
if (Array.isArray(block.contentBlocks)) {
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
349
|
+
for (const cb of block.contentBlocks) {
|
|
350
|
+
if (
|
|
351
|
+
isRecord(cb) &&
|
|
352
|
+
cb.type === "image" &&
|
|
353
|
+
isRecord(cb.source) &&
|
|
354
|
+
typeof (cb.source as Record<string, unknown>).data === "string"
|
|
355
|
+
) {
|
|
356
|
+
imageDataList.push(
|
|
357
|
+
(cb.source as Record<string, unknown>).data as string,
|
|
358
|
+
);
|
|
354
359
|
}
|
|
355
360
|
}
|
|
356
361
|
}
|
|
@@ -358,14 +363,19 @@ export function renderHistoryContent(content: unknown): RenderedHistoryContent {
|
|
|
358
363
|
if (matched) {
|
|
359
364
|
matched.result = resultContent;
|
|
360
365
|
matched.isError = isError;
|
|
361
|
-
if (
|
|
366
|
+
if (imageDataList.length > 0) {
|
|
367
|
+
matched.imageData = imageDataList[0];
|
|
368
|
+
matched.imageDataList = imageDataList;
|
|
369
|
+
}
|
|
362
370
|
} else {
|
|
363
371
|
toolCalls.push({
|
|
364
372
|
name: "unknown",
|
|
365
373
|
input: {},
|
|
366
374
|
result: resultContent,
|
|
367
375
|
isError,
|
|
368
|
-
...(
|
|
376
|
+
...(imageDataList.length > 0
|
|
377
|
+
? { imageData: imageDataList[0], imageDataList }
|
|
378
|
+
: {}),
|
|
369
379
|
});
|
|
370
380
|
}
|
|
371
381
|
continue;
|