@vellumai/vellum-gateway 0.4.26 → 0.4.30

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.
Files changed (127) hide show
  1. package/AGENTS.md +46 -0
  2. package/ARCHITECTURE.md +209 -204
  3. package/README.md +104 -102
  4. package/package.json +3 -2
  5. package/src/__tests__/block-kit-builder.test.ts +58 -0
  6. package/src/__tests__/browser-relay-websocket.test.ts +43 -15
  7. package/src/__tests__/config.test.ts +4 -1
  8. package/src/__tests__/contacts-control-plane-proxy.test.ts +230 -0
  9. package/src/__tests__/contacts-control-plane-route-match.test.ts +86 -0
  10. package/src/__tests__/credential-reader.test.ts +68 -20
  11. package/src/__tests__/credential-watcher.test.ts +1 -7
  12. package/src/__tests__/feature-flag-defaults-sync.test.ts +20 -4
  13. package/src/__tests__/feature-flags-route.test.ts +146 -68
  14. package/src/__tests__/guardian-control-plane-proxy.test.ts +85 -39
  15. package/src/__tests__/load-guards.test.ts +9 -1
  16. package/src/__tests__/oauth-callback.test.ts +20 -25
  17. package/src/__tests__/probes.test.ts +7 -5
  18. package/src/__tests__/resolve-assistant.test.ts +5 -1
  19. package/src/__tests__/runtime-client.test.ts +60 -45
  20. package/src/__tests__/runtime-health-proxy.test.ts +23 -12
  21. package/src/__tests__/runtime-proxy-auth.test.ts +23 -15
  22. package/src/__tests__/runtime-proxy.test.ts +81 -49
  23. package/src/__tests__/schema.test.ts +29 -31
  24. package/src/__tests__/slack-app-home.test.ts +155 -0
  25. package/src/__tests__/slack-deliver-ratelimit.test.ts +193 -0
  26. package/src/__tests__/slack-deliver.test.ts +695 -50
  27. package/src/__tests__/slack-display-name.test.ts +255 -0
  28. package/src/__tests__/slack-errors.test.ts +77 -0
  29. package/src/__tests__/slack-normalize.test.ts +206 -30
  30. package/src/__tests__/slack-reaction-normalize.test.ts +180 -0
  31. package/src/__tests__/telegram-api-redaction.test.ts +49 -12
  32. package/src/__tests__/telegram-control-plane-proxy.test.ts +42 -20
  33. package/src/__tests__/telegram-deliver-auth.test.ts +61 -15
  34. package/src/__tests__/telegram-normalize.test.ts +60 -11
  35. package/src/__tests__/telegram-only-default.test.ts +12 -11
  36. package/src/__tests__/telegram-reconcile-route.test.ts +37 -21
  37. package/src/__tests__/telegram-send-attachments.test.ts +101 -30
  38. package/src/__tests__/telegram-webhook-handler.test.ts +251 -123
  39. package/src/__tests__/telegram-webhook-manager.test.ts +83 -43
  40. package/src/__tests__/text-to-blocks.test.ts +164 -0
  41. package/src/__tests__/twilio-relay-websocket.test.ts +49 -22
  42. package/src/__tests__/twilio-webhooks.test.ts +76 -55
  43. package/src/auth/scopes.ts +22 -29
  44. package/src/auth/subject.ts +19 -13
  45. package/src/auth/token-exchange.ts +24 -21
  46. package/src/auth/token-service.ts +61 -41
  47. package/src/auth/types.ts +23 -23
  48. package/src/channels/inbound-event.ts +11 -8
  49. package/src/channels/transport-hints.ts +16 -4
  50. package/src/channels/types.ts +31 -7
  51. package/src/config-file-watcher.ts +52 -36
  52. package/src/config.ts +171 -53
  53. package/src/credential-reader.ts +57 -23
  54. package/src/credential-watcher.ts +25 -19
  55. package/src/db/connection.ts +52 -0
  56. package/src/db/slack-store.ts +90 -0
  57. package/src/dedup-cache.ts +4 -1
  58. package/src/feature-flag-defaults.ts +16 -4
  59. package/src/feature-flag-registry.json +31 -7
  60. package/src/handlers/handle-inbound.ts +35 -13
  61. package/src/http/middleware/auth.ts +97 -0
  62. package/src/http/middleware/deliver-auth.ts +1 -1
  63. package/src/http/middleware/rate-limit.ts +54 -0
  64. package/src/http/router.ts +163 -0
  65. package/src/http/routes/brain-graph-proxy.ts +26 -6
  66. package/src/http/routes/browser-relay-websocket.ts +40 -12
  67. package/src/http/routes/channel-readiness-proxy.ts +22 -5
  68. package/src/http/routes/{ingress-control-plane-proxy.ts → contacts-control-plane-proxy.ts} +50 -24
  69. package/src/http/routes/contacts-control-plane-route-match.ts +56 -0
  70. package/src/http/routes/feature-flags.ts +49 -16
  71. package/src/http/routes/guardian-control-plane-proxy.ts +56 -11
  72. package/src/http/routes/oauth-callback.ts +11 -2
  73. package/src/http/routes/pairing-proxy.ts +38 -9
  74. package/src/http/routes/runtime-health-proxy.ts +22 -5
  75. package/src/http/routes/runtime-proxy.ts +40 -9
  76. package/src/http/routes/slack-deliver.ts +661 -29
  77. package/src/http/routes/sms-deliver.test.ts +131 -60
  78. package/src/http/routes/sms-deliver.ts +20 -8
  79. package/src/http/routes/telegram-control-plane-proxy.ts +22 -5
  80. package/src/http/routes/telegram-deliver.test.ts +24 -15
  81. package/src/http/routes/telegram-deliver.ts +81 -18
  82. package/src/http/routes/telegram-reconcile.ts +18 -5
  83. package/src/http/routes/telegram-webhook.test.ts +57 -30
  84. package/src/http/routes/telegram-webhook.ts +255 -71
  85. package/src/http/routes/twilio-connect-action-webhook.ts +16 -4
  86. package/src/http/routes/twilio-control-plane-proxy.ts +50 -11
  87. package/src/http/routes/twilio-relay-websocket.ts +38 -10
  88. package/src/http/routes/twilio-sms-webhook.test.ts +47 -19
  89. package/src/http/routes/twilio-sms-webhook.ts +58 -17
  90. package/src/http/routes/twilio-status-webhook.ts +8 -2
  91. package/src/http/routes/twilio-voice-webhook.test.ts +4 -4
  92. package/src/http/routes/twilio-voice-webhook.ts +34 -8
  93. package/src/http/routes/whatsapp-deliver.test.ts +36 -18
  94. package/src/http/routes/whatsapp-deliver.ts +80 -21
  95. package/src/http/routes/whatsapp-webhook.test.ts +134 -101
  96. package/src/http/routes/whatsapp-webhook.ts +100 -27
  97. package/src/index.ts +589 -480
  98. package/src/logger.ts +26 -5
  99. package/src/rejection-rate-limiter.ts +3 -1
  100. package/src/routing/resolve-assistant.ts +8 -2
  101. package/src/runtime/client.ts +53 -23
  102. package/src/schema.ts +327 -133
  103. package/src/slack/app-home.ts +120 -0
  104. package/src/slack/block-kit-builder.test.ts +281 -0
  105. package/src/slack/block-kit-builder.ts +229 -0
  106. package/src/slack/errors.ts +67 -0
  107. package/src/slack/normalize.test.ts +254 -0
  108. package/src/slack/normalize.ts +527 -1
  109. package/src/slack/socket-mode.ts +316 -28
  110. package/src/slack/text-to-blocks.ts +244 -0
  111. package/src/telegram/api.ts +23 -7
  112. package/src/telegram/download.ts +1 -3
  113. package/src/telegram/normalize.ts +18 -4
  114. package/src/telegram/send.test.ts +38 -18
  115. package/src/telegram/send.ts +43 -13
  116. package/src/telegram/webhook-manager.ts +6 -2
  117. package/src/twilio/send-sms.ts +8 -2
  118. package/src/twilio/validate-webhook.ts +11 -3
  119. package/src/twilio/verify.ts +1 -3
  120. package/src/types.ts +9 -1
  121. package/src/util/split-text.ts +5 -1
  122. package/src/whatsapp/api.ts +16 -4
  123. package/src/whatsapp/normalize.ts +17 -3
  124. package/src/whatsapp/send.ts +63 -17
  125. package/src/__tests__/ingress-control-plane-proxy.test.ts +0 -177
  126. package/src/__tests__/ingress-control-plane-route-match.test.ts +0 -53
  127. package/src/http/routes/ingress-control-plane-route-match.ts +0 -47
