@vellumai/assistant 0.4.34 → 0.4.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/ARCHITECTURE.md +44 -49
- package/README.md +32 -20
- package/docs/architecture/keychain-broker.md +186 -0
- package/docs/architecture/security.md +110 -116
- package/docs/runbook-trusted-contacts.md +2 -2
- package/docs/skills.md +25 -25
- package/package.json +4 -1
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +11 -2
- package/src/__tests__/actor-token-service.test.ts +1 -0
- package/src/__tests__/amazon-cdp-integration.test.ts +74 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +38 -9
- package/src/__tests__/assistant-id-boundary-guard.test.ts +91 -43
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/bundle-scanner.test.ts +1 -1
- package/src/__tests__/channel-guardian.test.ts +102 -102
- package/src/__tests__/channel-invite-transport.test.ts +155 -256
- package/src/__tests__/channel-readiness-routes.test.ts +336 -0
- package/src/__tests__/checker.test.ts +6 -6
- package/src/__tests__/chrome-cdp.test.ts +350 -0
- package/src/__tests__/computer-use-session-lifecycle.test.ts +3 -3
- package/src/__tests__/computer-use-session-working-dir.test.ts +86 -52
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +1 -1
- package/src/__tests__/config-loader-migration.test.ts +85 -0
- package/src/__tests__/conversation-pairing.test.ts +370 -5
- package/src/__tests__/credential-broker-browser-fill.test.ts +1 -10
- package/src/__tests__/credential-broker-server-use.test.ts +1 -10
- package/src/__tests__/credential-security-e2e.test.ts +7 -1
- package/src/__tests__/credential-security-invariants.test.ts +14 -20
- package/src/__tests__/credential-vault-unit.test.ts +1 -11
- package/src/__tests__/credential-vault.test.ts +5 -19
- package/src/__tests__/credentials-cli.test.ts +806 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +23 -4
- package/src/__tests__/email-invite-adapter.test.ts +78 -0
- package/src/__tests__/email-service-config-fallback.test.ts +102 -0
- package/src/__tests__/encrypted-store.test.ts +6 -6
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/gateway-only-enforcement.test.ts +5 -1
- package/src/__tests__/guardian-actions-endpoint.test.ts +70 -12
- package/src/__tests__/guardian-outbound-http.test.ts +53 -47
- package/src/__tests__/handle-user-message-secret-resume.test.ts +23 -0
- package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +32 -23
- package/src/__tests__/handlers-telegram-config.test.ts +8 -2
- package/src/__tests__/handlers-twitter-config.test.ts +2 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +108 -7
- package/src/__tests__/ingress-reconcile.test.ts +6 -0
- package/src/__tests__/intent-routing.test.ts +23 -4
- package/src/__tests__/invite-routes-http.test.ts +12 -0
- package/src/__tests__/ipc-snapshot.test.ts +8 -2
- package/src/__tests__/keychain-broker-client.test.ts +543 -0
- package/src/__tests__/llm-usage-store.test.ts +344 -0
- package/src/__tests__/mcp-client-auth.test.ts +2 -2
- package/src/__tests__/media-reuse-story.e2e.test.ts +1 -1
- package/src/__tests__/migration-transport.test.ts +49 -0
- package/src/__tests__/notification-broadcaster.test.ts +205 -5
- package/src/__tests__/notification-deep-link.test.ts +365 -1
- package/src/__tests__/oauth-connect-handler.test.ts +2 -2
- package/src/__tests__/onboarding-starter-tasks.test.ts +17 -4
- package/src/__tests__/proxy-approval-callback.test.ts +1 -1
- package/src/__tests__/recording-handler.test.ts +1 -1
- package/src/__tests__/recording-intent-handler.test.ts +6 -1
- package/src/__tests__/recording-state-machine.test.ts +1 -1
- package/src/__tests__/relay-server.test.ts +9 -1
- package/src/__tests__/ride-shotgun-handler.test.ts +499 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +160 -1
- package/src/__tests__/script-proxy-injection-runtime.test.ts +299 -2
- package/src/__tests__/script-proxy-profile-template-fallback.test.ts +1 -1
- package/src/__tests__/secret-onetime-send.test.ts +8 -2
- package/src/__tests__/secure-keys.test.ts +175 -216
- package/src/__tests__/session-confirmation-signals.test.ts +1 -1
- package/src/__tests__/session-messaging-secret-redirect.test.ts +1 -1
- package/src/__tests__/session-queue.test.ts +2 -1
- package/src/__tests__/session-tool-setup-app-refresh.test.ts +2 -2
- package/src/__tests__/skill-feature-flags-integration.test.ts +29 -4
- package/src/__tests__/skill-feature-flags.test.ts +12 -9
- package/src/__tests__/skill-load-feature-flag.test.ts +26 -5
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skills.test.ts +34 -4
- package/src/__tests__/slack-channel-config.test.ts +2 -2
- package/src/__tests__/system-prompt.test.ts +26 -4
- package/src/__tests__/telegram-bot-username-resolution.test.ts +212 -0
- package/src/__tests__/telegram-invite-adapter.test.ts +164 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
- package/src/__tests__/tool-permission-simulate-handler.test.ts +8 -2
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +9 -1
- package/src/__tests__/twitter-auth-handler.test.ts +2 -2
- package/src/__tests__/twitter-oauth-client.test.ts +1 -1
- package/src/__tests__/usage-routes.test.ts +339 -0
- package/src/__tests__/whatsapp-invite-adapter.test.ts +94 -0
- package/src/agent/loop.ts +3 -0
- package/src/amazon/checkout.ts +0 -1
- package/src/approvals/guardian-request-resolvers.ts +9 -1
- package/src/bundler/app-bundler.ts +28 -12
- package/src/bundler/bundle-scanner.ts +1 -1
- package/src/bundler/bundle-signer.ts +3 -3
- package/src/bundler/manifest.ts +1 -1
- package/src/bundler/signature-verifier.ts +3 -3
- package/src/channels/config.ts +1 -1
- package/src/cli/AGENTS.md +63 -0
- package/src/cli/__tests__/notifications.test.ts +470 -0
- package/src/cli/amazon.ts +344 -167
- package/src/cli/audit.ts +85 -0
- package/src/cli/autonomy.ts +369 -0
- package/src/cli/channels.ts +51 -0
- package/src/cli/completions.ts +208 -0
- package/src/cli/config.ts +220 -0
- package/src/cli/contacts.ts +471 -0
- package/src/cli/credentials.ts +564 -0
- package/src/cli/default-action.ts +14 -0
- package/src/cli/dev.ts +131 -0
- package/src/cli/doctor.ts +398 -0
- package/src/cli/email.ts +491 -0
- package/src/cli/influencer.ts +72 -0
- package/src/cli/integrations.ts +248 -57
- package/src/cli/keys.ts +114 -0
- package/src/cli/map.ts +46 -54
- package/src/cli/mcp.ts +111 -3
- package/src/cli/{config-commands.ts → memory.ts} +133 -242
- package/src/cli/notifications.ts +407 -0
- package/src/cli/program.ts +65 -0
- package/src/cli/reference.ts +48 -0
- package/src/cli/sequence.ts +154 -0
- package/src/cli/sessions.ts +262 -0
- package/src/cli/trust.ts +177 -0
- package/src/cli/twitter.ts +323 -106
- package/src/config/__tests__/build-cli-reference-section.test.ts +49 -0
- package/src/config/bundled-skills/amazon/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/TOOLS.json +26 -0
- package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +13 -0
- package/src/config/bundled-skills/contacts/SKILL.md +178 -10
- package/src/config/bundled-skills/doordash/doordash-cli.ts +23 -168
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +175 -145
- package/src/config/bundled-skills/messaging/tools/shared.ts +4 -1
- package/src/config/bundled-skills/twilio-setup/SKILL.md +70 -17
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/core-schema.ts +7 -0
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/loader.ts +26 -0
- package/src/config/schema.ts +4 -0
- package/src/config/skill-state.ts +0 -13
- package/src/config/system-prompt.ts +27 -0
- package/src/contacts/contact-store.ts +25 -0
- package/src/daemon/computer-use-session.ts +1 -1
- package/src/daemon/handlers/apps.ts +1 -0
- package/src/daemon/handlers/config-channels.ts +3 -3
- package/src/daemon/handlers/config-dispatch.ts +29 -0
- package/src/daemon/handlers/config-inbox.ts +4 -3
- package/src/daemon/handlers/config.ts +3 -43
- package/src/daemon/handlers/contacts.ts +34 -0
- package/src/daemon/handlers/index.ts +17 -3
- package/src/daemon/handlers/session-user-message.ts +7 -0
- package/src/daemon/handlers/sessions.ts +21 -2
- package/src/daemon/handlers/shared.ts +17 -0
- package/src/daemon/ipc-contract/apps.ts +2 -0
- package/src/daemon/ipc-contract/computer-use.ts +9 -0
- package/src/daemon/ipc-contract/contacts.ts +3 -3
- package/src/daemon/ipc-contract/inbox.ts +2 -0
- package/src/daemon/ipc-contract/messages.ts +4 -0
- package/src/daemon/ipc-contract/sessions.ts +8 -0
- package/src/daemon/ipc-contract-inventory.json +1 -0
- package/src/daemon/lifecycle.ts +0 -5
- package/src/daemon/ride-shotgun-handler.ts +139 -25
- package/src/daemon/session-agent-loop-handlers.ts +100 -0
- package/src/daemon/session-agent-loop.ts +72 -0
- package/src/daemon/session-tool-setup.ts +7 -0
- package/src/daemon/session.ts +23 -1
- package/src/daemon/tool-side-effects.ts +39 -1
- package/src/email/service.ts +59 -2
- package/src/index.ts +2 -60
- package/src/mcp/mcp-oauth-provider.ts +90 -8
- package/src/media/app-icon-generator.ts +86 -0
- package/src/memory/db-init.ts +12 -1
- package/src/memory/llm-usage-store.ts +186 -0
- package/src/memory/migrations/026-guardian-verification-sessions.ts +28 -9
- package/src/memory/migrations/027a-guardian-bootstrap-token.ts +16 -3
- package/src/memory/migrations/038-actor-token-records.ts +8 -1
- package/src/memory/migrations/039-actor-refresh-token-records.ts +11 -2
- package/src/memory/migrations/110-channel-guardian.ts +27 -6
- package/src/memory/migrations/112-assistant-inbox.ts +39 -15
- package/src/memory/migrations/114-notifications.ts +37 -15
- package/src/memory/migrations/117-conversation-attention.ts +33 -9
- package/src/memory/migrations/137-usage-dashboard-indexes.ts +26 -0
- package/src/memory/migrations/139-drop-usage-composite-indexes.ts +30 -0
- package/src/memory/migrations/index.ts +2 -0
- package/src/memory/migrations/schema-introspection.ts +18 -0
- package/src/memory/schema-migration.ts +1 -0
- package/src/memory/shared-app-links-store.ts +1 -1
- package/src/messaging/registry.ts +27 -0
- package/src/notifications/README.md +79 -70
- package/src/notifications/broadcaster.ts +2 -1
- package/src/notifications/conversation-pairing.ts +147 -13
- package/src/notifications/copy-composer.ts +7 -3
- package/src/notifications/destination-resolver.ts +14 -1
- package/src/notifications/emit-signal.ts +3 -2
- package/src/notifications/signal.ts +105 -1
- package/src/notifications/types.ts +16 -0
- package/src/permissions/checker.ts +29 -3
- package/src/permissions/prompter.ts +11 -3
- package/src/runtime/access-request-helper.ts +2 -1
- package/src/runtime/auth/route-policy.ts +7 -1
- package/src/runtime/channel-invite-transport.ts +40 -63
- package/src/runtime/channel-invite-transports/email.ts +13 -39
- package/src/runtime/channel-invite-transports/slack.ts +5 -34
- package/src/runtime/channel-invite-transports/sms.ts +8 -29
- package/src/runtime/channel-invite-transports/telegram.ts +69 -28
- package/src/runtime/channel-invite-transports/voice.ts +0 -7
- package/src/runtime/channel-invite-transports/whatsapp.ts +43 -0
- package/src/runtime/channel-readiness-service.ts +202 -45
- package/src/runtime/confirmation-request-guardian-bridge.ts +2 -1
- package/src/runtime/guardian-outbound-actions.ts +8 -5
- package/src/runtime/http-server.ts +5 -9
- package/src/runtime/http-types.ts +13 -1
- package/src/runtime/invite-instruction-generator.ts +178 -0
- package/src/runtime/invite-service.ts +22 -25
- package/src/runtime/migrations/migration-transport.ts +13 -0
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +8 -7
- package/src/runtime/routes/channel-readiness-routes.ts +30 -11
- package/src/runtime/routes/contact-routes.ts +54 -26
- package/src/runtime/routes/guardian-bootstrap-routes.ts +1 -1
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +1 -1
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +2 -1
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +2 -1
- package/src/runtime/routes/integration-routes.ts +1 -1
- package/src/runtime/routes/invite-routes.ts +1 -1
- package/src/runtime/routes/secret-routes.ts +31 -7
- package/src/runtime/routes/surface-content-routes.ts +104 -0
- package/src/runtime/routes/twilio-routes.ts +32 -1
- package/src/runtime/routes/usage-routes.ts +114 -0
- package/src/runtime/tool-grant-request-helper.ts +2 -1
- package/src/security/encrypted-store.ts +9 -5
- package/src/security/keychain-broker-client.ts +393 -0
- package/src/security/secure-keys.ts +106 -321
- package/src/tools/apps/executors.ts +73 -0
- package/src/tools/browser/auto-navigate.ts +15 -6
- package/src/tools/browser/chrome-cdp.ts +211 -0
- package/src/tools/browser/network-recorder.test.ts +83 -0
- package/src/tools/browser/network-recorder.ts +8 -7
- package/src/tools/browser/x-auto-navigate.ts +12 -6
- package/src/tools/credentials/policy-types.ts +24 -0
- package/src/tools/credentials/vault.ts +22 -27
- package/src/tools/network/script-proxy/session-manager.ts +47 -3
- package/src/tools/permission-checker.ts +1 -0
- package/src/tools/types.ts +2 -0
- package/src/tools/ui-surface/definitions.ts +1 -2
- package/src/tools/watch/watch-state.ts +2 -0
- package/src/__tests__/key-migration.test.ts +0 -240
- package/src/__tests__/keychain.test.ts +0 -286
- package/src/cli/core-commands.ts +0 -899
- package/src/security/keychain-to-encrypted-migration.ts +0 -66
- package/src/security/keychain.ts +0 -490
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: "Google OAuth Setup"
|
|
3
|
-
description: "Set up Google Cloud OAuth credentials for Gmail and Calendar
|
|
3
|
+
description: "Set up Google Cloud OAuth credentials for Gmail and Calendar"
|
|
4
4
|
user-invocable: true
|
|
5
5
|
credential-setup-for: "gmail"
|
|
6
|
-
includes: ["
|
|
7
|
-
metadata: {"vellum": {"emoji": "\ud83d\udd11"}}
|
|
6
|
+
includes: ["public-ingress", "browser"]
|
|
7
|
+
metadata: { "vellum": { "emoji": "\ud83d\udd11" } }
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
You are helping your user set up Google Cloud OAuth credentials so Gmail and Google Calendar integrations can connect.
|
|
11
11
|
|
|
12
12
|
## Client Check
|
|
13
13
|
|
|
14
|
-
Determine
|
|
14
|
+
Determine which setup path to use based on the user's client:
|
|
15
15
|
|
|
16
|
-
- **macOS desktop app**: Follow
|
|
17
|
-
- **Telegram or other channel** (no browser automation): Follow
|
|
16
|
+
- **macOS desktop app**: Follow **Path B: CLI Setup** below.
|
|
17
|
+
- **Telegram or other channel** (no browser automation): Follow **Path A: Manual Setup for Channels** below.
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
@@ -29,6 +29,7 @@ Tell the user:
|
|
|
29
29
|
> **Setting up Gmail & Calendar from Telegram**
|
|
30
30
|
>
|
|
31
31
|
> Since I can't automate the browser from here, I'll walk you through each step with direct links. You'll need:
|
|
32
|
+
>
|
|
32
33
|
> 1. A Google account with access to Google Cloud Console
|
|
33
34
|
> 2. About 5 minutes
|
|
34
35
|
>
|
|
@@ -87,6 +88,7 @@ Tell the user:
|
|
|
87
88
|
> - `https://www.googleapis.com/auth/calendar.readonly`
|
|
88
89
|
> - `https://www.googleapis.com/auth/calendar.events`
|
|
89
90
|
> - `https://www.googleapis.com/auth/userinfo.email`
|
|
91
|
+
> - `https://www.googleapis.com/auth/contacts.readonly`
|
|
90
92
|
> - Click **Update**, then **Save and Continue**
|
|
91
93
|
> 5. On the Test users page, add **your email**, click **Save and Continue**
|
|
92
94
|
> 6. On the Summary page, click **Back to Dashboard**
|
|
@@ -96,6 +98,7 @@ Tell the user:
|
|
|
96
98
|
### Channel Step 5: Create OAuth Credentials (Web Application)
|
|
97
99
|
|
|
98
100
|
Before sending Step 4 to the user, resolve the concrete callback URL:
|
|
101
|
+
|
|
99
102
|
- Read the configured public gateway URL (`ingress.publicBaseUrl`). If it is missing, run the `public-ingress` skill first.
|
|
100
103
|
- Build `oauthCallbackUrl` as `<public gateway URL>/webhooks/oauth/callback`.
|
|
101
104
|
- When you send the instructions below, replace `OAUTH_CALLBACK_URL` with that concrete value. Never send placeholders literally.
|
|
@@ -140,7 +143,7 @@ credential_store store:
|
|
|
140
143
|
|
|
141
144
|
**Step 6b: Client Secret (requires split entry to avoid security filters)**
|
|
142
145
|
|
|
143
|
-
The Client Secret starts with `GOCSPX-` which triggers the ingress secret scanner on channel messages. To work around this, ask the user to send only the portion
|
|
146
|
+
The Client Secret starts with `GOCSPX-` which triggers the ingress secret scanner on channel messages. To work around this, ask the user to send only the portion _after_ the prefix.
|
|
144
147
|
|
|
145
148
|
Tell the user:
|
|
146
149
|
|
|
@@ -192,229 +195,265 @@ After the user authorizes (they'll come back and say so, or you can suggest they
|
|
|
192
195
|
|
|
193
196
|
---
|
|
194
197
|
|
|
195
|
-
# Path B:
|
|
198
|
+
# Path B: CLI Setup (macOS Desktop App)
|
|
196
199
|
|
|
197
|
-
|
|
200
|
+
**IMPORTANT: Always use `host_bash` (not `bash`) for all commands in this path.** The `gcloud` and `gws` CLIs need host access for Homebrew/npm installation, browser-based authentication, and interactive terminal prompts — none of which are available inside the sandbox.
|
|
201
|
+
|
|
202
|
+
You will set up Google Cloud OAuth credentials using the `gcloud` and `gws` command-line tools plus browser automation. The user signs in once via the browser, the CLI handles project setup, and the browser automates credential creation — the user only needs to copy-paste the Client Secret.
|
|
198
203
|
|
|
199
204
|
## Browser Interaction Principles
|
|
200
205
|
|
|
201
|
-
Google Cloud Console's UI
|
|
206
|
+
Google Cloud Console's UI may change over time. Do NOT memorize or depend on specific element IDs, CSS selectors, or DOM structures. Instead:
|
|
202
207
|
|
|
203
|
-
1. **
|
|
204
|
-
2. **Adapt to what you see.** If
|
|
205
|
-
3. **Verify after every action.** After clicking, typing, or navigating, take a new
|
|
206
|
-
4. **Never assume DOM structure.**
|
|
207
|
-
5. **When stuck after 2 attempts,
|
|
208
|
+
1. **Screenshot first, act second.** Before every interaction, take a `browser_screenshot` to see the current visual state. Use `browser_snapshot` to find interactive elements.
|
|
209
|
+
2. **Adapt to what you see.** If a button's label or position differs from what you expect, use the screenshot to find the correct element.
|
|
210
|
+
3. **Verify after every action.** After clicking, typing, or navigating, take a new screenshot to confirm the action succeeded.
|
|
211
|
+
4. **Never assume DOM structure.** Use the snapshot to identify what's on the page and interact accordingly.
|
|
212
|
+
5. **When stuck, screenshot and describe.** If you cannot find an expected element after 2 attempts, take a screenshot, describe what you see to the user, and ask for guidance.
|
|
208
213
|
|
|
209
214
|
## Anti-Loop Guardrails
|
|
210
215
|
|
|
211
216
|
Each step has a **retry budget of 3 attempts**. An attempt is one try at the step's primary action (e.g., clicking a button, filling a form). If a step fails after 3 attempts:
|
|
212
217
|
|
|
213
218
|
1. **Stop trying.** Do not continue retrying the same approach.
|
|
214
|
-
2. **Fall back to manual.** Tell the user what you were trying to do and ask them to complete that step manually in the
|
|
219
|
+
2. **Fall back to manual.** Tell the user what you were trying to do and ask them to complete that step manually in the browser. Give them the direct URL and clear text instructions.
|
|
215
220
|
3. **Resume automation** at the next step once the user confirms the manual step is done.
|
|
216
221
|
|
|
217
|
-
If **two or more steps** require manual fallback, abandon the automated flow entirely and switch to giving the user the remaining steps as clear text instructions with links
|
|
222
|
+
If **two or more steps** require manual fallback, abandon the automated flow entirely and switch to giving the user the remaining steps as clear text instructions with links.
|
|
218
223
|
|
|
219
|
-
## Things That Do Not Work
|
|
224
|
+
## Things That Do Not Work — Do Not Attempt
|
|
220
225
|
|
|
221
|
-
These actions are technically impossible in the browser automation environment
|
|
226
|
+
These actions are technically impossible in the browser automation environment:
|
|
222
227
|
|
|
223
|
-
- **Downloading files.** `browser_click` on a Download button does not save files to disk.
|
|
224
|
-
- **
|
|
225
|
-
- **
|
|
226
|
-
- **Navigating away from the credential dialog** before both credentials are stored. You will lose the Client Secret display and cannot get it back without creating a new client.
|
|
228
|
+
- **Downloading files.** `browser_click` on a Download button does not save files to disk. Do NOT click "Download JSON" in the OAuth client creation dialog.
|
|
229
|
+
- **Reading the Client Secret from a screenshot.** The secret IS visible in the creation dialog, but you MUST NOT attempt to read it from a screenshot — it is too easy to misread characters, and the value must be exact. Always use the `credential_store prompt` approach to let the user copy-paste it accurately.
|
|
230
|
+
- **Clipboard operations.** You cannot copy/paste via browser automation.
|
|
227
231
|
|
|
228
|
-
##
|
|
232
|
+
## Error Handling
|
|
233
|
+
|
|
234
|
+
- **Page load failures:** Retry navigation once. If it still fails, tell the user and ask them to check their internet connection.
|
|
235
|
+
- **Element not found:** Take a fresh screenshot to re-assess. The GCP Console UI may have changed. Describe what you see and try alternative approaches. If stuck after 2 attempts, ask the user for guidance.
|
|
236
|
+
- **OAuth client already exists with same name:** This is fine — GCP allows multiple clients with the same name. Proceed with creation.
|
|
237
|
+
- **Any unexpected state:** Take a `browser_screenshot`, describe what you see, and ask the user for guidance.
|
|
229
238
|
|
|
230
|
-
|
|
239
|
+
## CLI Step 1: Confirm
|
|
240
|
+
|
|
241
|
+
Use `ui_show` with `surface_type: "confirmation"`:
|
|
231
242
|
|
|
232
243
|
- **message:** `Set up Google Cloud for Gmail & Calendar`
|
|
233
244
|
- **detail:**
|
|
234
245
|
> Here's what will happen:
|
|
235
|
-
> 1. **A browser opens on the side** so you can watch everything I do
|
|
236
|
-
> 2. **You sign in** to your Google account in the browser
|
|
237
|
-
> 3. **I automate everything** including project creation, APIs, OAuth config, and credentials
|
|
238
|
-
> 4. **One copy-paste** where I'll ask you to copy the Client Secret from the browser into a secure prompt
|
|
239
|
-
> 5. **You authorize Vellum** with one click
|
|
240
246
|
>
|
|
241
|
-
>
|
|
247
|
+
> 1. **Install CLI tools** (`gcloud` and `gws`) if not already installed
|
|
248
|
+
> 2. **You sign in** to your Google account once via the browser
|
|
249
|
+
> 3. **CLI automates everything** — project creation, APIs, and consent screen
|
|
250
|
+
> 4. **I create OAuth credentials** in the browser — you just watch
|
|
251
|
+
> 5. **One quick copy-paste** — you copy the Client Secret into a secure prompt
|
|
252
|
+
> 6. **You authorize Vellum** with one click
|
|
253
|
+
>
|
|
254
|
+
> Takes about a minute after first-time setup. Ready?
|
|
242
255
|
|
|
243
|
-
If the user declines, acknowledge and stop.
|
|
256
|
+
If the user declines, acknowledge and stop.
|
|
244
257
|
|
|
245
|
-
## Step 2:
|
|
258
|
+
## CLI Step 2: Install Prerequisites
|
|
246
259
|
|
|
247
|
-
|
|
260
|
+
Check for and install each prerequisite. If any installation fails (e.g., Homebrew not available, corporate restrictions), tell the user what went wrong and provide manual installation instructions.
|
|
248
261
|
|
|
249
|
-
|
|
262
|
+
### gcloud
|
|
250
263
|
|
|
251
|
-
|
|
264
|
+
```bash
|
|
265
|
+
which gcloud
|
|
266
|
+
```
|
|
252
267
|
|
|
253
|
-
|
|
254
|
-
- **Already signed in:** Tell the user: "Already signed in, starting setup now..." and continue immediately.
|
|
255
|
-
- **CAPTCHA:** The browser automation's built-in handoff will handle this. If it persists, tell the user: "There's a CAPTCHA in the browser, please complete it and I'll continue automatically."
|
|
268
|
+
If missing:
|
|
256
269
|
|
|
257
|
-
|
|
270
|
+
```bash
|
|
271
|
+
brew install google-cloud-sdk
|
|
272
|
+
```
|
|
258
273
|
|
|
259
|
-
|
|
274
|
+
After installation, verify it works:
|
|
260
275
|
|
|
261
|
-
|
|
276
|
+
```bash
|
|
277
|
+
gcloud --version
|
|
278
|
+
```
|
|
262
279
|
|
|
263
|
-
|
|
280
|
+
### gws
|
|
264
281
|
|
|
265
|
-
|
|
282
|
+
```bash
|
|
283
|
+
which gws
|
|
284
|
+
```
|
|
266
285
|
|
|
267
|
-
|
|
286
|
+
If missing:
|
|
268
287
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
- **Organization restriction or quota error**: tell the user what happened and ask them to resolve it.
|
|
288
|
+
```bash
|
|
289
|
+
npm install -g @googleworkspace/cli
|
|
290
|
+
```
|
|
273
291
|
|
|
274
|
-
|
|
292
|
+
After installation, verify it works:
|
|
275
293
|
|
|
276
|
-
|
|
294
|
+
```bash
|
|
295
|
+
gws --version
|
|
296
|
+
```
|
|
277
297
|
|
|
278
|
-
## Step
|
|
298
|
+
## CLI Step 3: Sign In to Google
|
|
279
299
|
|
|
280
|
-
|
|
300
|
+
Tell the user: "Opening your browser so you can sign in to Google..."
|
|
281
301
|
|
|
282
|
-
|
|
302
|
+
```bash
|
|
303
|
+
gcloud auth login
|
|
304
|
+
```
|
|
283
305
|
|
|
284
|
-
|
|
285
|
-
1. `https://console.cloud.google.com/apis/library/gmail.googleapis.com?project=PROJECT_ID`
|
|
286
|
-
2. `https://console.cloud.google.com/apis/library/calendar-json.googleapis.com?project=PROJECT_ID`
|
|
306
|
+
This opens the browser for Google sign-in. Wait for the command to complete — it prints the authenticated account email on success.
|
|
287
307
|
|
|
288
|
-
|
|
289
|
-
- **"Enable" button**: click it, wait a few seconds, take another snapshot to confirm.
|
|
290
|
-
- **"Manage" button or "API enabled" text**: the API is already enabled. Skip it.
|
|
308
|
+
If the user is already authenticated (`gcloud auth list` shows an active account), skip this step and tell the user: "Already signed in, continuing setup..."
|
|
291
309
|
|
|
292
|
-
|
|
310
|
+
## CLI Step 4: GCP Project Setup
|
|
293
311
|
|
|
294
|
-
Tell the user: "APIs
|
|
312
|
+
Tell the user: "Setting up your Google Cloud project, APIs, and credentials..."
|
|
295
313
|
|
|
296
|
-
|
|
314
|
+
### Primary: `gws auth setup`
|
|
297
315
|
|
|
298
|
-
|
|
316
|
+
```bash
|
|
317
|
+
gws auth setup
|
|
318
|
+
```
|
|
299
319
|
|
|
300
|
-
|
|
320
|
+
This command automates:
|
|
301
321
|
|
|
302
|
-
|
|
322
|
+
- GCP project creation (or selection of an existing one)
|
|
323
|
+
- OAuth consent screen configuration
|
|
324
|
+
- OAuth credential creation
|
|
303
325
|
|
|
304
|
-
|
|
326
|
+
Wait for the command to complete. It may have interactive prompts — let them run in the terminal and the user can respond if needed.
|
|
305
327
|
|
|
306
|
-
|
|
328
|
+
If `gws auth setup` **succeeds**, note the **project ID** from the output and continue to **CLI Step 5**.
|
|
307
329
|
|
|
308
|
-
|
|
330
|
+
### Fallback: `gcloud` CLI + browser automation
|
|
309
331
|
|
|
310
|
-
|
|
332
|
+
If `gws auth setup` **fails** (common with personal Google accounts due to workspace-admin scope errors), use `gcloud` CLI and browser automation instead.
|
|
311
333
|
|
|
312
|
-
|
|
334
|
+
**Step 4f-1: Create GCP project**
|
|
313
335
|
|
|
314
|
-
|
|
336
|
+
Generate a unique suffix (4-6 random alphanumeric characters):
|
|
315
337
|
|
|
316
|
-
|
|
338
|
+
```bash
|
|
339
|
+
gcloud projects create vellum-assistant-SUFFIX --name="Vellum Assistant"
|
|
340
|
+
```
|
|
317
341
|
|
|
318
|
-
**
|
|
319
|
-
- **App name**: Type "Vellum Assistant" in the app name field.
|
|
320
|
-
- **User support email**: This is typically a dropdown showing the signed-in user's email. Use `browser_snapshot` to find a `<select>` or clickable dropdown element near "User support email". Select the user's email.
|
|
321
|
-
- **Developer contact email**: Type the user's email into this field. (Use the same email visible in the support email dropdown if you can read it, or use `browser_extract` to find the email shown on the page.)
|
|
322
|
-
- Click **Save and Continue** if on a multi-page wizard.
|
|
342
|
+
If the project already exists, use it. Note the **project ID**.
|
|
323
343
|
|
|
324
|
-
**
|
|
325
|
-
- Click **"Add or Remove Scopes"** (or similar button).
|
|
326
|
-
- In the scope picker dialog, look for a text input labeled **"Manually add scopes"** or **"Filter"** at the bottom or top of the dialog.
|
|
327
|
-
- Paste all 6 scopes at once as a comma-separated string into that input:
|
|
328
|
-
```
|
|
329
|
-
https://www.googleapis.com/auth/gmail.readonly,https://www.googleapis.com/auth/gmail.modify,https://www.googleapis.com/auth/gmail.send,https://www.googleapis.com/auth/calendar.readonly,https://www.googleapis.com/auth/calendar.events,https://www.googleapis.com/auth/userinfo.email
|
|
330
|
-
```
|
|
331
|
-
- Click **"Add to Table"** or **"Update"** to confirm the scopes.
|
|
332
|
-
- If no manual input is available, you'll need to search for and check each scope individually using the scope tree. Search for each scope URL in the filter box and check its checkbox.
|
|
333
|
-
- Click **Save and Continue** (or **Update** then **Save and Continue**).
|
|
344
|
+
**Step 4f-2: Enable APIs**
|
|
334
345
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
346
|
+
```bash
|
|
347
|
+
gcloud services enable gmail.googleapis.com --project=PROJECT_ID
|
|
348
|
+
gcloud services enable calendar-json.googleapis.com --project=PROJECT_ID
|
|
349
|
+
gcloud services enable people.googleapis.com --project=PROJECT_ID
|
|
350
|
+
```
|
|
339
351
|
|
|
340
|
-
**
|
|
341
|
-
- Click **"Back to Dashboard"** or **"Submit"**.
|
|
352
|
+
**Step 4f-3: Configure OAuth consent screen via browser**
|
|
342
353
|
|
|
343
|
-
|
|
354
|
+
Navigate to `https://console.cloud.google.com/apis/credentials/consent?project=PROJECT_ID`.
|
|
344
355
|
|
|
345
|
-
|
|
356
|
+
Take a screenshot and snapshot, then:
|
|
346
357
|
|
|
347
|
-
|
|
358
|
+
1. Select **"External"** user type, click **Create**
|
|
359
|
+
2. Fill in the app registration form:
|
|
360
|
+
- App name: **"Vellum Assistant"**
|
|
361
|
+
- User support email: select the authenticated email from the dropdown
|
|
362
|
+
- Developer contact email: type the same email
|
|
363
|
+
- Click **Save and Continue**
|
|
364
|
+
3. On the Scopes page, click **Save and Continue** (scopes are not needed for test-mode apps)
|
|
365
|
+
4. On the Test users page:
|
|
366
|
+
- Click **+ Add Users**
|
|
367
|
+
- Enter the authenticated email address
|
|
368
|
+
- Click **Add**, then **Save and Continue**
|
|
369
|
+
5. On the Summary page, click **Back to Dashboard**
|
|
348
370
|
|
|
349
|
-
**
|
|
371
|
+
**Verify:** Take a screenshot. The consent screen should show "Testing" publishing status.
|
|
350
372
|
|
|
351
|
-
|
|
373
|
+
After the fallback completes, skip CLI Step 5 (APIs already enabled above) and CLI Step 5c (test user already added above) — continue directly to **CLI Step 6**.
|
|
352
374
|
|
|
353
|
-
|
|
375
|
+
## CLI Step 5: Enable Additional APIs
|
|
354
376
|
|
|
355
|
-
|
|
377
|
+
`gws auth setup` enables the APIs it needs, but Vellum also requires the Calendar and People APIs. Enable them explicitly using the project ID from step 4:
|
|
356
378
|
|
|
357
|
-
|
|
379
|
+
```bash
|
|
380
|
+
gcloud services enable calendar-json.googleapis.com --project=PROJECT_ID
|
|
381
|
+
gcloud services enable people.googleapis.com --project=PROJECT_ID
|
|
382
|
+
```
|
|
358
383
|
|
|
359
|
-
|
|
360
|
-
- **Application type**: Find the dropdown and select **"Desktop app"**. This may be a `<select>` element or a custom dropdown. Use the snapshot to identify it. You might need to click the dropdown first, then take another snapshot to see the options, then click "Desktop app".
|
|
361
|
-
- **Name**: Type "Vellum Assistant" in the name field.
|
|
362
|
-
- Do NOT add any redirect URIs. The desktop app flow doesn't need them.
|
|
384
|
+
If either command reports the API is already enabled, that's fine — continue.
|
|
363
385
|
|
|
364
|
-
|
|
386
|
+
## CLI Step 5c: Add Test User
|
|
365
387
|
|
|
366
|
-
|
|
388
|
+
`gws auth setup` does not add test users to the consent screen, and there is no CLI/API for it. Use browser automation to add the authenticated email as a test user.
|
|
367
389
|
|
|
368
|
-
|
|
390
|
+
Navigate to `https://console.cloud.google.com/apis/credentials/consent?project=PROJECT_ID`.
|
|
369
391
|
|
|
370
|
-
|
|
392
|
+
Take a screenshot and snapshot. Find the **Test users** section (you may need to click **Edit App** or navigate to the consent screen edit flow):
|
|
371
393
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
394
|
+
1. Find and click the option to add test users (e.g., **+ Add Users** button)
|
|
395
|
+
2. Enter the authenticated email address (from `gcloud auth list`)
|
|
396
|
+
3. Click **Add** or **Save**
|
|
397
|
+
|
|
398
|
+
**Verify:** Take a screenshot confirming the email appears in the test users list.
|
|
399
|
+
|
|
400
|
+
If the user is already listed as a test user, skip this step.
|
|
401
|
+
|
|
402
|
+
## CLI Step 6: Create OAuth Credentials via Browser
|
|
403
|
+
|
|
404
|
+
**Goal:** Create a Desktop OAuth client in GCP Console and capture both credentials.
|
|
405
|
+
|
|
406
|
+
Navigate to `https://console.cloud.google.com/apis/credentials?project=PROJECT_ID` (substitute the actual project ID from step 4).
|
|
407
|
+
|
|
408
|
+
Take a screenshot and snapshot to check the page state:
|
|
409
|
+
|
|
410
|
+
- **Sign-in page:** Tell the user: "Please sign in to your Google account in the browser." Then auto-detect sign-in completion by polling screenshots every 5-10 seconds. Once signed in, continue.
|
|
411
|
+
- **Already signed in / Credentials page loaded:** Continue immediately.
|
|
412
|
+
|
|
413
|
+
### Step 6a: Create the OAuth Client
|
|
414
|
+
|
|
415
|
+
1. Take a screenshot and snapshot. Find and click **+ Create Credentials**, then select **OAuth client ID**.
|
|
416
|
+
2. On the creation form:
|
|
417
|
+
- Application type: Select **"Desktop app"**
|
|
418
|
+
- Name: **"Vellum Assistant"**
|
|
419
|
+
- Click **Create**
|
|
420
|
+
3. **Verify:** Take a screenshot. A dialog should appear showing both the **Client ID** and **Client Secret**.
|
|
378
421
|
|
|
379
|
-
|
|
422
|
+
### Step 6b: Extract Client ID
|
|
423
|
+
|
|
424
|
+
Use `browser_extract` to read the Client ID from the creation dialog. It looks like `123456789-xxxxx.apps.googleusercontent.com`.
|
|
425
|
+
|
|
426
|
+
Store it immediately:
|
|
380
427
|
|
|
381
428
|
```
|
|
382
|
-
credential_store
|
|
429
|
+
credential_store store:
|
|
383
430
|
service: "integration:gmail"
|
|
384
431
|
field: "client_id"
|
|
385
|
-
|
|
386
|
-
description: "Copy the Client ID from the dialog in the Chrome window and paste it here. It looks like 123456789-xxxxx.apps.googleusercontent.com"
|
|
387
|
-
placeholder: "xxxxx.apps.googleusercontent.com"
|
|
432
|
+
value: "<the extracted Client ID>"
|
|
388
433
|
```
|
|
389
434
|
|
|
390
|
-
|
|
435
|
+
### Step 6c: Capture Client Secret via Secure Prompt
|
|
391
436
|
|
|
392
|
-
|
|
437
|
+
The Client Secret is visible in the same dialog. Do NOT attempt to read it from the screenshot — use a secure prompt so the user copies it accurately.
|
|
393
438
|
|
|
394
|
-
|
|
439
|
+
Tell the user: "Your OAuth credentials have been created! Please copy the **Client Secret** shown in the dialog and paste it into the secure prompt below."
|
|
395
440
|
|
|
396
441
|
```
|
|
397
442
|
credential_store prompt:
|
|
398
443
|
service: "integration:gmail"
|
|
399
444
|
field: "client_secret"
|
|
400
445
|
label: "Google OAuth Client Secret"
|
|
401
|
-
description: "Copy the Client Secret from the
|
|
446
|
+
description: "Copy the Client Secret from the dialog on screen. It starts with GOCSPX-"
|
|
402
447
|
placeholder: "GOCSPX-..."
|
|
403
448
|
```
|
|
404
449
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
If the user has trouble locating the secret, take a `browser_screenshot` and describe where the secret field is on the screen, but do NOT attempt to read the secret value yourself. It must come from the user for accuracy.
|
|
408
|
-
|
|
409
|
-
**What you should see when done:** `credential_store list` shows both `client_id` and `client_secret` for `integration:gmail`.
|
|
450
|
+
**CRITICAL — do NOT dismiss the creation dialog before the user has copied the secret.** Wait for the secure prompt to be completed before clicking OK or navigating away.
|
|
410
451
|
|
|
411
|
-
|
|
452
|
+
After the secret is stored, you may close the dialog.
|
|
412
453
|
|
|
413
|
-
## Step 7:
|
|
454
|
+
## CLI Step 7: Authorize
|
|
414
455
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
Tell the user: "Starting the authorization flow — a Google sign-in page will open in a few seconds. Just click 'Allow' when it appears."
|
|
456
|
+
Tell the user: "Starting the authorization flow — a Google sign-in page will open. Just click 'Allow' when it appears."
|
|
418
457
|
|
|
419
458
|
Use `credential_store` with:
|
|
420
459
|
|
|
@@ -429,15 +468,6 @@ This auto-reads client_id and client_secret from the secure store and auto-fills
|
|
|
429
468
|
|
|
430
469
|
**Verify:** The `oauth2_connect` call returns a success message with the connected account email.
|
|
431
470
|
|
|
432
|
-
## Step 8: Done!
|
|
471
|
+
## CLI Step 8: Done!
|
|
433
472
|
|
|
434
473
|
Tell the user: "**Gmail and Calendar are connected!** You can now read, search, and send emails, plus view and manage your calendar. Try asking me to check your inbox or show your upcoming events!"
|
|
435
|
-
|
|
436
|
-
## Error Handling
|
|
437
|
-
|
|
438
|
-
- **Page load failures:** Retry navigation once. If it still fails, tell the user and ask them to check their internet connection.
|
|
439
|
-
- **Permission errors in GCP:** The user may need billing enabled or organization-level permissions. Explain clearly and ask them to resolve it.
|
|
440
|
-
- **Consent screen already configured:** Don't overwrite. Skip to credential creation.
|
|
441
|
-
- **Element not found:** Take a fresh `browser_snapshot` to re-assess. The GCP UI may have changed. Describe what you see and try alternative approaches. If stuck after 2 attempts, ask the user for guidance. They can see the Chrome window too.
|
|
442
|
-
- **OAuth flow timeout or failure:** Offer to retry. The credentials are already stored, so reconnecting only requires re-running the authorization flow.
|
|
443
|
-
- **Any unexpected state:** Take a `browser_screenshot`, describe what you see, and ask the user for guidance.
|
|
@@ -11,6 +11,7 @@ import type { MessagingProvider } from "../../../../messaging/provider.js";
|
|
|
11
11
|
import {
|
|
12
12
|
getConnectedProviders,
|
|
13
13
|
getMessagingProvider,
|
|
14
|
+
isPlatformEnabled,
|
|
14
15
|
} from "../../../../messaging/registry.js";
|
|
15
16
|
import { withValidToken } from "../../../../security/token-manager.js";
|
|
16
17
|
import type { ToolExecutionResult } from "../../../../tools/types.js";
|
|
@@ -32,7 +33,9 @@ export function err(message: string): ToolExecutionResult {
|
|
|
32
33
|
export function resolveProvider(platformInput?: string): MessagingProvider {
|
|
33
34
|
if (platformInput) return getMessagingProvider(platformInput);
|
|
34
35
|
|
|
35
|
-
const connected = getConnectedProviders()
|
|
36
|
+
const connected = getConnectedProviders().filter((p) =>
|
|
37
|
+
isPlatformEnabled(p.id),
|
|
38
|
+
);
|
|
36
39
|
if (connected.length === 1) return connected[0];
|
|
37
40
|
if (connected.length === 0) {
|
|
38
41
|
throw new Error(
|