@vellumai/assistant 0.4.43 β 0.4.45
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/.prettierignore +4 -0
- package/ARCHITECTURE.md +46 -44
- package/README.md +15 -16
- package/bun.lock +10 -35
- package/docs/architecture/integrations.md +102 -215
- package/docs/architecture/keychain-broker.md +1 -1
- package/docs/architecture/memory.md +2 -2
- package/docs/architecture/scheduling.md +1 -1
- package/docs/architecture/security.md +11 -11
- package/docs/error-handling.md +1 -1
- package/docs/trusted-contact-access.md +3 -3
- package/drizzle/meta/0000_snapshot.json +34 -100
- package/drizzle/meta/_journal.json +1 -1
- package/drizzle.config.ts +4 -4
- package/package.json +3 -2
- package/scripts/capture-x-graphql.ts +237 -141
- package/scripts/generate-bundled-tool-registry.ts +223 -0
- package/src/__tests__/access-request-decision.test.ts +0 -1
- package/src/__tests__/actor-token-service.test.ts +23 -24
- package/src/__tests__/agent-loop.test.ts +0 -131
- package/src/__tests__/always-loaded-tools-guard.test.ts +71 -0
- package/src/__tests__/amazon-cdp-integration.test.ts +11 -9
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +11 -3
- package/src/__tests__/asset-materialize-tool.test.ts +0 -1
- package/src/__tests__/asset-search-tool.test.ts +0 -1
- package/src/__tests__/assistant-attachment-directive.test.ts +1 -1
- package/src/__tests__/assistant-events-sse-hardening.test.ts +0 -1
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +70 -18
- package/src/__tests__/assistant-id-boundary-guard.test.ts +6 -6
- package/src/__tests__/attachments-store.test.ts +0 -1
- package/src/__tests__/avatar-e2e.test.ts +74 -115
- package/src/__tests__/avatar-router.test.ts +25 -62
- package/src/__tests__/browser-manager.test.ts +24 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +4 -3
- package/src/__tests__/browser-skill-endstate.test.ts +8 -11
- package/src/__tests__/btw-routes.test.ts +326 -0
- package/src/__tests__/bundled-asset.test.ts +1 -1
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +23 -9
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/call-conversation-messages.test.ts +0 -1
- package/src/__tests__/call-domain.test.ts +0 -1
- package/src/__tests__/call-pointer-messages.test.ts +0 -1
- package/src/__tests__/call-recovery.test.ts +0 -1
- package/src/__tests__/call-routes-http.test.ts +0 -1
- package/src/__tests__/call-store.test.ts +0 -1
- package/src/__tests__/canonical-guardian-store.test.ts +0 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +0 -1
- package/src/__tests__/channel-guardian.test.ts +5 -7
- package/src/__tests__/channel-retry-sweep.test.ts +0 -1
- package/src/__tests__/checker.test.ts +32 -36
- package/src/__tests__/compaction.benchmark.test.ts +16 -14
- package/src/__tests__/computer-use-session-lifecycle.test.ts +10 -11
- package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +2 -5
- package/src/__tests__/computer-use-tools.test.ts +35 -31
- package/src/__tests__/config-schema.test.ts +11 -15
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/conflict-store.test.ts +0 -1
- package/src/__tests__/connection-policy.test.ts +4 -7
- package/src/__tests__/contacts-tools.test.ts +0 -1
- package/src/__tests__/context-memory-e2e.test.ts +2 -4
- package/src/__tests__/context-overflow-reducer.test.ts +2 -4
- package/src/__tests__/context-window-manager.test.ts +147 -60
- package/src/__tests__/contradiction-checker.test.ts +0 -1
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +31 -7
- package/src/__tests__/conversation-routes-slash-commands.test.ts +381 -0
- package/src/__tests__/conversation-store.test.ts +0 -1
- package/src/__tests__/conversation-unread-route.test.ts +1 -2
- package/src/__tests__/credential-security-invariants.test.ts +8 -8
- package/src/__tests__/cross-provider-web-search.test.ts +353 -0
- package/src/__tests__/daemon-assistant-events.test.ts +6 -7
- package/src/__tests__/db-schedule-syntax-migration.test.ts +15 -3
- package/src/__tests__/delete-managed-skill-tool.test.ts +5 -9
- package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
- package/src/__tests__/diagnostics-export.test.ts +189 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
- package/src/__tests__/entity-extractor.test.ts +0 -1
- package/src/__tests__/entity-search.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +2 -4
- package/src/__tests__/error-handler-friendly-messages.test.ts +46 -0
- package/src/__tests__/file-read-tool.test.ts +86 -0
- package/src/__tests__/followup-tools.test.ts +0 -1
- package/src/__tests__/frontmatter.test.ts +77 -34
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/gateway-only-guard.test.ts +1 -1
- package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -1
- package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
- package/src/__tests__/guardian-action-followup-store.test.ts +0 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-action-late-reply.test.ts +0 -1
- package/src/__tests__/guardian-action-store.test.ts +0 -1
- package/src/__tests__/guardian-action-sweep.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -2
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-outbound-http.test.ts +0 -1
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +1 -1
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +3 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +28 -426
- package/src/__tests__/host-bash-proxy.test.ts +335 -0
- package/src/__tests__/host-file-proxy.test.ts +374 -0
- package/src/__tests__/host-shell-tool.test.ts +147 -1
- package/src/__tests__/http-user-message-parity.test.ts +361 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
- package/src/__tests__/integration-status.test.ts +3 -8
- package/src/__tests__/intent-routing.test.ts +7 -46
- package/src/__tests__/invite-redemption-service.test.ts +0 -1
- package/src/__tests__/invite-routes-http.test.ts +0 -1
- package/src/__tests__/llm-usage-store.test.ts +0 -1
- package/src/__tests__/managed-avatar-client.test.ts +101 -55
- package/src/__tests__/managed-skill-lifecycle.test.ts +9 -18
- package/src/__tests__/managed-store.test.ts +94 -21
- package/src/__tests__/media-reuse-story.e2e.test.ts +0 -1
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +2 -4
- package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -1
- package/src/__tests__/memory-recall-quality.test.ts +0 -1
- package/src/__tests__/memory-regressions.experimental.test.ts +0 -1
- package/src/__tests__/memory-regressions.test.ts +0 -1
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -1
- package/src/__tests__/memory-upsert-concurrency.test.ts +0 -1
- package/src/__tests__/messaging-send-tool.test.ts +35 -0
- package/src/__tests__/messaging-skill-split.test.ts +138 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1
- package/src/__tests__/migration-export-http.test.ts +2 -3
- package/src/__tests__/migration-import-commit-http.test.ts +1 -2
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -2
- package/src/__tests__/migration-validate-http.test.ts +1 -2
- package/src/__tests__/native-web-search.test.ts +475 -0
- package/src/__tests__/navigate-settings-tab.test.ts +84 -0
- package/src/__tests__/non-member-access-request.test.ts +0 -1
- package/src/__tests__/notification-broadcaster.test.ts +15 -15
- package/src/__tests__/notification-decision-strategy.test.ts +6 -6
- package/src/__tests__/notification-deep-link.test.ts +7 -7
- package/src/__tests__/notification-guardian-path.test.ts +2 -3
- package/src/__tests__/notification-telegram-adapter.test.ts +1 -1
- package/src/__tests__/notification-thread-candidates.test.ts +4 -4
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +0 -10
- package/src/__tests__/playbook-execution.test.ts +0 -1
- package/src/__tests__/playbook-tools.test.ts +0 -1
- package/src/__tests__/profile-compiler.test.ts +0 -1
- package/src/__tests__/provider-fail-open-selection.test.ts +12 -2
- package/src/__tests__/provider-managed-proxy-integration.test.ts +25 -0
- package/src/__tests__/qdrant-collection-migration.test.ts +223 -0
- package/src/__tests__/recording-handler.test.ts +30 -94
- package/src/__tests__/registry.test.ts +28 -35
- package/src/__tests__/relay-server.test.ts +0 -1
- package/src/__tests__/ride-shotgun-handler.test.ts +4 -20
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +0 -1
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -1
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +30 -28
- package/src/__tests__/schedule-store.test.ts +441 -1
- package/src/__tests__/schedule-tools.test.ts +468 -7
- package/src/__tests__/scheduler-recurrence.test.ts +196 -23
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +6 -3
- package/src/__tests__/secret-response-routing.test.ts +4 -1
- package/src/__tests__/send-endpoint-busy.test.ts +14 -5
- package/src/__tests__/send-notification-tool.test.ts +0 -7
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/server-history-render.test.ts +1 -2
- package/src/__tests__/session-abort-tool-results.test.ts +0 -1
- package/src/__tests__/session-agent-loop.test.ts +46 -6
- package/src/__tests__/session-confirmation-signals.test.ts +7 -46
- package/src/__tests__/session-conflict-gate.test.ts +2 -6
- package/src/__tests__/session-error.test.ts +5 -14
- package/src/__tests__/session-init.benchmark.test.ts +3 -5
- package/src/__tests__/session-load-history-repair.test.ts +0 -1
- package/src/__tests__/session-media-retry.test.ts +12 -74
- package/src/__tests__/session-pre-run-repair.test.ts +0 -1
- package/src/__tests__/session-profile-injection.test.ts +2 -6
- package/src/__tests__/session-provider-retry-repair.test.ts +2 -6
- package/src/__tests__/session-queue.test.ts +94 -139
- package/src/__tests__/session-skill-tools.test.ts +115 -115
- package/src/__tests__/session-slash-known.test.ts +0 -1
- package/src/__tests__/session-slash-queue.test.ts +0 -1
- package/src/__tests__/session-slash-unknown.test.ts +0 -1
- package/src/__tests__/session-surfaces-task-progress.test.ts +34 -0
- package/src/__tests__/session-usage.test.ts +0 -1
- package/src/__tests__/session-workspace-cache-state.test.ts +2 -6
- package/src/__tests__/session-workspace-injection.test.ts +2 -6
- package/src/__tests__/session-workspace-tool-tracking.test.ts +2 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +180 -184
- package/src/__tests__/skill-feature-flags.test.ts +125 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -2
- package/src/__tests__/skill-load-tool.test.ts +194 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +27 -16
- package/src/__tests__/skill-projection.benchmark.test.ts +15 -14
- package/src/__tests__/skills.test.ts +14 -53
- package/src/__tests__/slack-channel-config.test.ts +0 -1
- package/src/__tests__/slack-inbound-verification.test.ts +0 -1
- package/src/__tests__/slack-skill.test.ts +1 -1
- package/src/__tests__/starter-task-flow.test.ts +9 -19
- package/src/__tests__/subagent-tools.test.ts +2 -2
- package/src/__tests__/system-prompt.test.ts +7 -7
- package/src/__tests__/task-compiler.test.ts +0 -1
- package/src/__tests__/task-management-tools.test.ts +0 -1
- package/src/__tests__/task-memory-cleanup.test.ts +0 -1
- package/src/__tests__/task-runner.test.ts +0 -1
- package/src/__tests__/task-scheduler.test.ts +0 -1
- package/src/__tests__/terminal-tools.test.ts +0 -1
- package/src/__tests__/test-support/computer-use-skill-harness.ts +2 -4
- package/src/__tests__/thread-seed-composer.test.ts +5 -5
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +8 -86
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/tool-notification-listener.test.ts +1 -1
- package/src/__tests__/tool-preview-lifecycle.test.ts +416 -0
- package/src/__tests__/trust-store.test.ts +84 -8
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/trusted-contact-verification.test.ts +0 -1
- package/src/__tests__/twilio-provider.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +0 -1
- package/src/__tests__/{request-file-tool.test.ts β ui-file-upload-surface.test.ts} +11 -72
- package/src/__tests__/update-bulletin.test.ts +0 -1
- package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -1
- package/src/__tests__/usage-routes.test.ts +0 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -4
- package/src/__tests__/voice-invite-redemption.test.ts +0 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/__tests__/voice-session-bridge.test.ts +9 -1
- package/src/__tests__/web-fetch.test.ts +57 -0
- package/src/__tests__/workspace-git-service.test.ts +5 -14
- package/src/__tests__/workspace-policy.test.ts +0 -1
- package/src/agent/loop.ts +22 -34
- package/src/bundler/bundle-signer.ts +4 -4
- package/src/calls/call-controller.ts +1 -1
- package/src/calls/relay-server.ts +1 -1
- package/src/calls/twilio-rest.ts +1 -1
- package/src/calls/voice-session-bridge.ts +3 -1
- package/src/cli/__tests__/notifications.test.ts +3 -4
- package/src/cli/commands/map.ts +2 -6
- package/src/cli/commands/mcp.ts +73 -15
- package/src/cli/commands/notifications.ts +4 -4
- package/src/cli/commands/sessions.ts +9 -1
- package/src/cli/commands/skills.ts +6 -10
- package/src/cli/http-client.ts +2 -3
- package/src/cli/main-screen.tsx +10 -10
- package/src/cli/program.ts +0 -4
- package/src/cli/reference.ts +0 -2
- package/src/cli.ts +15 -9
- package/src/config/__tests__/bundled-tool-registry-guard.test.ts +120 -0
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +11 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +6 -7
- package/src/config/bundled-skills/app-builder/TOOLS.json +0 -4
- package/src/config/bundled-skills/browser/SKILL.md +6 -1
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +5 -1
- package/src/config/bundled-skills/claude-code/SKILL.md +5 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -1
- package/src/config/bundled-skills/computer-use/TOOLS.json +6 -69
- package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +10 -1
- package/src/config/bundled-skills/contacts/SKILL.md +10 -1
- package/src/config/bundled-skills/contacts/TOOLS.json +35 -0
- package/src/config/bundled-skills/{messaging β contacts}/tools/google-contacts.ts +9 -2
- package/src/config/bundled-skills/document/SKILL.md +4 -1
- package/src/config/bundled-skills/doordash/SKILL.md +8 -2
- package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +1 -82
- package/src/config/bundled-skills/doordash/doordash-cli.ts +17 -28
- package/src/config/bundled-skills/doordash/lib/session.ts +21 -17
- package/src/config/bundled-skills/doordash/lib/shared/platform.ts +4 -1
- package/src/config/bundled-skills/followups/SKILL.md +4 -1
- package/src/config/bundled-skills/gmail/SKILL.md +180 -0
- package/src/config/bundled-skills/gmail/TOOLS.json +506 -0
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +149 -0
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +110 -0
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-draft.ts +1 -1
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-filters.ts +1 -1
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-follow-up.ts +1 -1
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-forward.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +50 -0
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-outreach-scan.ts +8 -90
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-send-draft.ts +1 -1
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-sender-digest.ts +2 -2
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-trash.ts +1 -1
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-unsubscribe.ts +1 -1
- package/src/config/bundled-skills/{messaging β gmail}/tools/gmail-vacation.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/shared.ts +47 -0
- package/src/config/bundled-skills/google-calendar/SKILL.md +5 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +5 -1
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -1
- package/src/config/bundled-skills/media-processing/SKILL.md +7 -13
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -22
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +12 -1
- package/src/config/bundled-skills/messaging/SKILL.md +23 -139
- package/src/config/bundled-skills/messaging/TOOLS.json +33 -1215
- package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +42 -0
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +165 -2
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +1 -13
- package/src/config/bundled-skills/messaging/tools/shared.ts +81 -34
- package/src/config/bundled-skills/notifications/SKILL.md +5 -1
- package/src/config/bundled-skills/orchestration/SKILL.md +30 -0
- package/src/config/bundled-skills/orchestration/TOOLS.json +35 -0
- package/src/config/bundled-skills/{reminder/tools/reminder-cancel.ts β orchestration/tools/swarm-delegate.ts} +3 -3
- package/src/config/bundled-skills/phone-calls/SKILL.md +9 -1
- package/src/config/bundled-skills/playbooks/SKILL.md +4 -1
- package/src/config/bundled-skills/schedule/SKILL.md +70 -9
- package/src/config/bundled-skills/schedule/TOOLS.json +38 -6
- package/src/config/bundled-skills/screen-watch/SKILL.md +28 -0
- package/src/config/bundled-skills/screen-watch/TOOLS.json +35 -0
- package/src/config/bundled-skills/{reminder/tools/reminder-create.ts β screen-watch/tools/start-screen-watch.ts} +3 -3
- package/src/config/bundled-skills/sequences/SKILL.md +47 -0
- package/src/config/bundled-skills/sequences/TOOLS.json +340 -0
- package/src/config/bundled-skills/sequences/tools/sequence-update.ts +128 -0
- package/src/config/bundled-skills/sequences/tools/shared.ts +9 -0
- package/src/config/bundled-skills/settings/SKILL.md +12 -0
- package/src/config/bundled-skills/settings/TOOLS.json +112 -0
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +43 -0
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +52 -0
- package/src/config/bundled-skills/{computer-use/tools/computer-use-right-click.ts β settings/tools/set-avatar.ts} +2 -6
- package/src/{tools/system/voice-config.ts β config/bundled-skills/settings/tools/voice-config-update.ts} +59 -96
- package/src/config/bundled-skills/skill-management/SKILL.md +18 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +90 -0
- package/src/config/bundled-skills/{computer-use/tools/computer-use-double-click.ts β skill-management/tools/delete-managed.ts} +2 -6
- package/src/config/bundled-skills/skill-management/tools/scaffold-managed.ts +12 -0
- package/src/config/bundled-skills/slack/SKILL.md +5 -1
- package/src/config/bundled-skills/subagent/SKILL.md +4 -1
- package/src/config/bundled-skills/tasks/SKILL.md +5 -2
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -1
- package/src/config/bundled-skills/watcher/SKILL.md +4 -1
- package/src/config/bundled-tool-registry.ts +118 -107
- package/src/config/env.ts +5 -2
- package/src/config/feature-flag-registry.json +33 -9
- package/src/config/loader.ts +10 -2
- package/src/config/schema.ts +19 -16
- package/src/config/schemas/inference.ts +12 -22
- package/src/config/schemas/memory-storage.ts +19 -1
- package/src/config/schemas/platform.ts +0 -16
- package/src/config/skill-state.ts +11 -8
- package/src/config/skills.ts +83 -32
- package/src/context/token-estimator.ts +11 -0
- package/src/context/window-manager.ts +180 -151
- package/src/daemon/computer-use-session.ts +11 -43
- package/src/daemon/daemon-control.ts +4 -1
- package/src/daemon/handlers/config-channels.ts +5 -9
- package/src/daemon/handlers/config-ingress.ts +0 -4
- package/src/daemon/handlers/config-model.ts +7 -13
- package/src/daemon/handlers/config-telegram.ts +4 -8
- package/src/daemon/handlers/config-voice.ts +2 -5
- package/src/daemon/handlers/dictation.ts +2 -12
- package/src/daemon/handlers/identity.ts +0 -105
- package/src/daemon/handlers/recording.ts +3 -23
- package/src/daemon/handlers/session-history.ts +42 -10
- package/src/daemon/handlers/sessions.ts +53 -72
- package/src/daemon/handlers/shared.ts +7 -28
- package/src/daemon/handlers/skills.ts +31 -27
- package/src/daemon/host-bash-proxy.ts +148 -0
- package/src/daemon/host-file-proxy.ts +135 -0
- package/src/daemon/lifecycle.ts +53 -41
- package/src/daemon/mcp-reload-service.ts +123 -0
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/apps.ts +0 -25
- package/src/daemon/message-types/browser.ts +1 -1
- package/src/daemon/message-types/computer-use.ts +1 -4
- package/src/daemon/message-types/guardian-actions.ts +1 -1
- package/src/daemon/message-types/host-bash.ts +18 -0
- package/src/daemon/message-types/host-file.ts +44 -0
- package/src/daemon/message-types/integrations.ts +1 -73
- package/src/daemon/message-types/messages.ts +15 -0
- package/src/daemon/message-types/schedules.ts +11 -27
- package/src/daemon/message-types/sessions.ts +8 -2
- package/src/daemon/message-types/settings.ts +1 -1
- package/src/daemon/message-types/shared.ts +1 -1
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/ride-shotgun-handler.ts +35 -43
- package/src/daemon/seed-files.ts +3 -27
- package/src/daemon/server.ts +45 -28
- package/src/daemon/session-agent-loop-handlers.ts +72 -9
- package/src/daemon/session-agent-loop.ts +97 -66
- package/src/daemon/session-attachments.ts +1 -1
- package/src/daemon/session-error.ts +17 -16
- package/src/daemon/session-lifecycle.ts +20 -1
- package/src/daemon/session-media-retry.ts +1 -15
- package/src/daemon/session-messaging.ts +14 -6
- package/src/daemon/session-process.ts +36 -7
- package/src/daemon/session-queue-manager.ts +62 -103
- package/src/daemon/session-runtime-assembly.ts +27 -7
- package/src/daemon/session-skill-tools.ts +12 -11
- package/src/daemon/session-slash.ts +7 -0
- package/src/daemon/session-surfaces.ts +192 -118
- package/src/daemon/session-tool-setup.ts +146 -6
- package/src/daemon/session.ts +75 -37
- package/src/errors.ts +0 -2
- package/src/export/formatter.ts +6 -0
- package/src/mcp/mcp-oauth-provider.ts +1 -3
- package/src/media/avatar-router.ts +20 -28
- package/src/media/avatar-types.ts +7 -14
- package/src/media/managed-avatar-client.ts +70 -34
- package/src/memory/app-store.ts +0 -18
- package/src/memory/conversation-title-service.ts +1 -2
- package/src/memory/db-init.ts +16 -0
- package/src/memory/embedding-backend.ts +129 -27
- package/src/memory/embedding-gemini.test.ts +256 -0
- package/src/memory/embedding-gemini.ts +47 -13
- package/src/memory/embedding-local.ts +14 -2
- package/src/memory/embedding-ollama.ts +15 -2
- package/src/memory/embedding-openai.ts +15 -2
- package/src/memory/embedding-types.test.ts +116 -0
- package/src/memory/embedding-types.ts +61 -0
- package/src/memory/fingerprint.ts +1 -1
- package/src/memory/indexer.ts +25 -1
- package/src/memory/job-handlers/embedding.test.ts +258 -0
- package/src/memory/job-handlers/embedding.ts +81 -1
- package/src/memory/job-handlers/index-maintenance.ts +35 -1
- package/src/memory/job-handlers/media-processing.ts +11 -1
- package/src/memory/job-utils.ts +21 -6
- package/src/memory/jobs-store.ts +5 -1
- package/src/memory/jobs-worker.ts +8 -0
- package/src/memory/message-content.ts +66 -0
- package/src/memory/migrations/100-core-tables.ts +1 -31
- package/src/memory/migrations/104-core-indexes.ts +0 -11
- package/src/memory/migrations/145-drop-accounts-table.ts +19 -0
- package/src/memory/migrations/146-schedule-oneshot-routing.ts +94 -0
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +129 -0
- package/src/memory/migrations/148-drop-reminders-table.ts +18 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/migrations/registry.ts +19 -0
- package/src/memory/qdrant-client.ts +158 -43
- package/src/memory/retriever.test.ts +0 -1
- package/src/memory/retriever.ts +12 -2
- package/src/memory/schema/infrastructure.ts +5 -37
- package/src/memory/search/formatting.ts +34 -9
- package/src/memory/search/semantic.ts +57 -2
- package/src/memory/search/types.ts +2 -1
- package/src/notifications/AGENTS.md +2 -2
- package/src/notifications/README.md +59 -58
- package/src/notifications/adapters/macos.ts +1 -1
- package/src/notifications/broadcaster.ts +5 -5
- package/src/notifications/copy-composer.ts +1 -1
- package/src/notifications/decision-engine.ts +2 -2
- package/src/notifications/destination-resolver.ts +2 -2
- package/src/notifications/emit-signal.ts +8 -8
- package/src/notifications/signal.ts +1 -1
- package/src/notifications/thread-seed-composer.ts +1 -1
- package/src/oauth/connect-orchestrator.ts +1 -1
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +12 -1
- package/src/permissions/defaults.ts +13 -17
- package/src/permissions/trust-store.ts +37 -0
- package/src/permissions/workspace-policy.ts +0 -1
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +11 -0
- package/src/prompts/computer-use-prompt.ts +1 -1
- package/src/prompts/system-prompt.ts +33 -35
- package/src/prompts/templates/BOOTSTRAP.md +0 -3
- package/src/prompts/templates/SOUL.md +1 -2
- package/src/prompts/templates/UPDATES.md +16 -7
- package/src/providers/anthropic/client.ts +87 -33
- package/src/providers/gemini/client.ts +6 -0
- package/src/providers/managed-proxy/constants.ts +5 -0
- package/src/providers/openai/client.ts +15 -0
- package/src/providers/registry.ts +4 -6
- package/src/providers/types.ts +24 -2
- package/src/runtime/AGENTS.md +18 -0
- package/src/runtime/assistant-event-hub.ts +2 -3
- package/src/runtime/assistant-event.ts +4 -4
- package/src/runtime/auth/__tests__/context.test.ts +5 -5
- package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
- package/src/runtime/auth/__tests__/guard-tests.test.ts +3 -2
- package/src/runtime/auth/__tests__/{ipc-auth-context.test.ts β local-auth-context.test.ts} +21 -21
- package/src/runtime/auth/__tests__/route-policy.test.ts +2 -2
- package/src/runtime/auth/__tests__/scopes.test.ts +9 -8
- package/src/runtime/auth/__tests__/subject.test.ts +8 -8
- package/src/runtime/auth/__tests__/token-service.test.ts +0 -1
- package/src/runtime/auth/route-policy.ts +8 -8
- package/src/runtime/auth/scopes.ts +2 -1
- package/src/runtime/auth/subject.ts +4 -4
- package/src/runtime/auth/token-service.ts +1 -24
- package/src/runtime/auth/types.ts +3 -3
- package/src/runtime/guardian-action-followup-executor.ts +1 -1
- package/src/runtime/guardian-action-grant-minter.ts +1 -1
- package/src/runtime/guardian-action-service.ts +3 -3
- package/src/runtime/http-server.ts +15 -2
- package/src/runtime/http-types.ts +10 -0
- package/src/runtime/invite-service.ts +3 -3
- package/src/runtime/local-actor-identity.ts +17 -22
- package/src/runtime/middleware/error-handler.ts +14 -1
- package/src/runtime/pending-interactions.ts +21 -9
- package/src/runtime/routes/app-management-routes.ts +63 -67
- package/src/runtime/routes/approval-routes.ts +1 -3
- package/src/runtime/routes/brain-graph/brain-graph.html +1845 -0
- package/src/runtime/routes/brain-graph-routes.ts +4 -42
- package/src/runtime/routes/btw-routes.ts +155 -0
- package/src/runtime/routes/computer-use-routes.ts +77 -31
- package/src/runtime/routes/conversation-routes.ts +234 -47
- package/src/runtime/routes/diagnostics-routes.ts +154 -43
- package/src/runtime/routes/documents-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/host-bash-routes.ts +83 -0
- package/src/runtime/routes/host-file-routes.ts +79 -0
- package/src/runtime/routes/integrations/slack/share.ts +1 -1
- package/src/runtime/routes/log-export-routes.ts +120 -0
- package/src/runtime/routes/mcp-routes.ts +20 -0
- package/src/runtime/routes/migration-routes.ts +3 -3
- package/src/runtime/routes/pairing-routes.ts +1 -1
- package/src/runtime/routes/recording-routes.ts +6 -4
- package/src/runtime/routes/schedule-routes.ts +31 -5
- package/src/runtime/routes/session-management-routes.ts +2 -6
- package/src/runtime/routes/session-query-routes.ts +18 -15
- package/src/runtime/routes/settings-routes.ts +7 -351
- package/src/runtime/routes/skills-routes.ts +7 -6
- package/src/runtime/routes/subagents-routes.ts +4 -10
- package/src/runtime/routes/surface-action-routes.ts +3 -14
- package/src/runtime/routes/surface-content-routes.ts +22 -5
- package/src/runtime/routes/work-items-routes.ts +21 -25
- package/src/runtime/routes/workspace-routes.test.ts +3 -3
- package/src/runtime/routes/workspace-utils.ts +1 -1
- package/src/runtime/telegram-streaming-delivery.ts +3 -0
- package/src/runtime/verification-outbound-actions.ts +2 -2
- package/src/schedule/integration-status.ts +0 -6
- package/src/schedule/schedule-store.ts +234 -43
- package/src/schedule/scheduler.ts +73 -74
- package/src/security/oauth2.ts +1 -1
- package/src/sequence/store.ts +12 -2
- package/src/skills/frontmatter.ts +19 -77
- package/src/skills/managed-store.ts +11 -2
- package/src/subagent/manager.ts +5 -3
- package/src/tasks/ephemeral-permissions.ts +3 -5
- package/src/tools/AGENTS.md +37 -0
- package/src/tools/apps/executors.ts +0 -6
- package/src/tools/browser/browser-manager.ts +17 -11
- package/src/tools/browser/jit-auth.ts +4 -1
- package/src/tools/claude-code/claude-code.ts +1 -1
- package/src/tools/computer-use/definitions.ts +48 -60
- package/src/tools/document/document-tool.ts +6 -6
- package/src/tools/document/editor-template.ts +10 -8
- package/src/tools/filesystem/edit.ts +2 -1
- package/src/tools/filesystem/read.ts +20 -2
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +17 -1
- package/src/tools/host-filesystem/read.ts +16 -1
- package/src/tools/host-filesystem/write.ts +15 -1
- package/src/tools/host-terminal/host-shell.ts +24 -0
- package/src/tools/memory/definitions.ts +45 -81
- package/src/tools/memory/handlers.test.ts +0 -1
- package/src/tools/memory/handlers.ts +1 -1
- package/src/tools/memory/register.ts +26 -60
- package/src/tools/network/script-proxy/session-manager.ts +6 -8
- package/src/tools/network/web-fetch.ts +7 -1
- package/src/tools/network/web-search.ts +2 -1
- package/src/tools/registry.ts +23 -0
- package/src/tools/schedule/create.ts +113 -5
- package/src/tools/schedule/list.ts +57 -15
- package/src/tools/schedule/update.ts +73 -3
- package/src/tools/shared/filesystem/image-read.ts +192 -0
- package/src/tools/side-effects.ts +1 -7
- package/src/tools/skills/delete-managed.ts +27 -64
- package/src/tools/skills/execute.ts +54 -0
- package/src/tools/skills/load.ts +127 -5
- package/src/tools/skills/scaffold-managed.ts +93 -172
- package/src/tools/subagent/message.ts +0 -7
- package/src/tools/subagent/spawn.ts +1 -1
- package/src/tools/swarm/delegate.ts +0 -3
- package/src/tools/system/avatar-generator.ts +13 -19
- package/src/tools/system/request-permission.ts +2 -1
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/tool-manifest.ts +41 -47
- package/src/tools/types.ts +6 -2
- package/src/tools/ui-surface/definitions.ts +0 -55
- package/src/util/errors.ts +12 -10
- package/src/workspace/git-service.ts +0 -2
- package/src/__tests__/account-registry.test.ts +0 -258
- package/src/__tests__/email-classifier.test.ts +0 -25
- package/src/__tests__/gmail-integration.test.ts +0 -97
- package/src/__tests__/handle-user-message-secret-resume.test.ts +0 -172
- package/src/__tests__/home-base-bootstrap.test.ts +0 -84
- package/src/__tests__/managed-twitter-guardrails.test.ts +0 -353
- package/src/__tests__/prebuilt-home-base-seed.test.ts +0 -79
- package/src/__tests__/recording-intent-fallback.test.ts +0 -199
- package/src/__tests__/recording-intent.test.ts +0 -985
- package/src/__tests__/recording-state-machine.test.ts +0 -1574
- package/src/__tests__/reminder-store.test.ts +0 -350
- package/src/__tests__/reminder.test.ts +0 -337
- package/src/__tests__/scan-result-store.test.ts +0 -121
- package/src/__tests__/twitter-platform-proxy-client.test.ts +0 -450
- package/src/__tests__/view-image-tool.test.ts +0 -241
- package/src/cli/commands/amazon/cart.ts +0 -513
- package/src/cli/commands/amazon/checkout.ts +0 -394
- package/src/cli/commands/amazon/client.ts +0 -513
- package/src/cli/commands/amazon/index.ts +0 -920
- package/src/cli/commands/amazon/product-details.ts +0 -145
- package/src/cli/commands/amazon/request-extractor.ts +0 -187
- package/src/cli/commands/amazon/search.ts +0 -76
- package/src/cli/commands/amazon/session.ts +0 -116
- package/src/cli/commands/twitter/__tests__/cli-error-shaping.test.ts +0 -265
- package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +0 -483
- package/src/cli/commands/twitter/__tests__/cli-routing.test.ts +0 -412
- package/src/cli/commands/twitter/__tests__/oauth-client.test.ts +0 -197
- package/src/cli/commands/twitter/client.ts +0 -989
- package/src/cli/commands/twitter/index.ts +0 -1160
- package/src/cli/commands/twitter/oauth-client.ts +0 -94
- package/src/cli/commands/twitter/router.ts +0 -396
- package/src/cli/commands/twitter/session.ts +0 -121
- package/src/config/bundled-skills/agentmail/SKILL.md +0 -132
- package/src/config/bundled-skills/agentmail/icon.svg +0 -21
- package/src/config/bundled-skills/amazon/SKILL.md +0 -137
- package/src/config/bundled-skills/amazon/icon.svg +0 -13
- package/src/config/bundled-skills/api-mapping/SKILL.md +0 -78
- package/src/config/bundled-skills/api-mapping/icon.svg +0 -18
- package/src/config/bundled-skills/cli-discover/SKILL.md +0 -68
- package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +0 -179
- package/src/config/bundled-skills/document-writer/SKILL.md +0 -195
- package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +0 -140
- package/src/config/bundled-skills/email-setup/SKILL.md +0 -68
- package/src/config/bundled-skills/frontend-design/SKILL.md +0 -44
- package/src/config/bundled-skills/frontend-design/icon.svg +0 -16
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +0 -452
- package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +0 -203
- package/src/config/bundled-skills/influencer/SKILL.md +0 -144
- package/src/config/bundled-skills/influencer/scripts/client.ts +0 -1269
- package/src/config/bundled-skills/influencer/scripts/influencer.ts +0 -267
- package/src/config/bundled-skills/macos-automation/SKILL.md +0 -65
- package/src/config/bundled-skills/macos-automation/icon.svg +0 -12
- package/src/config/bundled-skills/mcp-setup/SKILL.md +0 -75
- package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +0 -184
- package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +0 -80
- package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +0 -29
- package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +0 -56
- package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +0 -34
- package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +0 -47
- package/src/config/bundled-skills/messaging/tools/gmail-label.ts +0 -31
- package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +0 -67
- package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +0 -97
- package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +0 -135
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +0 -24
- package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +0 -201
- package/src/config/bundled-skills/messaging/tools/send-notification.ts +0 -1
- package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +0 -27
- package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +0 -48
- package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +0 -27
- package/src/config/bundled-skills/messaging/tools/sequence-update.ts +0 -56
- package/src/config/bundled-skills/notion/SKILL.md +0 -240
- package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +0 -126
- package/src/config/bundled-skills/oauth-setup/SKILL.md +0 -143
- package/src/config/bundled-skills/public-ingress/SKILL.md +0 -258
- package/src/config/bundled-skills/reminder/SKILL.md +0 -79
- package/src/config/bundled-skills/reminder/TOOLS.json +0 -89
- package/src/config/bundled-skills/reminder/tools/reminder-list.ts +0 -12
- package/src/config/bundled-skills/restaurant-reservation/SKILL.md +0 -141
- package/src/config/bundled-skills/screen-recording/SKILL.md +0 -148
- package/src/config/bundled-skills/self-upgrade/SKILL.md +0 -69
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -78
- package/src/config/bundled-skills/slack-app-setup/SKILL.md +0 -178
- package/src/config/bundled-skills/slack-digest-setup/SKILL.md +0 -163
- package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +0 -157
- package/src/config/bundled-skills/start-the-day/SKILL.md +0 -70
- package/src/config/bundled-skills/start-the-day/icon.svg +0 -13
- package/src/config/bundled-skills/telegram-setup/SKILL.md +0 -105
- package/src/config/bundled-skills/time-based-actions/SKILL.md +0 -142
- package/src/config/bundled-skills/twilio-setup/SKILL.md +0 -232
- package/src/config/bundled-skills/twitter/SKILL.md +0 -319
- package/src/config/bundled-skills/twitter/icon.svg +0 -14
- package/src/config/bundled-skills/typescript-eval/SKILL.md +0 -60
- package/src/config/bundled-skills/vercel-token-setup/SKILL.md +0 -214
- package/src/config/bundled-skills/voice-setup/SKILL.md +0 -131
- package/src/config/bundled-skills/voice-setup/icon.svg +0 -20
- package/src/daemon/handlers/pairing.ts +0 -119
- package/src/daemon/handlers/session-user-message.ts +0 -961
- package/src/daemon/recording-executor.ts +0 -180
- package/src/daemon/recording-intent-fallback.ts +0 -162
- package/src/daemon/recording-intent.ts +0 -493
- package/src/home-base/app-link-store.ts +0 -78
- package/src/home-base/bootstrap.ts +0 -74
- package/src/home-base/prebuilt/brain-graph.html +0 -1483
- package/src/home-base/prebuilt/index.html +0 -702
- package/src/home-base/prebuilt/seed-metadata.json +0 -21
- package/src/home-base/prebuilt/seed.ts +0 -122
- package/src/home-base/prebuilt-home-base-updater.ts +0 -36
- package/src/memory/account-store.ts +0 -117
- package/src/messaging/activity-analyzer.ts +0 -76
- package/src/messaging/email-classifier.ts +0 -208
- package/src/messaging/index.ts +0 -2
- package/src/messaging/outreach-classifier.ts +0 -185
- package/src/messaging/thread-summarizer.ts +0 -346
- package/src/messaging/types.ts +0 -17
- package/src/tools/browser/x-auto-navigate.ts +0 -254
- package/src/tools/credentials/account-registry.ts +0 -144
- package/src/tools/filesystem/view-image.ts +0 -244
- package/src/tools/reminder/reminder-store.ts +0 -194
- package/src/tools/reminder/reminder.ts +0 -158
- package/src/tools/system/navigate-settings.ts +0 -74
- package/src/tools/system/open-system-settings.ts +0 -85
- package/src/tools/system/version.ts +0 -54
- package/src/twitter/platform-proxy-client.ts +0 -405
- package/src/util/cookie-session.ts +0 -98
- /package/src/config/bundled-skills/{messaging β gmail}/tools/scan-result-store.ts +0 -0
- /package/src/config/bundled-skills/{messaging β sequences}/tools/sequence-analytics.ts +0 -0
- /package/src/config/bundled-skills/{messaging β sequences}/tools/sequence-create.ts +0 -0
- /package/src/config/bundled-skills/{messaging β sequences}/tools/sequence-delete.ts +0 -0
- /package/src/config/bundled-skills/{messaging β sequences}/tools/sequence-enroll.ts +0 -0
- /package/src/config/bundled-skills/{messaging β sequences}/tools/sequence-enrollment-list.ts +0 -0
- /package/src/config/bundled-skills/{messaging β sequences}/tools/sequence-get.ts +0 -0
- /package/src/config/bundled-skills/{messaging β sequences}/tools/sequence-import.ts +0 -0
- /package/src/config/bundled-skills/{messaging β sequences}/tools/sequence-list.ts +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
getAttachment,
|
|
6
|
+
getMessage,
|
|
7
|
+
} from "../../../../messaging/providers/gmail/client.js";
|
|
8
|
+
import type { GmailMessagePart } from "../../../../messaging/providers/gmail/types.js";
|
|
9
|
+
import { getMessagingProvider } from "../../../../messaging/registry.js";
|
|
10
|
+
import { withValidToken } from "../../../../security/token-manager.js";
|
|
11
|
+
import type {
|
|
12
|
+
ToolContext,
|
|
13
|
+
ToolExecutionResult,
|
|
14
|
+
} from "../../../../tools/types.js";
|
|
15
|
+
import { err, ok } from "./shared.js";
|
|
16
|
+
|
|
17
|
+
interface AttachmentInfo {
|
|
18
|
+
partId: string;
|
|
19
|
+
filename: string;
|
|
20
|
+
mimeType: string;
|
|
21
|
+
size: number;
|
|
22
|
+
attachmentId: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Recursively walk the MIME parts tree to find attachments. */
|
|
26
|
+
function collectAttachments(
|
|
27
|
+
parts: GmailMessagePart[] | undefined,
|
|
28
|
+
): AttachmentInfo[] {
|
|
29
|
+
if (!parts) return [];
|
|
30
|
+
const result: AttachmentInfo[] = [];
|
|
31
|
+
for (const part of parts) {
|
|
32
|
+
if (part.filename && part.body?.attachmentId) {
|
|
33
|
+
result.push({
|
|
34
|
+
partId: part.partId ?? "",
|
|
35
|
+
filename: part.filename,
|
|
36
|
+
mimeType: part.mimeType ?? "application/octet-stream",
|
|
37
|
+
size: part.body.size ?? 0,
|
|
38
|
+
attachmentId: part.body.attachmentId,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (part.parts) {
|
|
42
|
+
result.push(...collectAttachments(part.parts));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function run(
|
|
49
|
+
input: Record<string, unknown>,
|
|
50
|
+
context: ToolContext,
|
|
51
|
+
): Promise<ToolExecutionResult> {
|
|
52
|
+
const action = input.action as string;
|
|
53
|
+
const messageId = input.message_id as string;
|
|
54
|
+
|
|
55
|
+
if (!action) return err("action is required.");
|
|
56
|
+
if (!messageId) return err("message_id is required.");
|
|
57
|
+
|
|
58
|
+
if (action === "list") {
|
|
59
|
+
try {
|
|
60
|
+
const provider = getMessagingProvider("gmail");
|
|
61
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
62
|
+
const message = await getMessage(token, messageId, "full");
|
|
63
|
+
const attachments = collectAttachments(message.payload?.parts);
|
|
64
|
+
|
|
65
|
+
if (attachments.length === 0) {
|
|
66
|
+
return ok("No attachments found on this message.");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return ok(JSON.stringify(attachments, null, 2));
|
|
70
|
+
});
|
|
71
|
+
} catch (e) {
|
|
72
|
+
return err(e instanceof Error ? e.message : String(e));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (action === "download") {
|
|
77
|
+
const attachmentId = input.attachment_id as string;
|
|
78
|
+
const filename = input.filename as string;
|
|
79
|
+
|
|
80
|
+
if (!attachmentId) return err("attachment_id is required for download.");
|
|
81
|
+
if (!filename) return err("filename is required for download.");
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const provider = getMessagingProvider("gmail");
|
|
85
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
86
|
+
const attachment = await getAttachment(token, messageId, attachmentId);
|
|
87
|
+
|
|
88
|
+
// Gmail returns base64url; convert to standard base64 then to Buffer
|
|
89
|
+
const base64 = attachment.data.replace(/-/g, "+").replace(/_/g, "/");
|
|
90
|
+
const buffer = Buffer.from(base64, "base64");
|
|
91
|
+
|
|
92
|
+
const outputDir = context.workingDir ?? process.cwd();
|
|
93
|
+
// Sanitize filename: strip path separators to prevent traversal attacks from crafted MIME filenames
|
|
94
|
+
const safeName = basename(filename).replace(/\.\./g, "_");
|
|
95
|
+
const outputPath = resolve(outputDir, safeName);
|
|
96
|
+
if (!outputPath.startsWith(outputDir))
|
|
97
|
+
return err("Invalid filename: path traversal detected.");
|
|
98
|
+
await writeFile(outputPath, buffer);
|
|
99
|
+
|
|
100
|
+
return ok(
|
|
101
|
+
`Attachment saved to ${outputPath} (${buffer.length} bytes).`,
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
} catch (e) {
|
|
105
|
+
return err(e instanceof Error ? e.message : String(e));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return err(`Unknown action: ${action}. Expected "list" or "download".`);
|
|
110
|
+
}
|
|
@@ -24,7 +24,7 @@ export async function run(
|
|
|
24
24
|
|
|
25
25
|
try {
|
|
26
26
|
const provider = getMessagingProvider("gmail");
|
|
27
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
27
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
28
28
|
const draft = await createDraft(
|
|
29
29
|
token,
|
|
30
30
|
to,
|
|
@@ -27,7 +27,7 @@ export async function run(
|
|
|
27
27
|
|
|
28
28
|
try {
|
|
29
29
|
const provider = getMessagingProvider("gmail");
|
|
30
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
30
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
31
31
|
switch (action) {
|
|
32
32
|
case "list": {
|
|
33
33
|
const filters = await listFilters(token);
|
|
@@ -36,7 +36,7 @@ export async function run(
|
|
|
36
36
|
|
|
37
37
|
try {
|
|
38
38
|
const provider = getMessagingProvider("gmail");
|
|
39
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
39
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
40
40
|
switch (action) {
|
|
41
41
|
case "track": {
|
|
42
42
|
const messageId = input.message_id as string;
|
|
@@ -77,7 +77,7 @@ export async function run(
|
|
|
77
77
|
|
|
78
78
|
try {
|
|
79
79
|
const provider = getMessagingProvider("gmail");
|
|
80
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
80
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
81
81
|
const message = await getMessage(token, messageId, "full");
|
|
82
82
|
const headers = message.payload?.headers ?? [];
|
|
83
83
|
const originalFrom = extractHeader(headers, "From");
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
batchModifyMessages,
|
|
3
|
+
modifyMessage,
|
|
4
|
+
} from "../../../../messaging/providers/gmail/client.js";
|
|
5
|
+
import { getMessagingProvider } from "../../../../messaging/registry.js";
|
|
6
|
+
import { withValidToken } from "../../../../security/token-manager.js";
|
|
7
|
+
import type {
|
|
8
|
+
ToolContext,
|
|
9
|
+
ToolExecutionResult,
|
|
10
|
+
} from "../../../../tools/types.js";
|
|
11
|
+
import { err, ok } from "./shared.js";
|
|
12
|
+
|
|
13
|
+
export async function run(
|
|
14
|
+
input: Record<string, unknown>,
|
|
15
|
+
_context: ToolContext,
|
|
16
|
+
): Promise<ToolExecutionResult> {
|
|
17
|
+
const messageId = input.message_id as string | undefined;
|
|
18
|
+
const messageIds = input.message_ids as string[] | undefined;
|
|
19
|
+
const addLabelIds = input.add_label_ids as string[] | undefined;
|
|
20
|
+
const removeLabelIds = input.remove_label_ids as string[] | undefined;
|
|
21
|
+
|
|
22
|
+
if (messageIds && messageIds.length > 0) {
|
|
23
|
+
try {
|
|
24
|
+
const provider = getMessagingProvider("gmail");
|
|
25
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
26
|
+
await batchModifyMessages(token, messageIds, {
|
|
27
|
+
addLabelIds,
|
|
28
|
+
removeLabelIds,
|
|
29
|
+
});
|
|
30
|
+
return ok(`Labels updated on ${messageIds.length} message(s).`);
|
|
31
|
+
});
|
|
32
|
+
} catch (e) {
|
|
33
|
+
return err(e instanceof Error ? e.message : String(e));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (messageId) {
|
|
38
|
+
try {
|
|
39
|
+
const provider = getMessagingProvider("gmail");
|
|
40
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
41
|
+
await modifyMessage(token, messageId, { addLabelIds, removeLabelIds });
|
|
42
|
+
return ok("Labels updated.");
|
|
43
|
+
});
|
|
44
|
+
} catch (e) {
|
|
45
|
+
return err(e instanceof Error ? e.message : String(e));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return err("Provide message_id or message_ids.");
|
|
50
|
+
}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import type { EmailMetadata } from "../../../../messaging/email-classifier.js";
|
|
2
|
-
import {
|
|
3
|
-
classifyOutreach,
|
|
4
|
-
type OutreachClassification,
|
|
5
|
-
} from "../../../../messaging/outreach-classifier.js";
|
|
6
1
|
import {
|
|
7
2
|
batchGetMessages,
|
|
8
3
|
listMessages,
|
|
@@ -31,8 +26,6 @@ interface OutreachSenderAggregation {
|
|
|
31
26
|
messageIds: string[];
|
|
32
27
|
hasMore: boolean;
|
|
33
28
|
sampleSubjects: string[];
|
|
34
|
-
outreachTypes: string[];
|
|
35
|
-
confidenceSum: number;
|
|
36
29
|
}
|
|
37
30
|
|
|
38
31
|
/** Parse "Display Name <email@example.com>" into parts. */
|
|
@@ -48,39 +41,6 @@ function parseFrom(from: string): { displayName: string; email: string } {
|
|
|
48
41
|
return { displayName: "", email: bare };
|
|
49
42
|
}
|
|
50
43
|
|
|
51
|
-
function buildSuggestedActions(email: string, count: number): string[] {
|
|
52
|
-
const actions: string[] = [`Archive all ${count} messages`];
|
|
53
|
-
if (count >= 2) {
|
|
54
|
-
actions.push(`Create filter to auto-archive future emails from ${email}`);
|
|
55
|
-
}
|
|
56
|
-
if (count >= 3) {
|
|
57
|
-
const domain = email.split("@")[1];
|
|
58
|
-
if (domain) {
|
|
59
|
-
actions.push(
|
|
60
|
-
`Create filter to auto-archive future emails from @${domain}`,
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return actions;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** Find the most common string in an array. */
|
|
68
|
-
function mostCommon(items: string[]): string {
|
|
69
|
-
const counts = new Map<string, number>();
|
|
70
|
-
for (const item of items) {
|
|
71
|
-
counts.set(item, (counts.get(item) ?? 0) + 1);
|
|
72
|
-
}
|
|
73
|
-
let best = items[0] ?? "other";
|
|
74
|
-
let bestCount = 0;
|
|
75
|
-
for (const [item, count] of counts) {
|
|
76
|
-
if (count > bestCount) {
|
|
77
|
-
best = item;
|
|
78
|
-
bestCount = count;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return best;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
44
|
export async function run(
|
|
85
45
|
input: Record<string, unknown>,
|
|
86
46
|
_context: ToolContext,
|
|
@@ -91,14 +51,13 @@ export async function run(
|
|
|
91
51
|
);
|
|
92
52
|
const maxSenders = (input.max_senders as number) ?? 30;
|
|
93
53
|
const timeRange = (input.time_range as string) ?? "90d";
|
|
94
|
-
const minConfidence = (input.min_confidence as number) ?? 0.5;
|
|
95
54
|
const inputPageToken = input.page_token as string | undefined;
|
|
96
55
|
|
|
97
56
|
const query = `in:inbox -has:unsubscribe newer_than:${timeRange}`;
|
|
98
57
|
|
|
99
58
|
try {
|
|
100
59
|
const provider = getMessagingProvider("gmail");
|
|
101
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
60
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
102
61
|
// Pipeline: fire metadata fetches for each page of IDs as they arrive
|
|
103
62
|
const allMessageIds: string[] = [];
|
|
104
63
|
const fetchPromises: Promise<GmailMessage[]>[] = [];
|
|
@@ -142,42 +101,17 @@ export async function run(
|
|
|
142
101
|
JSON.stringify({
|
|
143
102
|
senders: [],
|
|
144
103
|
total_scanned: 0,
|
|
145
|
-
|
|
146
|
-
message: "No emails found matching the query.",
|
|
104
|
+
note: "No emails found matching the query.",
|
|
147
105
|
}),
|
|
148
106
|
);
|
|
149
107
|
}
|
|
150
108
|
|
|
151
109
|
const messages = (await Promise.all(fetchPromises)).flat();
|
|
152
110
|
|
|
153
|
-
//
|
|
154
|
-
const emailMetadata: EmailMetadata[] = messages.map((msg) => {
|
|
155
|
-
const headers = msg.payload?.headers ?? [];
|
|
156
|
-
const from =
|
|
157
|
-
headers.find((h) => h.name.toLowerCase() === "from")?.value ?? "";
|
|
158
|
-
const subject =
|
|
159
|
-
headers.find((h) => h.name.toLowerCase() === "subject")?.value ?? "";
|
|
160
|
-
return { id: msg.id, from, subject, snippet: "", labels: [] };
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
// Classify in batches
|
|
164
|
-
const classifications = await classifyOutreach(emailMetadata);
|
|
165
|
-
|
|
166
|
-
// Index classifications by message ID
|
|
167
|
-
const classificationMap = new Map<string, OutreachClassification>();
|
|
168
|
-
for (const c of classifications) {
|
|
169
|
-
if (c.isOutreach) {
|
|
170
|
-
classificationMap.set(c.id, c);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Aggregate by sender email (only outreach-classified messages)
|
|
111
|
+
// Aggregate all fetched messages by sender
|
|
175
112
|
const senderMap = new Map<string, OutreachSenderAggregation>();
|
|
176
113
|
|
|
177
114
|
for (const msg of messages) {
|
|
178
|
-
const classification = classificationMap.get(msg.id);
|
|
179
|
-
if (!classification) continue;
|
|
180
|
-
|
|
181
115
|
const headers = msg.payload?.headers ?? [];
|
|
182
116
|
const fromHeader =
|
|
183
117
|
headers.find((h) => h.name.toLowerCase() === "from")?.value ?? "";
|
|
@@ -201,15 +135,11 @@ export async function run(
|
|
|
201
135
|
messageIds: [],
|
|
202
136
|
hasMore: false,
|
|
203
137
|
sampleSubjects: [],
|
|
204
|
-
outreachTypes: [],
|
|
205
|
-
confidenceSum: 0,
|
|
206
138
|
};
|
|
207
139
|
senderMap.set(email, agg);
|
|
208
140
|
}
|
|
209
141
|
|
|
210
142
|
agg.messageCount++;
|
|
211
|
-
agg.outreachTypes.push(classification.outreachType);
|
|
212
|
-
agg.confidenceSum += classification.confidence;
|
|
213
143
|
|
|
214
144
|
if (!agg.displayName && displayName) agg.displayName = displayName;
|
|
215
145
|
|
|
@@ -241,33 +171,21 @@ export async function run(
|
|
|
241
171
|
}
|
|
242
172
|
}
|
|
243
173
|
|
|
244
|
-
// Sort by message count desc,
|
|
245
|
-
const
|
|
246
|
-
.
|
|
247
|
-
|
|
248
|
-
avgConfidence:
|
|
249
|
-
s.messageCount > 0 ? s.confidenceSum / s.messageCount : 0,
|
|
250
|
-
outreachType: mostCommon(s.outreachTypes),
|
|
251
|
-
}))
|
|
252
|
-
.filter((s) => s.avgConfidence >= minConfidence)
|
|
253
|
-
.sort((a, b) => b.messageCount - a.messageCount);
|
|
254
|
-
|
|
255
|
-
const totalOutreachDetected = qualified.length;
|
|
256
|
-
const sorted = qualified.slice(0, maxSenders);
|
|
174
|
+
// Sort by message count desc, take top N
|
|
175
|
+
const sorted = [...senderMap.values()]
|
|
176
|
+
.sort((a, b) => b.messageCount - a.messageCount)
|
|
177
|
+
.slice(0, maxSenders);
|
|
257
178
|
|
|
258
179
|
const senders = sorted.map((s) => ({
|
|
259
180
|
id: Buffer.from(s.email).toString("base64url"),
|
|
260
181
|
display_name: s.displayName || s.email.split("@")[0],
|
|
261
182
|
email: s.email,
|
|
262
183
|
message_count: s.messageCount,
|
|
263
|
-
outreach_type: s.outreachType,
|
|
264
|
-
confidence: Math.round(s.avgConfidence * 100) / 100,
|
|
265
184
|
newest_message_id: s.newestMessageId,
|
|
266
185
|
oldest_date: s.oldestDate,
|
|
267
186
|
newest_date: s.newestDate,
|
|
268
187
|
search_query: `from:${s.email}`,
|
|
269
188
|
sample_subjects: s.sampleSubjects,
|
|
270
|
-
suggested_actions: buildSuggestedActions(s.email, s.messageCount),
|
|
271
189
|
}));
|
|
272
190
|
|
|
273
191
|
// Store message IDs server-side to keep them out of LLM context
|
|
@@ -285,9 +203,9 @@ export async function run(
|
|
|
285
203
|
scan_id: scanId,
|
|
286
204
|
senders,
|
|
287
205
|
total_scanned: allMessageIds.length,
|
|
288
|
-
outreach_detected: totalOutreachDetected,
|
|
289
206
|
...(truncated ? { truncated: true } : {}),
|
|
290
207
|
...(timeBudgetExceeded ? { time_budget_exceeded: true } : {}),
|
|
208
|
+
note: "Scanned inbox for senders without List-Unsubscribe headers (potential cold outreach). Use gmail_archive and gmail_filters for cleanup.",
|
|
291
209
|
}),
|
|
292
210
|
);
|
|
293
211
|
});
|
|
@@ -16,7 +16,7 @@ export async function run(
|
|
|
16
16
|
|
|
17
17
|
try {
|
|
18
18
|
const provider = getMessagingProvider("gmail");
|
|
19
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
19
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
20
20
|
const msg = await sendDraft(token, draftId);
|
|
21
21
|
return ok(`Draft sent (Message ID: ${msg.id}).`);
|
|
22
22
|
});
|
|
@@ -59,7 +59,7 @@ export async function run(
|
|
|
59
59
|
|
|
60
60
|
try {
|
|
61
61
|
const provider = getMessagingProvider("gmail");
|
|
62
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
62
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
63
63
|
// Pipeline: fire metadata fetches for each page of IDs as they arrive,
|
|
64
64
|
// overlapping fetch latency with pagination latency
|
|
65
65
|
const allMessageIds: string[] = [];
|
|
@@ -235,7 +235,7 @@ export async function run(
|
|
|
235
235
|
query_used: query,
|
|
236
236
|
...(truncated ? { truncated: true } : {}),
|
|
237
237
|
...(timeBudgetExceeded ? { time_budget_exceeded: true } : {}),
|
|
238
|
-
note: `message_count reflects emails found per sender within the ${allMessageIds.length} messages scanned. Use scan_id with
|
|
238
|
+
note: `message_count reflects emails found per sender within the ${allMessageIds.length} messages scanned. Use scan_id with gmail_archive to archive messages (pass scan_id + sender_ids instead of message_ids).`,
|
|
239
239
|
}),
|
|
240
240
|
);
|
|
241
241
|
});
|
|
@@ -19,7 +19,7 @@ export async function run(
|
|
|
19
19
|
|
|
20
20
|
try {
|
|
21
21
|
const provider = getMessagingProvider("gmail");
|
|
22
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
22
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
23
23
|
await trashMessage(token, messageId);
|
|
24
24
|
return ok("Message moved to trash.");
|
|
25
25
|
});
|
|
@@ -33,7 +33,7 @@ export async function run(
|
|
|
33
33
|
|
|
34
34
|
try {
|
|
35
35
|
const provider = getMessagingProvider("gmail");
|
|
36
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
36
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
37
37
|
const message = await getMessage(token, messageId, "metadata", [
|
|
38
38
|
"List-Unsubscribe",
|
|
39
39
|
"List-Unsubscribe-Post",
|
|
@@ -23,7 +23,7 @@ export async function run(
|
|
|
23
23
|
|
|
24
24
|
try {
|
|
25
25
|
const provider = getMessagingProvider("gmail");
|
|
26
|
-
return withValidToken(provider.credentialService, async (token) => {
|
|
26
|
+
return await withValidToken(provider.credentialService, async (token) => {
|
|
27
27
|
switch (action) {
|
|
28
28
|
case "get": {
|
|
29
29
|
const settings = await getVacation(token);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for gmail skill tools.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
request as httpsRequest,
|
|
7
|
+
type RequestOptions as HttpsRequestOptions,
|
|
8
|
+
} from "node:https";
|
|
9
|
+
|
|
10
|
+
import type { ToolExecutionResult } from "../../../../tools/types.js";
|
|
11
|
+
|
|
12
|
+
export function ok(content: string): ToolExecutionResult {
|
|
13
|
+
return { content, isError: false };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function err(message: string): ToolExecutionResult {
|
|
17
|
+
return { content: message, isError: true };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Make an HTTPS request pinned to a specific resolved IP to prevent DNS rebinding. */
|
|
21
|
+
export function pinnedHttpsRequest(
|
|
22
|
+
target: URL,
|
|
23
|
+
resolvedAddress: string,
|
|
24
|
+
options?: {
|
|
25
|
+
method?: string;
|
|
26
|
+
headers?: Record<string, string>;
|
|
27
|
+
body?: string;
|
|
28
|
+
},
|
|
29
|
+
): Promise<number> {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const reqOpts: HttpsRequestOptions = {
|
|
32
|
+
method: options?.method ?? "GET",
|
|
33
|
+
hostname: resolvedAddress,
|
|
34
|
+
port: target.port ? Number(target.port) : undefined,
|
|
35
|
+
path: `${target.pathname}${target.search}`,
|
|
36
|
+
headers: { host: target.host, ...options?.headers },
|
|
37
|
+
servername: target.hostname,
|
|
38
|
+
};
|
|
39
|
+
const req = httpsRequest(reqOpts, (res) => {
|
|
40
|
+
res.resume();
|
|
41
|
+
resolve(res.statusCode ?? 0);
|
|
42
|
+
});
|
|
43
|
+
req.once("error", reject);
|
|
44
|
+
if (options?.body) req.write(options.body);
|
|
45
|
+
req.end();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
name: google-calendar
|
|
3
3
|
description: View, create, and manage Google Calendar events and check availability
|
|
4
4
|
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
5
|
+
metadata:
|
|
6
|
+
emoji: "π
"
|
|
7
|
+
vellum:
|
|
8
|
+
display-name: "Google Calendar"
|
|
9
|
+
user-invocable: true
|
|
6
10
|
---
|
|
7
11
|
|
|
8
12
|
You are a Google Calendar assistant with full access to the user's calendar. Use the Calendar tools to help them view, create, and manage events.
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
name: image-studio
|
|
3
3
|
description: Generate and edit images using AI
|
|
4
4
|
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
5
|
+
metadata:
|
|
6
|
+
emoji: "π¨"
|
|
7
|
+
vellum:
|
|
8
|
+
display-name: "Image Studio"
|
|
9
|
+
user-invocable: true
|
|
6
10
|
---
|
|
7
11
|
|
|
8
12
|
You are an image generation assistant. When the user asks you to create or edit images, use the `media_generate_image` tool.
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
name: knowledge-graph
|
|
3
3
|
description: Query the entity knowledge graph to explore relationships between people, projects, tools, and other entities tracked in memory
|
|
4
4
|
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
5
|
+
metadata:
|
|
6
|
+
emoji: "πΈοΈ"
|
|
7
|
+
vellum:
|
|
8
|
+
display-name: "Knowledge Graph"
|
|
6
9
|
---
|
|
7
10
|
|
|
8
11
|
# Knowledge Graph
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
name: media-processing
|
|
3
3
|
description: "Ingest and process media files (video, audio, image) through a 3-phase pipeline: preprocess, map (Gemini), and reduce (Claude)"
|
|
4
4
|
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
5
|
+
metadata:
|
|
6
|
+
emoji: "π¬"
|
|
7
|
+
vellum:
|
|
8
|
+
display-name: "Media Processing"
|
|
6
9
|
---
|
|
7
10
|
|
|
8
11
|
Ingest and track processing of media files (video, audio, images) through a configurable 3-phase pipeline.
|
|
@@ -80,15 +83,6 @@ Parameters:
|
|
|
80
83
|
|
|
81
84
|
Extract a video clip from a media asset using ffmpeg. Applies configurable pre/post-roll padding (clamped to file boundaries), outputs the clip as a temporary file.
|
|
82
85
|
|
|
83
|
-
### media_diagnostics
|
|
84
|
-
|
|
85
|
-
Get a diagnostic report for a media asset. Returns:
|
|
86
|
-
|
|
87
|
-
- **Processing stats**: total keyframes extracted.
|
|
88
|
-
- **Per-stage status and timing**: which stages (preprocess, map, reduce) have run, how long each took, current progress.
|
|
89
|
-
- **Failure reasons**: last error from any failed stage.
|
|
90
|
-
- **Cost estimation**: based on segment count and current Gemini pricing.
|
|
91
|
-
|
|
92
86
|
## Services
|
|
93
87
|
|
|
94
88
|
### Processing Pipeline (services/processing-pipeline.ts)
|
|
@@ -240,7 +234,7 @@ The response includes per-stage progress (0-100%) so you can see exactly where p
|
|
|
240
234
|
|
|
241
235
|
### Diagnosing Failures
|
|
242
236
|
|
|
243
|
-
Use `
|
|
237
|
+
Use `media_status` to check processing stages:
|
|
244
238
|
|
|
245
239
|
1. Check the `stages` array for any stage with `status: "failed"`.
|
|
246
240
|
2. Read the `lastError` field for that stage to understand what went wrong.
|
|
@@ -254,7 +248,7 @@ After fixing the root cause, re-run the failed stage. The pipeline is resumable
|
|
|
254
248
|
|
|
255
249
|
### Cost Expectations
|
|
256
250
|
|
|
257
|
-
|
|
251
|
+
The Map phase (Gemini) is the primary cost driver β it scales with video duration and keyframe interval. The Q&A phase (Claude) is negligible per query.
|
|
258
252
|
|
|
259
253
|
### Known Limitations
|
|
260
254
|
|
|
@@ -272,7 +266,7 @@ Use `media_diagnostics` to get per-asset cost estimates. The Map phase (Gemini)
|
|
|
272
266
|
| "No LLM provider available" | API key not configured | Add one in Settings |
|
|
273
267
|
| Map phase slow | Large video, small interval | Increase interval_seconds or reduce concurrency |
|
|
274
268
|
| Gemini returns errors | Rate limits or schema issues | Check max_retries setting; simplify output_schema if needed |
|
|
275
|
-
| Pipeline stuck at "processing" | Stage crashed without updating status | Use `
|
|
269
|
+
| Pipeline stuck at "processing" | Stage crashed without updating status | Use `media_status` to check stage progress; re-run manually |
|
|
276
270
|
|
|
277
271
|
## Usage Notes
|
|
278
272
|
|
|
@@ -249,28 +249,6 @@
|
|
|
249
249
|
},
|
|
250
250
|
"executor": "tools/generate-clip.ts",
|
|
251
251
|
"execution_target": "host"
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
"name": "media_diagnostics",
|
|
255
|
-
"description": "Get a diagnostic report for a media asset including processing stats, per-stage timing (preprocess/map/reduce), failure reasons, and Gemini-based cost estimation.",
|
|
256
|
-
"category": "media",
|
|
257
|
-
"risk": "low",
|
|
258
|
-
"input_schema": {
|
|
259
|
-
"type": "object",
|
|
260
|
-
"properties": {
|
|
261
|
-
"asset_id": {
|
|
262
|
-
"type": "string",
|
|
263
|
-
"description": "ID of the media asset to diagnose"
|
|
264
|
-
},
|
|
265
|
-
"reason": {
|
|
266
|
-
"type": "string",
|
|
267
|
-
"description": "Brief non-technical explanation of why this tool is being called"
|
|
268
|
-
}
|
|
269
|
-
},
|
|
270
|
-
"required": ["asset_id"]
|
|
271
|
-
},
|
|
272
|
-
"executor": "tools/media-diagnostics.ts",
|
|
273
|
-
"execution_target": "host"
|
|
274
252
|
}
|
|
275
253
|
]
|
|
276
254
|
}
|
|
@@ -73,6 +73,8 @@ const MIME_BY_FORMAT: Record<string, string> = {
|
|
|
73
73
|
mov: "video/quicktime",
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
+
const ALLOWED_OUTPUT_FORMATS = new Set(Object.keys(MIME_BY_FORMAT));
|
|
77
|
+
|
|
76
78
|
// ---------------------------------------------------------------------------
|
|
77
79
|
// Tool entry point
|
|
78
80
|
// ---------------------------------------------------------------------------
|
|
@@ -105,7 +107,16 @@ export async function run(
|
|
|
105
107
|
|
|
106
108
|
const preRoll = (input.pre_roll as number) ?? 3;
|
|
107
109
|
const postRoll = (input.post_roll as number) ?? 2;
|
|
108
|
-
const
|
|
110
|
+
const outputFormatInput =
|
|
111
|
+
typeof input.output_format === "string" ? input.output_format : "mp4";
|
|
112
|
+
const outputFormat = outputFormatInput.toLowerCase();
|
|
113
|
+
if (!ALLOWED_OUTPUT_FORMATS.has(outputFormat)) {
|
|
114
|
+
return {
|
|
115
|
+
content:
|
|
116
|
+
"output_format must be one of: mp4, webm, mov (defaults to mp4).",
|
|
117
|
+
isError: true,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
109
120
|
const title = input.title as string | undefined;
|
|
110
121
|
|
|
111
122
|
const asset = getMediaAssetById(assetId);
|