package/AGENTS.md ADDED
@@ -0,0 +1,46 @@
1
+ # Gateway — Agent Instructions
2
+
3
+ ## Public API / Webhook Ingress
4
+
5
+ All inbound HTTP endpoints — APIs, webhooks, OAuth callbacks, or any route that receives requests from the internet — **MUST** be routed through the **gateway** (`gateway/`). Never add ingresses, routes, or listeners directly to the daemon runtime (`assistant/`).
6
+
7
+ Concretely:
8
+
9
+ - Define new routes in the gateway and have the gateway forward requests to the assistant over the internal IPC/transport.
10
+ - The gateway's public URL is controlled by the **public ingress URL** setting. All externally-facing URLs you generate or advertise (callback URLs, webhook registration URLs, etc.) must be derived from this setting — never hardcode a hostname or port.
11
+ - The daemon should remain unreachable from the public internet. It only receives traffic from the gateway over the internal network.
12
+
13
+ Why: the gateway is the single point of ingress, handling TLS termination, auth, rate limiting, and routing. Exposing the daemon directly bypasses these protections and breaks the deployment model.
14
+
15
+ ### Gateway-Only API Consumption
16
+
17
+ All assistant API requests from clients, CLI, skills, and user-facing tooling **MUST** target gateway URLs. Never construct URLs using the daemon runtime port (`7821`) or `RUNTIME_HTTP_PORT` for external API consumption.
18
+
19
+ **Exception boundary:** The gateway service itself may call the runtime internally. Tests may use direct runtime URLs for isolated unit/integration scenarios. Intentional local daemon-control paths are exempt:
20
+
21
+ - `clients/shared/IPC/DaemonClient.swift`
22
+ - `clients/macos/vellum-assistant/App/AppDelegate.swift` (`localHttpEnabled`)
23
+ - `clients/macos/vellum-assistant/Features/Settings/SettingsConnectTab.swift` (health probe)
24
+
25
+ **Migration rule:** If a needed endpoint is not available at the gateway, add a gateway route/proxy first, then consume it. Do not work around a missing gateway endpoint by hitting the runtime directly.
26
+
27
+ **Ban on hardcoded runtime hosts/ports:** Do not embed `localhost:7821`, `127.0.0.1:7821`, or runtime-port-derived URLs in docs, skills, or user-facing guidance. Always reference gateway URLs instead. A CI guard test (`gateway-only-guard.test.ts`) enforces this — any new direct runtime URL reference in production code or skills will fail CI.
28
+
29
+ **SKILL.md retrieval contract:** For config/status retrieval in bundled skills, use `bash` + canonical CLI surfaces. Start with `vellum config get` for generic config keys and secure credential surfaces (`credential_store`, `vellum keys`) for secrets. Use domain read commands (for example `vellum integrations ...`, `vellum email status ...`) where those domain surfaces exist. Do not use direct gateway `curl` (or manual `Authorization: Bearer $GATEWAY_AUTH_TOKEN`) for read-only retrieval paths. Do not use keychain lookup commands (`security find-generic-password`, `secret-tool`) in SKILL.md. `host_bash` is not allowed for Vellum CLI retrieval commands unless a documented exception is intentionally allowlisted.
30
+
31
+ **SKILL.md proxied outbound pattern:** For outbound third-party API calls from skills that require stored credentials, default to `bash` with `network_mode: "proxied"` and `credential_ids` instead of manual token/keychain plumbing. This keeps credentials out of chat and enforces credential policies consistently.
32
+
33
+ **SKILL.md gateway URL pattern:** For gateway control-plane writes/actions that are not exposed through a CLI read command, use `$INTERNAL_GATEWAY_BASE_URL` (injected by `bash` and `host_bash`). `$GATEWAY_BASE_URL` is also injected and resolves to the configured public ingress URL when set (falling back to the internal gateway target). Do not hardcode `localhost`/ports in skill examples, and do not instruct users/agents to manually export either variable from Settings.
34
+
35
+ ### Channel Identity Vocabulary
36
+
37
+ Gateway inbound events use a channel-discriminated union model (`GatewayInboundEvent`) with explicit identity fields:
38
+
39
+ - **`conversationExternalId`**: Delivery/thread address (e.g., Telegram chat ID, SMS phone number). Used for conversation binding and message routing. **Not** used for trust classification.
40
+ - **`actorExternalId`**: Sender identity (e.g., Telegram user ID, WhatsApp phone number). Used for trust classification, guardian binding, and ACL enforcement. **Required** for all public channel ingress.
41
+ - **"conversation"** is canonical vocabulary for delivery addresses. "thread" is reserved for provider-specific fields (Slack `thread_ts`, email thread IDs).
42
+ - **"actor"** is canonical vocabulary for sender identity.
43
+
44
+ Trust/guardian decisions must be keyed on `actorExternalId` only — never fall back to `conversationExternalId` for actor identity.
45
+
46
+ Physical DB column names (`externalUserId`, `externalChatId`) are unchanged; the rename is at the API/type layer only.