@vellumai/assistant 0.4.49 → 0.4.51
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 +24 -33
- package/README.md +3 -3
- package/docs/architecture/integrations.md +2 -2
- package/docs/architecture/keychain-broker.md +6 -6
- package/docs/architecture/memory.md +180 -119
- package/knip.json +32 -0
- package/package.json +3 -2
- package/src/__tests__/agent-loop.test.ts +3 -1
- package/src/__tests__/anthropic-provider.test.ts +114 -23
- package/src/__tests__/approval-cascade.test.ts +1 -15
- package/src/__tests__/approval-routes-http.test.ts +2 -0
- package/src/__tests__/assistant-feature-flag-guard.test.ts +0 -23
- package/src/__tests__/btw-routes.test.ts +61 -5
- package/src/__tests__/canonical-guardian-store.test.ts +95 -0
- package/src/__tests__/checker.test.ts +13 -0
- package/src/__tests__/config-schema.test.ts +1 -68
- package/src/__tests__/config-watcher.test.ts +8 -0
- package/src/__tests__/context-memory-e2e.test.ts +11 -100
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +8 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/credential-security-e2e.test.ts +1 -0
- package/src/__tests__/credential-security-invariants.test.ts +8 -7
- package/src/__tests__/credential-vault-unit.test.ts +23 -18
- package/src/__tests__/credential-vault.test.ts +30 -18
- package/src/__tests__/credentials-cli.test.ts +257 -82
- package/src/__tests__/cu-unified-flow.test.ts +532 -0
- package/src/__tests__/date-context.test.ts +93 -77
- package/src/__tests__/deterministic-verification-control-plane.test.ts +64 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -0
- package/src/__tests__/history-repair.test.ts +245 -0
- package/src/__tests__/host-cu-proxy.test.ts +165 -3
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +36 -7
- package/src/__tests__/integration-status.test.ts +31 -30
- package/src/__tests__/invite-redemption-service.test.ts +166 -13
- package/src/__tests__/invite-routes-http.test.ts +166 -5
- package/src/__tests__/keychain-broker-client.test.ts +4 -4
- package/src/__tests__/list-messages-attachments.test.ts +193 -0
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +56 -18
- package/src/__tests__/memory-lifecycle-e2e.test.ts +244 -387
- package/src/__tests__/memory-recall-quality.test.ts +244 -407
- package/src/__tests__/memory-regressions.experimental.test.ts +126 -101
- package/src/__tests__/memory-regressions.test.ts +477 -2841
- package/src/__tests__/memory-retrieval.benchmark.test.ts +33 -150
- package/src/__tests__/memory-upsert-concurrency.test.ts +5 -244
- package/src/__tests__/mime-builder.test.ts +28 -0
- package/src/__tests__/native-web-search.test.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +824 -31
- package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +363 -17
- package/src/__tests__/qdrant-collection-migration.test.ts +53 -8
- package/src/__tests__/registry.test.ts +0 -1
- package/src/__tests__/relay-server.test.ts +55 -1
- package/src/__tests__/schedule-tools.test.ts +32 -0
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/secret-onetime-send.test.ts +1 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +183 -0
- package/src/__tests__/secure-keys.test.ts +78 -18
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/server-history-render.test.ts +2 -2
- package/src/__tests__/session-abort-tool-results.test.ts +1 -14
- package/src/__tests__/session-agent-loop-overflow.test.ts +1583 -0
- package/src/__tests__/session-agent-loop.test.ts +19 -15
- package/src/__tests__/session-confirmation-signals.test.ts +1 -15
- package/src/__tests__/session-error.test.ts +124 -2
- package/src/__tests__/session-history-web-search.test.ts +918 -0
- package/src/__tests__/session-pre-run-repair.test.ts +1 -14
- package/src/__tests__/session-provider-retry-repair.test.ts +25 -28
- package/src/__tests__/session-queue.test.ts +37 -27
- package/src/__tests__/session-runtime-assembly.test.ts +54 -0
- package/src/__tests__/session-slash-known.test.ts +1 -15
- package/src/__tests__/session-slash-queue.test.ts +1 -15
- package/src/__tests__/session-slash-unknown.test.ts +1 -15
- package/src/__tests__/session-workspace-cache-state.test.ts +3 -33
- package/src/__tests__/session-workspace-injection.test.ts +3 -37
- package/src/__tests__/session-workspace-tool-tracking.test.ts +3 -37
- package/src/__tests__/skills-install-extract.test.ts +93 -0
- package/src/__tests__/skills.test.ts +2 -2
- package/src/__tests__/skillssh-registry.test.ts +451 -0
- package/src/__tests__/slack-channel-config.test.ts +10 -8
- package/src/__tests__/trust-store.test.ts +15 -0
- package/src/__tests__/twilio-config.test.ts +11 -10
- package/src/__tests__/twilio-provider.test.ts +9 -4
- package/src/__tests__/voice-invite-redemption.test.ts +85 -5
- package/src/agent/ax-tree-compaction.test.ts +51 -0
- package/src/agent/loop.ts +39 -12
- package/src/approvals/AGENTS.md +1 -1
- package/src/approvals/guardian-request-resolvers.ts +14 -2
- package/src/bundler/compiler-tools.ts +66 -2
- package/src/calls/call-domain.ts +134 -3
- package/src/calls/call-store.ts +6 -0
- package/src/calls/relay-server.ts +44 -6
- package/src/calls/relay-setup-router.ts +17 -1
- package/src/calls/twilio-config.ts +5 -4
- package/src/calls/twilio-provider.ts +14 -9
- package/src/calls/twilio-rest.ts +10 -7
- package/src/calls/types.ts +3 -1
- package/src/cli/commands/config.ts +14 -9
- package/src/cli/commands/contacts.ts +3 -0
- package/src/cli/commands/credentials.ts +170 -174
- package/src/cli/commands/doctor.ts +11 -8
- package/src/cli/commands/keys.ts +9 -9
- package/src/cli/commands/mcp.ts +46 -59
- package/src/cli/commands/memory.ts +16 -165
- package/src/cli/commands/oauth/apps.ts +68 -10
- package/src/cli/commands/oauth/connections.ts +475 -105
- package/src/cli/commands/oauth/index.ts +3 -3
- package/src/cli/commands/oauth/providers.ts +18 -4
- package/src/cli/commands/sessions.ts +5 -2
- package/src/cli/commands/skills.ts +173 -1
- package/src/cli/http-client.ts +0 -20
- package/src/cli/main-screen.tsx +2 -2
- package/src/cli/program.ts +5 -6
- package/src/cli.ts +20 -22
- package/src/config/__tests__/feature-flag-registry-bundled.test.ts +39 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +1 -1
- package/src/config/bundled-skills/computer-use/tools/computer-use-observe.ts +12 -0
- package/src/config/bundled-skills/contacts/SKILL.md +35 -11
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +1 -1
- package/src/config/bundled-skills/gmail/SKILL.md +1 -1
- package/src/config/bundled-skills/gmail/TOOLS.json +52 -0
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +13 -3
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +9 -2
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +9 -2
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +5 -1
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +5 -1
- package/src/config/bundled-skills/google-calendar/TOOLS.json +20 -0
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +2 -1
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +8 -2
- package/src/config/bundled-skills/messaging/SKILL.md +1 -1
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/shared.ts +7 -5
- package/src/config/bundled-skills/slack/tools/shared.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +1 -1
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +1 -1
- package/src/config/bundled-tool-registry.ts +2 -5
- package/src/config/loader.ts +6 -42
- package/src/config/schema.ts +1 -12
- package/src/config/schemas/memory-lifecycle.ts +0 -9
- package/src/config/schemas/memory-processing.ts +0 -180
- package/src/config/schemas/memory-retrieval.ts +32 -104
- package/src/config/schemas/memory.ts +0 -10
- package/src/config/types.ts +0 -4
- package/src/contacts/contact-store.ts +39 -2
- package/src/contacts/contacts-write.ts +9 -0
- package/src/context/window-manager.ts +4 -1
- package/src/daemon/config-watcher.ts +55 -2
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/date-context.ts +114 -31
- package/src/daemon/handlers/config-ingress.ts +2 -2
- package/src/daemon/handlers/config-slack-channel.ts +59 -39
- package/src/daemon/handlers/config-telegram.ts +23 -14
- package/src/daemon/handlers/session-history.ts +1 -358
- package/src/daemon/handlers/sessions.ts +18 -13
- package/src/daemon/handlers/shared.ts +3 -17
- package/src/daemon/handlers/skills.ts +20 -1
- package/src/daemon/history-repair.ts +72 -8
- package/src/daemon/host-cu-proxy.ts +55 -26
- package/src/daemon/lifecycle.ts +39 -4
- package/src/daemon/mcp-reload-service.ts +2 -2
- package/src/daemon/message-types/computer-use.ts +1 -12
- package/src/daemon/message-types/memory.ts +4 -16
- package/src/daemon/message-types/messages.ts +1 -0
- package/src/daemon/message-types/sessions.ts +4 -42
- package/src/daemon/server.ts +6 -1
- package/src/daemon/session-agent-loop-handlers.ts +38 -0
- package/src/daemon/session-agent-loop.ts +334 -48
- package/src/daemon/session-error.ts +89 -6
- package/src/daemon/session-history.ts +17 -7
- package/src/daemon/session-media-retry.ts +6 -2
- package/src/daemon/session-memory.ts +69 -149
- package/src/daemon/session-process.ts +10 -1
- package/src/daemon/session-runtime-assembly.ts +49 -19
- package/src/daemon/session-slash.ts +3 -5
- package/src/daemon/session-surfaces.ts +4 -1
- package/src/daemon/session-tool-setup.ts +7 -1
- package/src/daemon/session.ts +12 -2
- package/src/email/providers/index.ts +2 -2
- package/src/instrument.ts +61 -1
- package/src/media/avatar-router.ts +1 -1
- package/src/memory/admin.ts +2 -191
- package/src/memory/canonical-guardian-store.ts +38 -2
- package/src/memory/conversation-crud.ts +0 -33
- package/src/memory/conversation-queries.ts +25 -83
- package/src/memory/db-init.ts +32 -0
- package/src/memory/embedding-backend.ts +84 -8
- package/src/memory/embedding-types.ts +9 -1
- package/src/memory/indexer.ts +7 -46
- package/src/memory/invite-store.ts +19 -0
- package/src/memory/items-extractor.ts +274 -76
- package/src/memory/job-handlers/backfill.ts +2 -127
- package/src/memory/job-handlers/cleanup.ts +2 -16
- package/src/memory/job-handlers/extraction.ts +2 -138
- package/src/memory/job-handlers/index-maintenance.ts +1 -6
- package/src/memory/job-handlers/summarization.ts +3 -148
- package/src/memory/job-utils.ts +21 -59
- package/src/memory/jobs-store.ts +1 -159
- package/src/memory/jobs-worker.ts +9 -52
- package/src/memory/migrations/104-core-indexes.ts +3 -3
- package/src/memory/migrations/149-oauth-tables.ts +2 -0
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +98 -0
- package/src/memory/migrations/151-oauth-providers-ping-url.ts +11 -0
- package/src/memory/migrations/152-memory-item-supersession.ts +44 -0
- package/src/memory/migrations/153-drop-entity-tables.ts +15 -0
- package/src/memory/migrations/154-drop-fts.ts +20 -0
- package/src/memory/migrations/155-drop-conflicts.ts +7 -0
- package/src/memory/migrations/156-call-session-invite-metadata.ts +24 -0
- package/src/memory/migrations/157-invite-contact-id.ts +104 -0
- package/src/memory/migrations/index.ts +8 -0
- package/src/memory/migrations/registry.ts +6 -0
- package/src/memory/qdrant-client.ts +148 -51
- package/src/memory/raw-query.ts +1 -1
- package/src/memory/retriever.test.ts +294 -273
- package/src/memory/retriever.ts +421 -645
- package/src/memory/schema/calls.ts +2 -0
- package/src/memory/schema/contacts.ts +1 -0
- package/src/memory/schema/memory-core.ts +3 -48
- package/src/memory/schema/oauth.ts +2 -0
- package/src/memory/search/formatting.ts +263 -176
- package/src/memory/search/lexical.ts +1 -254
- package/src/memory/search/ranking.ts +0 -455
- package/src/memory/search/semantic.ts +100 -14
- package/src/memory/search/staleness.ts +47 -0
- package/src/memory/search/tier-classifier.ts +21 -0
- package/src/memory/search/types.ts +15 -77
- package/src/memory/task-memory-cleanup.ts +4 -6
- package/src/messaging/provider.ts +1 -1
- package/src/messaging/providers/gmail/adapter.ts +1 -1
- package/src/messaging/providers/gmail/mime-builder.ts +17 -7
- package/src/messaging/providers/telegram-bot/adapter.ts +17 -8
- package/src/messaging/providers/whatsapp/adapter.ts +13 -9
- package/src/messaging/registry.ts +9 -5
- package/src/oauth/byo-connection.test.ts +40 -25
- package/src/oauth/connect-orchestrator.ts +4 -10
- package/src/oauth/connection-resolver.ts +20 -6
- package/src/oauth/manual-token-connection.ts +5 -5
- package/src/oauth/oauth-store.ts +183 -31
- package/src/oauth/platform-connection.test.ts +1 -1
- package/src/oauth/provider-behaviors.ts +503 -4
- package/src/oauth/seed-providers.ts +214 -8
- package/src/oauth/token-persistence.ts +31 -16
- package/src/permissions/defaults.ts +1 -0
- package/src/permissions/trust-store.ts +23 -1
- package/src/playbooks/playbook-compiler.ts +1 -1
- package/src/prompts/system-prompt.ts +18 -2
- package/src/providers/anthropic/client.ts +56 -126
- package/src/providers/types.ts +7 -1
- package/src/runtime/AGENTS.md +9 -0
- package/src/runtime/auth/route-policy.ts +6 -3
- package/src/runtime/channel-readiness-service.ts +48 -40
- package/src/runtime/guardian-reply-router.ts +24 -22
- package/src/runtime/http-server.ts +2 -2
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/invite-redemption-service.ts +72 -12
- package/src/runtime/invite-service.ts +43 -0
- package/src/runtime/middleware/twilio-validation.ts +1 -1
- package/src/runtime/pending-interactions.ts +2 -2
- package/src/runtime/routes/brain-graph-routes.ts +10 -90
- package/src/runtime/routes/btw-routes.ts +10 -5
- package/src/runtime/routes/conversation-routes.ts +56 -11
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -12
- package/src/runtime/routes/integrations/slack/channel.ts +2 -2
- package/src/runtime/routes/integrations/telegram.ts +2 -2
- package/src/runtime/routes/integrations/twilio.ts +17 -17
- package/src/runtime/routes/invite-routes.ts +29 -4
- package/src/runtime/routes/memory-item-routes.test.ts +754 -0
- package/src/runtime/routes/memory-item-routes.ts +503 -0
- package/src/runtime/routes/secret-routes.ts +17 -0
- package/src/runtime/routes/session-management-routes.ts +3 -3
- package/src/runtime/routes/settings-routes.ts +3 -3
- package/src/runtime/routes/trust-rules-routes.ts +14 -0
- package/src/runtime/routes/workspace-routes.ts +9 -4
- package/src/runtime/routes/workspace-utils.ts +8 -2
- package/src/schedule/integration-status.ts +26 -19
- package/src/security/keychain-broker-client.ts +17 -4
- package/src/security/oauth2.ts +6 -7
- package/src/security/secure-keys.ts +44 -19
- package/src/security/token-manager.ts +46 -39
- package/src/services/vercel-deploy.ts +0 -24
- package/src/signals/confirm.ts +78 -0
- package/src/signals/mcp-reload.ts +18 -0
- package/src/skills/catalog-install.ts +74 -18
- package/src/skills/skillssh-registry.ts +503 -0
- package/src/tools/assets/search.ts +5 -1
- package/src/tools/computer-use/definitions.ts +0 -10
- package/src/tools/computer-use/registry.ts +1 -1
- package/src/tools/credentials/vault.ts +22 -7
- package/src/tools/memory/definitions.ts +4 -13
- package/src/tools/memory/handlers.test.ts +83 -103
- package/src/tools/memory/handlers.ts +50 -85
- package/src/tools/network/script-proxy/session-manager.ts +8 -8
- package/src/tools/schedule/create.ts +10 -3
- package/src/tools/schedule/update.ts +8 -1
- package/src/tools/skills/load.ts +25 -2
- package/src/watcher/provider-types.ts +1 -1
- package/src/watcher/providers/github.ts +1 -1
- package/src/watcher/providers/gmail.ts +3 -3
- package/src/watcher/providers/google-calendar.ts +3 -3
- package/src/watcher/providers/linear.ts +1 -1
- package/src/__tests__/clarification-resolver.test.ts +0 -193
- package/src/__tests__/conflict-intent-tokenization.test.ts +0 -160
- package/src/__tests__/conflict-policy.test.ts +0 -269
- package/src/__tests__/conflict-store.test.ts +0 -372
- package/src/__tests__/contradiction-checker.test.ts +0 -361
- package/src/__tests__/entity-extractor.test.ts +0 -211
- package/src/__tests__/entity-search.test.ts +0 -1117
- package/src/__tests__/profile-compiler.test.ts +0 -392
- package/src/__tests__/session-conflict-gate.test.ts +0 -1228
- package/src/__tests__/session-profile-injection.test.ts +0 -557
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +0 -25
- package/src/config/bundled-skills/knowledge-graph/TOOLS.json +0 -66
- package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +0 -211
- package/src/daemon/session-conflict-gate.ts +0 -167
- package/src/daemon/session-dynamic-profile.ts +0 -77
- package/src/memory/clarification-resolver.ts +0 -417
- package/src/memory/conflict-intent.ts +0 -205
- package/src/memory/conflict-policy.ts +0 -127
- package/src/memory/conflict-store.ts +0 -410
- package/src/memory/contradiction-checker.ts +0 -508
- package/src/memory/entity-extractor.ts +0 -535
- package/src/memory/format-recall.ts +0 -47
- package/src/memory/fts-reconciler.ts +0 -165
- package/src/memory/job-handlers/conflict.ts +0 -200
- package/src/memory/profile-compiler.ts +0 -195
- package/src/memory/recall-cache.ts +0 -117
- package/src/memory/search/entity.ts +0 -535
- package/src/memory/search/query-expansion.test.ts +0 -70
- package/src/memory/search/query-expansion.ts +0 -118
- package/src/runtime/routes/mcp-routes.ts +0 -20
|
@@ -168,6 +168,8 @@ Replace `<channel_id>` with the channel's `id` from the contact's `channels` arr
|
|
|
168
168
|
|
|
169
169
|
Invite links let the guardian share a link or code that automatically grants access when used. Telegram invites use a deep link; voice invites use a phone number + numeric code; email, WhatsApp, and Slack invites use a 6-digit code that the invitee sends to the assistant on the respective channel.
|
|
170
170
|
|
|
171
|
+
**Every invite must be bound to a contact.** Before creating an invite, look up the contact with `assistant contacts list` or create one with `assistant contacts upsert`, then pass the contact's `id` via the required `--contact-id` flag.
|
|
172
|
+
|
|
171
173
|
### Create a Telegram invite link
|
|
172
174
|
|
|
173
175
|
Use this when the guardian wants to invite someone to message the assistant on Telegram without needing their user ID upfront. The invite link is a shareable Telegram deep link -- when someone opens it, they automatically get trusted-contact access.
|
|
@@ -175,7 +177,7 @@ Use this when the guardian wants to invite someone to message the assistant on T
|
|
|
175
177
|
**Important**: The shell snippet below emits a `<vellum-sensitive-output>` directive containing the raw invite token. The tool executor automatically strips this directive and replaces the raw token with a placeholder so the LLM never sees it. The placeholder is resolved back to the real token in the final assistant reply.
|
|
176
178
|
|
|
177
179
|
```bash
|
|
178
|
-
INVITE_JSON=$(assistant contacts invites create --source-channel telegram --max-uses 1 --note "<optional note, e.g. the person it is for>" --json)
|
|
180
|
+
INVITE_JSON=$(assistant contacts invites create --source-channel telegram --contact-id "<contact_id>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json)
|
|
179
181
|
|
|
180
182
|
INVITE_TOKEN=$(printf '%s' "$INVITE_JSON" | python3 -c "
|
|
181
183
|
import json, sys
|
|
@@ -210,6 +212,11 @@ echo "<vellum-sensitive-output kind=\"invite_code\" value=\"$INVITE_TOKEN\" />"
|
|
|
210
212
|
echo "$INVITE_URL"
|
|
211
213
|
```
|
|
212
214
|
|
|
215
|
+
Required flags:
|
|
216
|
+
|
|
217
|
+
- `--source-channel` -- must be `telegram`
|
|
218
|
+
- `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
|
|
219
|
+
|
|
213
220
|
Optional flags:
|
|
214
221
|
|
|
215
222
|
- `--max-uses` -- how many times the link can be used (default: 1). Use a higher number for group invites.
|
|
@@ -242,12 +249,13 @@ Use this when the guardian wants to authorize a specific phone number to call th
|
|
|
242
249
|
**Important**: The response includes a `voiceCode` field that is only returned at creation time and cannot be retrieved later. Extract and present it clearly.
|
|
243
250
|
|
|
244
251
|
```bash
|
|
245
|
-
assistant contacts invites create --source-channel phone --expected-external-user-id "<phone_E164>" --friend-name "<invitee_name>" --guardian-name "<guardian_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
|
|
252
|
+
assistant contacts invites create --source-channel phone --contact-id "<contact_id>" --expected-external-user-id "<phone_E164>" --friend-name "<invitee_name>" --guardian-name "<guardian_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
|
|
246
253
|
```
|
|
247
254
|
|
|
248
255
|
Required flags:
|
|
249
256
|
|
|
250
257
|
- `--source-channel` -- must be `phone`
|
|
258
|
+
- `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
|
|
251
259
|
- `--expected-external-user-id` -- the invitee's phone number in E.164 format (e.g., `+15551234567`)
|
|
252
260
|
- `--friend-name` -- the invitee's display name (e.g., "Mom", "Dr. Smith"). Used during the voice verification call to personalize the experience.
|
|
253
261
|
- `--guardian-name` -- the guardian's display name (e.g., "Alex"). Used during the voice verification call so the invitee knows who invited them.
|
|
@@ -287,9 +295,14 @@ If the user provides a phone number without the `+` country code prefix, ask the
|
|
|
287
295
|
Use this when the guardian wants to invite someone to message the assistant via email. Email invites use a 6-digit code — the invitee sends the code to the assistant's email address to redeem access.
|
|
288
296
|
|
|
289
297
|
```bash
|
|
290
|
-
assistant contacts invites create --source-channel email --contact-name "<invitee_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
|
|
298
|
+
assistant contacts invites create --source-channel email --contact-id "<contact_id>" --contact-name "<invitee_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
|
|
291
299
|
```
|
|
292
300
|
|
|
301
|
+
Required flags:
|
|
302
|
+
|
|
303
|
+
- `--source-channel` -- must be `email`
|
|
304
|
+
- `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
|
|
305
|
+
|
|
293
306
|
The response contains `{ ok: true, invite: { id, token, inviteCode, guardianInstruction, channelHandle, ... } }`.
|
|
294
307
|
|
|
295
308
|
- `inviteCode` is the 6-digit code the invitee must send to redeem the invite. It is only returned at creation time.
|
|
@@ -313,9 +326,14 @@ If the assistant's email address is not available (AgentMail not configured), te
|
|
|
313
326
|
Use this when the guardian wants to invite someone to message the assistant on WhatsApp. WhatsApp invites use a 6-digit code — the invitee sends the code to the assistant's WhatsApp number to redeem access.
|
|
314
327
|
|
|
315
328
|
```bash
|
|
316
|
-
assistant contacts invites create --source-channel whatsapp --contact-name "<invitee_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
|
|
329
|
+
assistant contacts invites create --source-channel whatsapp --contact-id "<contact_id>" --contact-name "<invitee_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
|
|
317
330
|
```
|
|
318
331
|
|
|
332
|
+
Required flags:
|
|
333
|
+
|
|
334
|
+
- `--source-channel` -- must be `whatsapp`
|
|
335
|
+
- `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
|
|
336
|
+
|
|
319
337
|
The response contains `{ ok: true, invite: { id, token, inviteCode, guardianInstruction, channelHandle?, ... } }`.
|
|
320
338
|
|
|
321
339
|
- `inviteCode` is the 6-digit code the invitee must send to redeem the invite.
|
|
@@ -341,9 +359,14 @@ If the assistant's WhatsApp integration is not configured at all (Meta WhatsApp
|
|
|
341
359
|
Use this when the guardian wants to invite someone to message the assistant on Slack. Slack invites use a 6-digit code -- the invitee sends the code as a direct message to the assistant's Slack bot to redeem access.
|
|
342
360
|
|
|
343
361
|
```bash
|
|
344
|
-
assistant contacts invites create --source-channel slack --contact-name "<invitee_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
|
|
362
|
+
assistant contacts invites create --source-channel slack --contact-id "<contact_id>" --contact-name "<invitee_name>" --max-uses 1 --note "<optional note, e.g. the person it is for>" --json
|
|
345
363
|
```
|
|
346
364
|
|
|
365
|
+
Required flags:
|
|
366
|
+
|
|
367
|
+
- `--source-channel` -- must be `slack`
|
|
368
|
+
- `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
|
|
369
|
+
|
|
347
370
|
The response follows the same shape as email and WhatsApp invites (`inviteCode`, `guardianInstruction`, `channelHandle`).
|
|
348
371
|
|
|
349
372
|
**Presenting to the guardian**: Give the guardian the invite code and instructions for the invitee to send the code as a DM to the assistant's Slack bot.
|
|
@@ -456,6 +479,7 @@ Each channel has:
|
|
|
456
479
|
- `Channel already blocked` -- the channel has already been blocked.
|
|
457
480
|
- `Cannot revoke a blocked channel` -- the channel is blocked; blocking is stronger than revoking. Tell the user the contact is already blocked.
|
|
458
481
|
- `sourceChannel is required for create` -- when creating an invite, always pass `--source-channel`.
|
|
482
|
+
- `contactId is required for create` -- when creating an invite, always pass `--contact-id`. Look up or create the contact first.
|
|
459
483
|
- `expectedExternalUserId is required for voice invites` -- voice invites must include the invitee's phone number via `--expected-external-user-id`.
|
|
460
484
|
- `expectedExternalUserId must be in E.164 format` -- the phone number must start with `+` followed by country code and number (e.g., `+15551234567`).
|
|
461
485
|
- `friendName is required for voice invites` -- voice invites must include the invitee's display name via `--friend-name`.
|
|
@@ -480,21 +504,21 @@ Each channel has:
|
|
|
480
504
|
|
|
481
505
|
**"Show me blocked contacts"** -- List contacts with `assistant contacts list --json` and filter for channels with `status: "blocked"`.
|
|
482
506
|
|
|
483
|
-
**"Create a Telegram invite link"** / **"Invite someone on Telegram"** --
|
|
507
|
+
**"Create a Telegram invite link"** / **"Invite someone on Telegram"** -- Look up or create the contact first, then create an invite with `assistant contacts invites create --source-channel telegram --contact-id <contact_id>`, look up the bot username, build the deep link, and present it with sharing instructions.
|
|
484
508
|
|
|
485
|
-
**"Invite someone by email"** / **"Send an email invite"** --
|
|
509
|
+
**"Invite someone by email"** / **"Send an email invite"** -- Look up or create the contact first, then create an invite with `assistant contacts invites create --source-channel email --contact-id <contact_id>`. Present the 6-digit invite code and the assistant's email address. Tell the guardian to share both with the invitee.
|
|
486
510
|
|
|
487
|
-
**"Invite someone on WhatsApp"** --
|
|
511
|
+
**"Invite someone on WhatsApp"** -- Look up or create the contact first, then create an invite with `assistant contacts invites create --source-channel whatsapp --contact-id <contact_id>`. Present the 6-digit invite code. If `channelHandle` is returned, also present the assistant's WhatsApp number; otherwise, tell the guardian to share the code and instruct the invitee to send it to the assistant on WhatsApp.
|
|
488
512
|
|
|
489
|
-
**"Invite someone on Slack"** --
|
|
513
|
+
**"Invite someone on Slack"** -- Look up or create the contact first, then create an invite with `assistant contacts invites create --source-channel slack --contact-id <contact_id>`. Present the 6-digit invite code and tell the guardian to have the invitee DM the code to the assistant's Slack bot.
|
|
490
514
|
|
|
491
515
|
**"Show my invites"** / **"List active invite links"** -- List invites with `assistant contacts invites list --source-channel telegram --json`, present active invites with uses remaining and expiration info. Use the appropriate `--source-channel` value for other channels.
|
|
492
516
|
|
|
493
517
|
**"Revoke invite"** / **"Cancel invite link"** -- List invites to identify the target, confirm, then revoke with `assistant contacts invites revoke <invite_id> --json`.
|
|
494
518
|
|
|
495
|
-
**"Create a voice invite for +15551234567"** --
|
|
519
|
+
**"Create a voice invite for +15551234567"** -- Look up or create the contact first, then create a voice invite with `assistant contacts invites create --source-channel phone --contact-id <contact_id> --expected-external-user-id "+15551234567" --friend-name "<name>" --guardian-name "<name>"`. Present the invite code and instructions: the person must call from that number and enter the code.
|
|
496
520
|
|
|
497
|
-
**"Let my mom call in"** / **"Invite someone by phone"** -- Ask for the phone number in E.164 format, create a voice invite with `assistant contacts invites create --source-channel phone
|
|
521
|
+
**"Let my mom call in"** / **"Invite someone by phone"** -- Ask for the phone number in E.164 format, look up or create the contact first, then create a voice invite with `assistant contacts invites create --source-channel phone --contact-id <contact_id>`, and present the code + calling instructions.
|
|
498
522
|
|
|
499
523
|
**"Show my voice invites"** / **"List phone invites"** -- List invites with `assistant contacts invites list --source-channel phone --json`, present active invites with bound phone number and expiration info.
|
|
500
524
|
|
|
@@ -43,7 +43,7 @@ export async function run(
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
try {
|
|
46
|
-
const connection = resolveOAuthConnection("integration:
|
|
46
|
+
const connection = await resolveOAuthConnection("integration:google");
|
|
47
47
|
switch (action) {
|
|
48
48
|
case "list": {
|
|
49
49
|
const pageSize = (input.page_size as number) ?? 50;
|
|
@@ -21,7 +21,7 @@ Do not offer AgentMail as an option or mention it unless the user specifically a
|
|
|
21
21
|
## Communication Style
|
|
22
22
|
|
|
23
23
|
- **Be action-oriented.** When the user asks to do something ("declutter", "check my email"), start doing it immediately. Don't ask for permission to read their inbox — that's obviously what they want.
|
|
24
|
-
- **Keep it human.** Never mention OAuth, tokens, APIs, sandboxes, credential proxies, or other technical internals. If something isn't working, say "Gmail needs to be reconnected" — not "the OAuth2 access token for integration:
|
|
24
|
+
- **Keep it human.** Never mention OAuth, tokens, APIs, sandboxes, credential proxies, or other technical internals. If something isn't working, say "Gmail needs to be reconnected" — not "the OAuth2 access token for integration:google has expired."
|
|
25
25
|
- **Show progress.** When running a tool that scans many emails, tell the user what you're doing: "Scanning your inbox for clutter..." Don't go silent.
|
|
26
26
|
- **Be brief and warm.** One or two sentences per update is plenty. Don't over-explain what you're about to do — just do it and narrate lightly.
|
|
27
27
|
|
|
@@ -42,6 +42,10 @@
|
|
|
42
42
|
"reason": {
|
|
43
43
|
"type": "string",
|
|
44
44
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
45
|
+
},
|
|
46
|
+
"account": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
45
49
|
}
|
|
46
50
|
},
|
|
47
51
|
"required": ["confidence"]
|
|
@@ -89,6 +93,10 @@
|
|
|
89
93
|
"reason": {
|
|
90
94
|
"type": "string",
|
|
91
95
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
96
|
+
},
|
|
97
|
+
"account": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
92
100
|
}
|
|
93
101
|
},
|
|
94
102
|
"required": ["confidence"]
|
|
@@ -115,6 +123,10 @@
|
|
|
115
123
|
"reason": {
|
|
116
124
|
"type": "string",
|
|
117
125
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
126
|
+
},
|
|
127
|
+
"account": {
|
|
128
|
+
"type": "string",
|
|
129
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
118
130
|
}
|
|
119
131
|
},
|
|
120
132
|
"required": ["message_id", "confidence"]
|
|
@@ -141,6 +153,10 @@
|
|
|
141
153
|
"reason": {
|
|
142
154
|
"type": "string",
|
|
143
155
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
156
|
+
},
|
|
157
|
+
"account": {
|
|
158
|
+
"type": "string",
|
|
159
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
144
160
|
}
|
|
145
161
|
},
|
|
146
162
|
"required": ["message_id", "confidence"]
|
|
@@ -183,6 +199,10 @@
|
|
|
183
199
|
"reason": {
|
|
184
200
|
"type": "string",
|
|
185
201
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
202
|
+
},
|
|
203
|
+
"account": {
|
|
204
|
+
"type": "string",
|
|
205
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
186
206
|
}
|
|
187
207
|
},
|
|
188
208
|
"required": ["to", "subject", "body"]
|
|
@@ -209,6 +229,10 @@
|
|
|
209
229
|
"reason": {
|
|
210
230
|
"type": "string",
|
|
211
231
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
232
|
+
},
|
|
233
|
+
"account": {
|
|
234
|
+
"type": "string",
|
|
235
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
212
236
|
}
|
|
213
237
|
},
|
|
214
238
|
"required": ["draft_id", "confidence"]
|
|
@@ -244,6 +268,10 @@
|
|
|
244
268
|
"reason": {
|
|
245
269
|
"type": "string",
|
|
246
270
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
271
|
+
},
|
|
272
|
+
"account": {
|
|
273
|
+
"type": "string",
|
|
274
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
247
275
|
}
|
|
248
276
|
},
|
|
249
277
|
"required": ["action", "message_id"]
|
|
@@ -278,6 +306,10 @@
|
|
|
278
306
|
"reason": {
|
|
279
307
|
"type": "string",
|
|
280
308
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
309
|
+
},
|
|
310
|
+
"account": {
|
|
311
|
+
"type": "string",
|
|
312
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
281
313
|
}
|
|
282
314
|
},
|
|
283
315
|
"required": ["message_id", "to", "confidence"]
|
|
@@ -309,6 +341,10 @@
|
|
|
309
341
|
"reason": {
|
|
310
342
|
"type": "string",
|
|
311
343
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
344
|
+
},
|
|
345
|
+
"account": {
|
|
346
|
+
"type": "string",
|
|
347
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
312
348
|
}
|
|
313
349
|
},
|
|
314
350
|
"required": ["action", "confidence"]
|
|
@@ -378,6 +414,10 @@
|
|
|
378
414
|
"reason": {
|
|
379
415
|
"type": "string",
|
|
380
416
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
417
|
+
},
|
|
418
|
+
"account": {
|
|
419
|
+
"type": "string",
|
|
420
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
381
421
|
}
|
|
382
422
|
},
|
|
383
423
|
"required": ["action", "confidence"]
|
|
@@ -429,6 +469,10 @@
|
|
|
429
469
|
"reason": {
|
|
430
470
|
"type": "string",
|
|
431
471
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
472
|
+
},
|
|
473
|
+
"account": {
|
|
474
|
+
"type": "string",
|
|
475
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
432
476
|
}
|
|
433
477
|
},
|
|
434
478
|
"required": ["action", "confidence"]
|
|
@@ -463,6 +507,10 @@
|
|
|
463
507
|
"reason": {
|
|
464
508
|
"type": "string",
|
|
465
509
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
510
|
+
},
|
|
511
|
+
"account": {
|
|
512
|
+
"type": "string",
|
|
513
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
466
514
|
}
|
|
467
515
|
}
|
|
468
516
|
},
|
|
@@ -496,6 +544,10 @@
|
|
|
496
544
|
"reason": {
|
|
497
545
|
"type": "string",
|
|
498
546
|
"description": "Brief non-technical explanation of why this tool is being called"
|
|
547
|
+
},
|
|
548
|
+
"account": {
|
|
549
|
+
"type": "string",
|
|
550
|
+
"description": "Email address of the Gmail account to use. Required when multiple Gmail accounts are connected. If omitted, uses the most recently connected account."
|
|
499
551
|
}
|
|
500
552
|
}
|
|
501
553
|
},
|
|
@@ -18,6 +18,7 @@ export async function run(
|
|
|
18
18
|
input: Record<string, unknown>,
|
|
19
19
|
context: ToolContext,
|
|
20
20
|
): Promise<ToolExecutionResult> {
|
|
21
|
+
const account = input.account as string | undefined;
|
|
21
22
|
const query = input.query as string | undefined;
|
|
22
23
|
const scanId = input.scan_id as string | undefined;
|
|
23
24
|
const senderIds = input.sender_ids as string[] | undefined;
|
|
@@ -34,7 +35,10 @@ export async function run(
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
try {
|
|
37
|
-
const connection = resolveOAuthConnection(
|
|
38
|
+
const connection = await resolveOAuthConnection(
|
|
39
|
+
"integration:google",
|
|
40
|
+
account,
|
|
41
|
+
);
|
|
38
42
|
const allMessageIds: string[] = [];
|
|
39
43
|
let pageToken: string | undefined;
|
|
40
44
|
let truncated = false;
|
|
@@ -103,7 +107,10 @@ export async function run(
|
|
|
103
107
|
} else if (messageId) {
|
|
104
108
|
// Single message path
|
|
105
109
|
try {
|
|
106
|
-
const connection = resolveOAuthConnection(
|
|
110
|
+
const connection = await resolveOAuthConnection(
|
|
111
|
+
"integration:google",
|
|
112
|
+
account,
|
|
113
|
+
);
|
|
107
114
|
await modifyMessage(connection, messageId, { removeLabelIds: ["INBOX"] });
|
|
108
115
|
return ok("Message archived.");
|
|
109
116
|
} catch (e) {
|
|
@@ -121,7 +128,10 @@ export async function run(
|
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
try {
|
|
124
|
-
const connection = resolveOAuthConnection(
|
|
131
|
+
const connection = await resolveOAuthConnection(
|
|
132
|
+
"integration:google",
|
|
133
|
+
account,
|
|
134
|
+
);
|
|
125
135
|
if (messageIds.length === 1) {
|
|
126
136
|
await modifyMessage(connection, messageIds[0], {
|
|
127
137
|
removeLabelIds: ["INBOX"],
|
|
@@ -48,6 +48,7 @@ export async function run(
|
|
|
48
48
|
input: Record<string, unknown>,
|
|
49
49
|
context: ToolContext,
|
|
50
50
|
): Promise<ToolExecutionResult> {
|
|
51
|
+
const account = input.account as string | undefined;
|
|
51
52
|
const action = input.action as string;
|
|
52
53
|
const messageId = input.message_id as string;
|
|
53
54
|
|
|
@@ -56,7 +57,10 @@ export async function run(
|
|
|
56
57
|
|
|
57
58
|
if (action === "list") {
|
|
58
59
|
try {
|
|
59
|
-
const connection = resolveOAuthConnection(
|
|
60
|
+
const connection = await resolveOAuthConnection(
|
|
61
|
+
"integration:google",
|
|
62
|
+
account,
|
|
63
|
+
);
|
|
60
64
|
const message = await getMessage(connection, messageId, "full");
|
|
61
65
|
const attachments = collectAttachments(message.payload?.parts);
|
|
62
66
|
|
|
@@ -78,7 +82,10 @@ export async function run(
|
|
|
78
82
|
if (!filename) return err("filename is required for download.");
|
|
79
83
|
|
|
80
84
|
try {
|
|
81
|
-
const connection = resolveOAuthConnection(
|
|
85
|
+
const connection = await resolveOAuthConnection(
|
|
86
|
+
"integration:google",
|
|
87
|
+
account,
|
|
88
|
+
);
|
|
82
89
|
const attachment = await getAttachment(
|
|
83
90
|
connection,
|
|
84
91
|
messageId,
|
|
@@ -10,6 +10,7 @@ export async function run(
|
|
|
10
10
|
input: Record<string, unknown>,
|
|
11
11
|
_context: ToolContext,
|
|
12
12
|
): Promise<ToolExecutionResult> {
|
|
13
|
+
const account = input.account as string | undefined;
|
|
13
14
|
const to = input.to as string;
|
|
14
15
|
const subject = input.subject as string;
|
|
15
16
|
const body = input.body as string;
|
|
@@ -22,7 +23,10 @@ export async function run(
|
|
|
22
23
|
if (!body) return err("body is required.");
|
|
23
24
|
|
|
24
25
|
try {
|
|
25
|
-
const connection = resolveOAuthConnection(
|
|
26
|
+
const connection = await resolveOAuthConnection(
|
|
27
|
+
"integration:google",
|
|
28
|
+
account,
|
|
29
|
+
);
|
|
26
30
|
const draft = await createDraft(
|
|
27
31
|
connection,
|
|
28
32
|
to,
|
|
@@ -18,6 +18,7 @@ export async function run(
|
|
|
18
18
|
input: Record<string, unknown>,
|
|
19
19
|
_context: ToolContext,
|
|
20
20
|
): Promise<ToolExecutionResult> {
|
|
21
|
+
const account = input.account as string | undefined;
|
|
21
22
|
const action = input.action as string;
|
|
22
23
|
|
|
23
24
|
if (!action) {
|
|
@@ -25,7 +26,10 @@ export async function run(
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
try {
|
|
28
|
-
const connection = resolveOAuthConnection(
|
|
29
|
+
const connection = await resolveOAuthConnection(
|
|
30
|
+
"integration:google",
|
|
31
|
+
account,
|
|
32
|
+
);
|
|
29
33
|
switch (action) {
|
|
30
34
|
case "list": {
|
|
31
35
|
const filters = await listFilters(connection);
|
|
@@ -30,6 +30,7 @@ export async function run(
|
|
|
30
30
|
input: Record<string, unknown>,
|
|
31
31
|
_context: ToolContext,
|
|
32
32
|
): Promise<ToolExecutionResult> {
|
|
33
|
+
const account = input.account as string | undefined;
|
|
33
34
|
const action = input.action as string;
|
|
34
35
|
|
|
35
36
|
if (!action) {
|
|
@@ -37,7 +38,10 @@ export async function run(
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
try {
|
|
40
|
-
const connection = resolveOAuthConnection(
|
|
41
|
+
const connection = await resolveOAuthConnection(
|
|
42
|
+
"integration:google",
|
|
43
|
+
account,
|
|
44
|
+
);
|
|
41
45
|
switch (action) {
|
|
42
46
|
case "track": {
|
|
43
47
|
const messageId = input.message_id as string;
|
|
@@ -67,6 +67,7 @@ export async function run(
|
|
|
67
67
|
input: Record<string, unknown>,
|
|
68
68
|
_context: ToolContext,
|
|
69
69
|
): Promise<ToolExecutionResult> {
|
|
70
|
+
const account = input.account as string | undefined;
|
|
70
71
|
const messageId = input.message_id as string;
|
|
71
72
|
const forwardTo = input.to as string;
|
|
72
73
|
const additionalText = input.text as string | undefined;
|
|
@@ -75,7 +76,10 @@ export async function run(
|
|
|
75
76
|
if (!forwardTo) return err("to is required.");
|
|
76
77
|
|
|
77
78
|
try {
|
|
78
|
-
const connection = resolveOAuthConnection(
|
|
79
|
+
const connection = await resolveOAuthConnection(
|
|
80
|
+
"integration:google",
|
|
81
|
+
account,
|
|
82
|
+
);
|
|
79
83
|
const message = await getMessage(connection, messageId, "full");
|
|
80
84
|
const headers = message.payload?.headers ?? [];
|
|
81
85
|
const originalFrom = extractHeader(headers, "From");
|
|
@@ -13,6 +13,7 @@ export async function run(
|
|
|
13
13
|
input: Record<string, unknown>,
|
|
14
14
|
_context: ToolContext,
|
|
15
15
|
): Promise<ToolExecutionResult> {
|
|
16
|
+
const account = input.account as string | undefined;
|
|
16
17
|
const messageId = input.message_id as string | undefined;
|
|
17
18
|
const messageIds = input.message_ids as string[] | undefined;
|
|
18
19
|
const addLabelIds = input.add_label_ids as string[] | undefined;
|
|
@@ -20,7 +21,10 @@ export async function run(
|
|
|
20
21
|
|
|
21
22
|
if (messageIds && messageIds.length > 0) {
|
|
22
23
|
try {
|
|
23
|
-
const connection = resolveOAuthConnection(
|
|
24
|
+
const connection = await resolveOAuthConnection(
|
|
25
|
+
"integration:google",
|
|
26
|
+
account,
|
|
27
|
+
);
|
|
24
28
|
await batchModifyMessages(connection, messageIds, {
|
|
25
29
|
addLabelIds,
|
|
26
30
|
removeLabelIds,
|
|
@@ -33,7 +37,10 @@ export async function run(
|
|
|
33
37
|
|
|
34
38
|
if (messageId) {
|
|
35
39
|
try {
|
|
36
|
-
const connection = resolveOAuthConnection(
|
|
40
|
+
const connection = await resolveOAuthConnection(
|
|
41
|
+
"integration:google",
|
|
42
|
+
account,
|
|
43
|
+
);
|
|
37
44
|
await modifyMessage(connection, messageId, {
|
|
38
45
|
addLabelIds,
|
|
39
46
|
removeLabelIds,
|
|
@@ -44,6 +44,7 @@ export async function run(
|
|
|
44
44
|
input: Record<string, unknown>,
|
|
45
45
|
_context: ToolContext,
|
|
46
46
|
): Promise<ToolExecutionResult> {
|
|
47
|
+
const account = input.account as string | undefined;
|
|
47
48
|
const maxMessages = Math.min(
|
|
48
49
|
(input.max_messages as number) ?? 2000,
|
|
49
50
|
MAX_MESSAGES_CAP,
|
|
@@ -55,7 +56,10 @@ export async function run(
|
|
|
55
56
|
const query = `in:inbox -has:unsubscribe newer_than:${timeRange}`;
|
|
56
57
|
|
|
57
58
|
try {
|
|
58
|
-
const connection = resolveOAuthConnection(
|
|
59
|
+
const connection = await resolveOAuthConnection(
|
|
60
|
+
"integration:google",
|
|
61
|
+
account,
|
|
62
|
+
);
|
|
59
63
|
// Pipeline: fire metadata fetches for each page of IDs as they arrive
|
|
60
64
|
const allMessageIds: string[] = [];
|
|
61
65
|
const fetchPromises: Promise<GmailMessage[]>[] = [];
|
|
@@ -10,11 +10,15 @@ export async function run(
|
|
|
10
10
|
input: Record<string, unknown>,
|
|
11
11
|
_context: ToolContext,
|
|
12
12
|
): Promise<ToolExecutionResult> {
|
|
13
|
+
const account = input.account as string | undefined;
|
|
13
14
|
const draftId = input.draft_id as string;
|
|
14
15
|
if (!draftId) return err("draft_id is required.");
|
|
15
16
|
|
|
16
17
|
try {
|
|
17
|
-
const connection = resolveOAuthConnection(
|
|
18
|
+
const connection = await resolveOAuthConnection(
|
|
19
|
+
"integration:google",
|
|
20
|
+
account,
|
|
21
|
+
);
|
|
18
22
|
const msg = await sendDraft(connection, draftId);
|
|
19
23
|
return ok(`Draft sent (Message ID: ${msg.id}).`);
|
|
20
24
|
} catch (e) {
|
|
@@ -48,6 +48,7 @@ export async function run(
|
|
|
48
48
|
input: Record<string, unknown>,
|
|
49
49
|
_context: ToolContext,
|
|
50
50
|
): Promise<ToolExecutionResult> {
|
|
51
|
+
const account = input.account as string | undefined;
|
|
51
52
|
const query = (input.query as string) ?? "category:promotions newer_than:90d";
|
|
52
53
|
const maxMessages = Math.min(
|
|
53
54
|
(input.max_messages as number) ?? 5000,
|
|
@@ -57,7 +58,10 @@ export async function run(
|
|
|
57
58
|
const inputPageToken = input.page_token as string | undefined;
|
|
58
59
|
|
|
59
60
|
try {
|
|
60
|
-
const connection = resolveOAuthConnection(
|
|
61
|
+
const connection = await resolveOAuthConnection(
|
|
62
|
+
"integration:google",
|
|
63
|
+
account,
|
|
64
|
+
);
|
|
61
65
|
// Pipeline: fire metadata fetches for each page of IDs as they arrive,
|
|
62
66
|
// overlapping fetch latency with pagination latency
|
|
63
67
|
const allMessageIds: string[] = [];
|
|
@@ -10,6 +10,7 @@ export async function run(
|
|
|
10
10
|
input: Record<string, unknown>,
|
|
11
11
|
_context: ToolContext,
|
|
12
12
|
): Promise<ToolExecutionResult> {
|
|
13
|
+
const account = input.account as string | undefined;
|
|
13
14
|
const messageId = input.message_id as string;
|
|
14
15
|
|
|
15
16
|
if (!messageId) {
|
|
@@ -17,7 +18,10 @@ export async function run(
|
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
try {
|
|
20
|
-
const connection = resolveOAuthConnection(
|
|
21
|
+
const connection = await resolveOAuthConnection(
|
|
22
|
+
"integration:google",
|
|
23
|
+
account,
|
|
24
|
+
);
|
|
21
25
|
await trashMessage(connection, messageId);
|
|
22
26
|
return ok("Message moved to trash.");
|
|
23
27
|
} catch (e) {
|
|
@@ -18,6 +18,7 @@ export async function run(
|
|
|
18
18
|
input: Record<string, unknown>,
|
|
19
19
|
context: ToolContext,
|
|
20
20
|
): Promise<ToolExecutionResult> {
|
|
21
|
+
const account = input.account as string | undefined;
|
|
21
22
|
if (!context.triggeredBySurfaceAction) {
|
|
22
23
|
return err(
|
|
23
24
|
"This tool requires user confirmation via a surface action. Present results in a selection table with action buttons and wait for the user to click before proceeding.",
|
|
@@ -31,7 +32,10 @@ export async function run(
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
try {
|
|
34
|
-
const connection = resolveOAuthConnection(
|
|
35
|
+
const connection = await resolveOAuthConnection(
|
|
36
|
+
"integration:google",
|
|
37
|
+
account,
|
|
38
|
+
);
|
|
35
39
|
const message = await getMessage(connection, messageId, "metadata", [
|
|
36
40
|
"List-Unsubscribe",
|
|
37
41
|
"List-Unsubscribe-Post",
|
|
@@ -14,6 +14,7 @@ export async function run(
|
|
|
14
14
|
input: Record<string, unknown>,
|
|
15
15
|
_context: ToolContext,
|
|
16
16
|
): Promise<ToolExecutionResult> {
|
|
17
|
+
const account = input.account as string | undefined;
|
|
17
18
|
const action = input.action as string;
|
|
18
19
|
|
|
19
20
|
if (!action) {
|
|
@@ -21,7 +22,10 @@ export async function run(
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
try {
|
|
24
|
-
const connection = resolveOAuthConnection(
|
|
25
|
+
const connection = await resolveOAuthConnection(
|
|
26
|
+
"integration:google",
|
|
27
|
+
account,
|
|
28
|
+
);
|
|
25
29
|
switch (action) {
|
|
26
30
|
case "get": {
|
|
27
31
|
const settings = await getVacation(connection);
|