@every-app/sdk 0.3.0-rc.1 → 0.3.0-rc.11

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 (181) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -64
  3. package/dist/cloudflare/catalogSettings.generated.d.ts +84 -0
  4. package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
  5. package/dist/cloudflare/catalogSettings.generated.js +175 -0
  6. package/dist/cloudflare/index.d.ts +3 -2
  7. package/dist/cloudflare/index.d.ts.map +1 -1
  8. package/dist/cloudflare/index.js +4 -1
  9. package/dist/cloudflare/sentinel.d.ts +60 -2
  10. package/dist/cloudflare/sentinel.d.ts.map +1 -1
  11. package/dist/cloudflare/sentinel.js +37 -2
  12. package/dist/cloudflare/worker.d.ts +391 -63
  13. package/dist/cloudflare/worker.d.ts.map +1 -1
  14. package/dist/cloudflare/worker.js +394 -108
  15. package/dist/dev/index.d.ts +1 -1
  16. package/dist/dev/index.d.ts.map +1 -1
  17. package/dist/dev/index.js +1 -1
  18. package/dist/dev/keypair.d.ts +2 -0
  19. package/dist/dev/keypair.d.ts.map +1 -1
  20. package/dist/dev/keypair.js +2 -0
  21. package/dist/index.d.ts +6 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +5 -0
  24. package/dist/internal/aiDefault.d.ts +205 -0
  25. package/dist/internal/aiDefault.d.ts.map +1 -0
  26. package/dist/internal/aiDefault.js +335 -0
  27. package/dist/internal/aiProviders.d.ts +7 -2
  28. package/dist/internal/aiProviders.d.ts.map +1 -1
  29. package/dist/internal/aiProviders.js +19 -6
  30. package/dist/internal/appSettings.d.ts +82 -4
  31. package/dist/internal/appSettings.d.ts.map +1 -1
  32. package/dist/internal/appSettings.js +204 -29
  33. package/dist/internal/audit.d.ts +108 -0
  34. package/dist/internal/audit.d.ts.map +1 -0
  35. package/dist/internal/audit.js +235 -0
  36. package/dist/internal/capabilities.d.ts +2261 -815
  37. package/dist/internal/capabilities.d.ts.map +1 -1
  38. package/dist/internal/capabilities.js +122 -1034
  39. package/dist/internal/catalog/commerce.d.ts +394 -0
  40. package/dist/internal/catalog/commerce.d.ts.map +1 -0
  41. package/dist/internal/catalog/commerce.js +477 -0
  42. package/dist/internal/catalog/comms.d.ts +375 -0
  43. package/dist/internal/catalog/comms.d.ts.map +1 -0
  44. package/dist/internal/catalog/comms.js +520 -0
  45. package/dist/internal/catalog/index.d.ts +2008 -0
  46. package/dist/internal/catalog/index.d.ts.map +1 -0
  47. package/dist/internal/catalog/index.js +19 -0
  48. package/dist/internal/catalog/inference.d.ts +393 -0
  49. package/dist/internal/catalog/inference.d.ts.map +1 -0
  50. package/dist/internal/catalog/inference.js +460 -0
  51. package/dist/internal/catalog/infra.d.ts +458 -0
  52. package/dist/internal/catalog/infra.d.ts.map +1 -0
  53. package/dist/internal/catalog/infra.js +608 -0
  54. package/dist/internal/catalog/search.d.ts +400 -0
  55. package/dist/internal/catalog/search.d.ts.map +1 -0
  56. package/dist/internal/catalog/search.js +463 -0
  57. package/dist/internal/devProviders.d.ts +2 -2
  58. package/dist/internal/devProviders.d.ts.map +1 -1
  59. package/dist/internal/devProviders.js +19 -1
  60. package/dist/internal/events.d.ts +65 -3
  61. package/dist/internal/events.d.ts.map +1 -1
  62. package/dist/internal/events.js +110 -5
  63. package/dist/internal/gatewaySettings.d.ts +3 -2
  64. package/dist/internal/gatewaySettings.d.ts.map +1 -1
  65. package/dist/internal/gatewaySettings.js +12 -6
  66. package/dist/internal/identity.d.ts +41 -4
  67. package/dist/internal/identity.d.ts.map +1 -1
  68. package/dist/internal/identity.js +48 -10
  69. package/dist/internal/index.d.ts +6 -1
  70. package/dist/internal/index.d.ts.map +1 -1
  71. package/dist/internal/index.js +6 -1
  72. package/dist/internal/members.d.ts +3 -2
  73. package/dist/internal/members.d.ts.map +1 -1
  74. package/dist/internal/oauthBuiltIns.d.ts +101 -0
  75. package/dist/internal/oauthBuiltIns.d.ts.map +1 -0
  76. package/dist/internal/oauthBuiltIns.js +122 -0
  77. package/dist/internal/oauthClient.d.ts +8 -50
  78. package/dist/internal/oauthClient.d.ts.map +1 -1
  79. package/dist/internal/oauthClient.js +2 -177
  80. package/dist/internal/oauthPresets.d.ts +32 -0
  81. package/dist/internal/oauthPresets.d.ts.map +1 -0
  82. package/dist/internal/oauthPresets.js +253 -0
  83. package/dist/internal/oauthScopes.d.ts +43 -100
  84. package/dist/internal/oauthScopes.d.ts.map +1 -1
  85. package/dist/internal/oauthScopes.js +83 -382
  86. package/dist/internal/oauthSpec.d.ts +103 -0
  87. package/dist/internal/oauthSpec.d.ts.map +1 -0
  88. package/dist/internal/oauthSpec.js +520 -0
  89. package/dist/internal/protocol.d.ts +97 -5
  90. package/dist/internal/protocol.d.ts.map +1 -1
  91. package/dist/internal/protocol.js +89 -1
  92. package/dist/internal/providerRegistry.d.ts +17 -6
  93. package/dist/internal/providerRegistry.d.ts.map +1 -1
  94. package/dist/internal/providerRegistry.js +71 -8
  95. package/dist/internal/providerSpec.d.ts +18 -7
  96. package/dist/internal/providerSpec.d.ts.map +1 -1
  97. package/dist/internal/providerSpec.js +420 -34
  98. package/dist/internal/remoteMcp.d.ts.map +1 -1
  99. package/dist/internal/remoteMcp.js +1 -5
  100. package/dist/internal/signInProviders.d.ts +104 -0
  101. package/dist/internal/signInProviders.d.ts.map +1 -0
  102. package/dist/internal/signInProviders.js +245 -0
  103. package/dist/internal/tools.d.ts +5 -4
  104. package/dist/internal/tools.d.ts.map +1 -1
  105. package/dist/internal/tools.js +4 -3
  106. package/dist/manifest.d.ts +267 -0
  107. package/dist/manifest.d.ts.map +1 -0
  108. package/dist/manifest.js +30 -0
  109. package/dist/server/ai.d.ts +111 -0
  110. package/dist/server/ai.d.ts.map +1 -0
  111. package/dist/server/ai.js +145 -0
  112. package/dist/server/aiBinding.d.ts +68 -0
  113. package/dist/server/aiBinding.d.ts.map +1 -0
  114. package/dist/server/aiBinding.js +294 -0
  115. package/dist/server/attribution.d.ts +18 -5
  116. package/dist/server/attribution.d.ts.map +1 -1
  117. package/dist/server/attribution.js +19 -5
  118. package/dist/server/connectUrl.d.ts +16 -0
  119. package/dist/server/connectUrl.d.ts.map +1 -0
  120. package/dist/server/connectUrl.js +40 -0
  121. package/dist/server/context.d.ts +68 -0
  122. package/dist/server/context.d.ts.map +1 -0
  123. package/dist/server/context.js +117 -0
  124. package/dist/server/emailBinding.d.ts +72 -0
  125. package/dist/server/emailBinding.d.ts.map +1 -0
  126. package/dist/server/emailBinding.js +124 -0
  127. package/dist/server/emit.d.ts +1 -1
  128. package/dist/server/emit.d.ts.map +1 -1
  129. package/dist/server/emit.js +7 -7
  130. package/dist/server/env.d.ts +44 -0
  131. package/dist/server/env.d.ts.map +1 -0
  132. package/dist/server/env.js +1 -0
  133. package/dist/server/eventsEndpoint.d.ts +48 -0
  134. package/dist/server/eventsEndpoint.d.ts.map +1 -0
  135. package/dist/server/eventsEndpoint.js +145 -0
  136. package/dist/server/everyApp.d.ts +40 -11
  137. package/dist/server/everyApp.d.ts.map +1 -1
  138. package/dist/server/everyApp.js +116 -6
  139. package/dist/server/fromMcpTools.d.ts +89 -0
  140. package/dist/server/fromMcpTools.d.ts.map +1 -0
  141. package/dist/server/fromMcpTools.js +192 -0
  142. package/dist/server/gatewayFetch.d.ts +42 -18
  143. package/dist/server/gatewayFetch.d.ts.map +1 -1
  144. package/dist/server/gatewayFetch.js +138 -19
  145. package/dist/server/gatewayUrl.d.ts +13 -0
  146. package/dist/server/gatewayUrl.d.ts.map +1 -0
  147. package/dist/server/gatewayUrl.js +34 -0
  148. package/dist/server/index.d.ts +16 -4
  149. package/dist/server/index.d.ts.map +1 -1
  150. package/dist/server/index.js +13 -3
  151. package/dist/server/integrationFetch.d.ts +92 -73
  152. package/dist/server/integrationFetch.d.ts.map +1 -1
  153. package/dist/server/integrationFetch.js +206 -319
  154. package/dist/server/listMembers.d.ts +1 -1
  155. package/dist/server/listMembers.d.ts.map +1 -1
  156. package/dist/server/listMembers.js +8 -11
  157. package/dist/server/refusal.d.ts +55 -0
  158. package/dist/server/refusal.d.ts.map +1 -0
  159. package/dist/server/refusal.js +193 -0
  160. package/dist/server/sendEmail.d.ts +1 -1
  161. package/dist/server/sendEmail.d.ts.map +1 -1
  162. package/dist/server/sendEmail.js +7 -7
  163. package/dist/server/tools.d.ts +7 -2
  164. package/dist/server/tools.d.ts.map +1 -1
  165. package/dist/server/tools.js +2 -1
  166. package/dist/server/toolsEndpoint.d.ts +3 -1
  167. package/dist/server/toolsEndpoint.d.ts.map +1 -1
  168. package/dist/server/toolsEndpoint.js +19 -7
  169. package/dist/server/webhooks.d.ts +56 -0
  170. package/dist/server/webhooks.d.ts.map +1 -0
  171. package/dist/server/webhooks.js +205 -0
  172. package/dist/tanstack-start/index.d.ts +9 -0
  173. package/dist/tanstack-start/index.d.ts.map +1 -0
  174. package/dist/tanstack-start/index.js +29 -0
  175. package/dist/testing/index.d.ts +93 -0
  176. package/dist/testing/index.d.ts.map +1 -0
  177. package/dist/testing/index.js +156 -0
  178. package/package.json +35 -14
  179. package/dist/server/authorizeUrl.d.ts +0 -43
  180. package/dist/server/authorizeUrl.d.ts.map +0 -1
  181. package/dist/server/authorizeUrl.js +0 -110
@@ -1,8 +1,8 @@
1
1
  import { ConfigurationError, serviceRoutePath, } from "../internal/index.js";
2
- import { applyAttribution, checkAttribution, isRequest, } from "./attribution.js";
2
+ import { applyAttribution, attributionFor, isRequest, } from "./attribution.js";
3
3
  import { getEveryAppUser } from "./everyApp.js";
4
- import { BINDING_ORIGIN } from "./gatewayFetch.js";
5
- import { GatewayRefusalError, gatewayRefusal } from "./integrationFetch.js";
4
+ import { BINDING_ORIGIN, gatewayBinding, } from "./gatewayFetch.js";
5
+ import { GatewayRefusalError, gatewayRefusal } from "./refusal.js";
6
6
  /**
7
7
  * The organization's members who can open the app now, through the
8
8
  * gateway's `members` capability: people deactivated, removed from the
@@ -19,10 +19,10 @@ import { GatewayRefusalError, gatewayRefusal } from "./integrationFetch.js";
19
19
  * for a request answers its signed-in user alone, and background work
20
20
  * answers no one.
21
21
  */
22
- export async function listMembers({ env, for: target, }) {
23
- checkAttribution(env, target, "listMembers");
22
+ export async function listMembers({ env, for: explicitTarget, }) {
23
+ const target = attributionFor(env, explicitTarget, "listMembers");
24
24
  const values = env;
25
- const binding = values["EVERY_APP_GATEWAY"];
25
+ const binding = gatewayBinding(env);
26
26
  if (binding) {
27
27
  if (typeof binding.fetch !== "function") {
28
28
  throw new ConfigurationError("EVERY_APP_GATEWAY is configured but is not a valid service binding.");
@@ -48,7 +48,7 @@ async function listThroughGateway(binding, target) {
48
48
  throw new GatewayRefusalError({
49
49
  status: response.status,
50
50
  code: "members_list_failed",
51
- message: `The Every App gateway answered ${response.status} to the members list.`,
51
+ message: `The EveryApp gateway answered ${response.status} to the members list.`,
52
52
  });
53
53
  }
54
54
  return (await response.json());
@@ -64,11 +64,8 @@ async function listInDev(env, target) {
64
64
  id: user.id,
65
65
  email: user.email,
66
66
  name: "",
67
- role: memberRole(user.orgRole),
67
+ role: user.orgRole,
68
68
  },
69
69
  ],
70
70
  };
71
71
  }
72
- function memberRole(role) {
73
- return role === "owner" || role === "admin" ? role : "member";
74
- }
@@ -0,0 +1,55 @@
1
+ /** What would make it work, as the Gateway words it. */
2
+ export interface SetupInfo {
3
+ /** The Gateway settings it needs (`["DATAFORSEO_API_KEY"]`); `[]` when ready or not a setting. */
4
+ settings: readonly string[];
5
+ /** One sentence for a person, naming what to set and how; null when ready. */
6
+ setup: string | null;
7
+ /** The command an admin runs (`pnpm everyapp configure crm`), or null. */
8
+ command: string | null;
9
+ }
10
+ /** A refusal the AppGateway binding made itself, not the provider. */
11
+ export interface GatewayRefusal extends SetupInfo {
12
+ status: number;
13
+ /** e.g. `capability_not_requested`, `integration_not_configured`. */
14
+ code: string;
15
+ message: string;
16
+ }
17
+ /** The refusal codes that mean no model is set up for the call. */
18
+ export declare const AI_NOT_CONFIGURED_CODES: readonly string[];
19
+ /**
20
+ * A refusal the AppGateway binding made, thrown: what `sendEmail()` throws
21
+ * when the gateway won't send (`email_sender_not_allowed`,
22
+ * `email_budget_exhausted`, ...). The thrown twin of {@link gatewayRefusal}.
23
+ */
24
+ export declare class GatewayRefusalError extends Error implements GatewayRefusal {
25
+ readonly status: number;
26
+ readonly code: string;
27
+ readonly settings: readonly string[];
28
+ readonly setup: string | null;
29
+ readonly command: string | null;
30
+ constructor({ status, code, message, settings, setup, command, }: Pick<GatewayRefusal, "status" | "code" | "message"> & Partial<SetupInfo>);
31
+ }
32
+ /**
33
+ * The gateway's own refusal in `response`, or null when the response is the
34
+ * provider's answer (which may be an error of its own). Reads the body only
35
+ * for a refusal, so call it before reading the body yourself.
36
+ */
37
+ export declare function gatewayRefusal(response: Response): Promise<GatewayRefusal | null>;
38
+ /**
39
+ * The Gateway's refusal behind a thrown error, or null when it isn't one:
40
+ * a {@link GatewayRefusalError} (`sendEmail()`, `listMembers()`, `emit()`),
41
+ * an OpenAI SDK `APIError` or an ai-sdk `APICallError` for a call the
42
+ * Gateway refused (also inside ai-sdk's `RetryError` or an error's
43
+ * `cause`), or the SDK's local-development `ConfigurationError` for a
44
+ * missing key, which answers as the deployed refusal would
45
+ * (`ai_provider_not_configured`, status 503, the `.dev.vars` names).
46
+ */
47
+ export declare function refusalFromError(error: unknown): GatewayRefusal | null;
48
+ /**
49
+ * Whether `error` (or a refusal already read) means no model is set up:
50
+ * `ai_provider_not_configured` or `ai_default_not_configured`, from the
51
+ * Gateway or, in local development, from the SDK with no key in
52
+ * `.dev.vars`. Show `refusalFromError(error).setup` to the person.
53
+ */
54
+ export declare function isAiNotConfigured(error: unknown): boolean;
55
+ //# sourceMappingURL=refusal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refusal.d.ts","sourceRoot":"","sources":["../../src/server/refusal.ts"],"names":[],"mappings":"AAgBA,wDAAwD;AACxD,MAAM,WAAW,SAAS;IACxB,kGAAkG;IAClG,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,8EAA8E;IAC9E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,sEAAsE;AACtE,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,mEAAmE;AACnE,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAGpD,CAAC;AAEF;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAM,YAAW,cAAc;IACtE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEpB,EACV,MAAM,EACN,IAAI,EACJ,OAAO,EACP,QAAa,EACb,KAAY,EACZ,OAAc,GACf,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;CAS5E;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAKhC;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAWtE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGzD"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * The Gateway's own refusals, read the same way wherever they surface: a
3
+ * `Response` from a gateway fetch ({@link gatewayRefusal}), the error an
4
+ * SDK helper throws ({@link GatewayRefusalError}), or the error an AI
5
+ * client throws for a refused call (an OpenAI SDK's `APIError`, ai-sdk's
6
+ * `APICallError`) ({@link refusalFromError}).
7
+ *
8
+ * A refusal that means "not set up" (`integration_not_configured`,
9
+ * `ai_provider_not_configured`, `ai_default_not_configured`) carries what
10
+ * to do in the Gateway's words: `settings` (the setting names it needs),
11
+ * `setup` (one sentence for a person) and `command` (what an admin runs,
12
+ * `pnpm everyapp configure <app>`, or null). Show them as they are; never
13
+ * match the message text or hardcode a setting name or a command.
14
+ */
15
+ import { ConfigurationError, GATEWAY_ERROR_HEADER } from "../internal/index.js";
16
+ /** The refusal codes that mean no model is set up for the call. */
17
+ export const AI_NOT_CONFIGURED_CODES = [
18
+ "ai_provider_not_configured",
19
+ "ai_default_not_configured",
20
+ ];
21
+ /**
22
+ * A refusal the AppGateway binding made, thrown: what `sendEmail()` throws
23
+ * when the gateway won't send (`email_sender_not_allowed`,
24
+ * `email_budget_exhausted`, ...). The thrown twin of {@link gatewayRefusal}.
25
+ */
26
+ export class GatewayRefusalError extends Error {
27
+ status;
28
+ code;
29
+ settings;
30
+ setup;
31
+ command;
32
+ constructor({ status, code, message, settings = [], setup = null, command = null, }) {
33
+ super(message);
34
+ this.name = "GatewayRefusalError";
35
+ this.status = status;
36
+ this.code = code;
37
+ this.settings = settings;
38
+ this.setup = setup;
39
+ this.command = command;
40
+ }
41
+ }
42
+ /**
43
+ * The gateway's own refusal in `response`, or null when the response is the
44
+ * provider's answer (which may be an error of its own). Reads the body only
45
+ * for a refusal, so call it before reading the body yourself.
46
+ */
47
+ export async function gatewayRefusal(response) {
48
+ const code = response.headers.get(GATEWAY_ERROR_HEADER);
49
+ if (!code)
50
+ return null;
51
+ const body = await response.json().catch(() => null);
52
+ return refusalOf(response.status, code, body);
53
+ }
54
+ /**
55
+ * The Gateway's refusal behind a thrown error, or null when it isn't one:
56
+ * a {@link GatewayRefusalError} (`sendEmail()`, `listMembers()`, `emit()`),
57
+ * an OpenAI SDK `APIError` or an ai-sdk `APICallError` for a call the
58
+ * Gateway refused (also inside ai-sdk's `RetryError` or an error's
59
+ * `cause`), or the SDK's local-development `ConfigurationError` for a
60
+ * missing key, which answers as the deployed refusal would
61
+ * (`ai_provider_not_configured`, status 503, the `.dev.vars` names).
62
+ */
63
+ export function refusalFromError(error) {
64
+ const seen = new Set();
65
+ let current = error;
66
+ while (current && typeof current === "object" && !seen.has(current)) {
67
+ seen.add(current);
68
+ const found = refusalHere(current);
69
+ if (found)
70
+ return found;
71
+ const record = current;
72
+ current = record["lastError"] ?? record["cause"];
73
+ }
74
+ return null;
75
+ }
76
+ /**
77
+ * Whether `error` (or a refusal already read) means no model is set up:
78
+ * `ai_provider_not_configured` or `ai_default_not_configured`, from the
79
+ * Gateway or, in local development, from the SDK with no key in
80
+ * `.dev.vars`. Show `refusalFromError(error).setup` to the person.
81
+ */
82
+ export function isAiNotConfigured(error) {
83
+ const refusal = isRefusal(error) ? error : refusalFromError(error);
84
+ return refusal !== null && AI_NOT_CONFIGURED_CODES.includes(refusal.code);
85
+ }
86
+ function isRefusal(value) {
87
+ return (!!value &&
88
+ typeof value === "object" &&
89
+ !(value instanceof Error) &&
90
+ typeof value.code === "string" &&
91
+ typeof value.status === "number");
92
+ }
93
+ function refusalHere(error) {
94
+ // A Response is read with gatewayRefusal(), which can read its body.
95
+ if (error instanceof Response)
96
+ return null;
97
+ if (error instanceof GatewayRefusalError) {
98
+ return {
99
+ status: error.status,
100
+ code: error.code,
101
+ message: error.message,
102
+ settings: error.settings,
103
+ setup: error.setup,
104
+ command: error.command,
105
+ };
106
+ }
107
+ if (error instanceof ConfigurationError) {
108
+ if (!error.code)
109
+ return null;
110
+ return {
111
+ status: 503,
112
+ code: error.code,
113
+ message: error.message,
114
+ settings: error.settings,
115
+ setup: error.message,
116
+ command: null,
117
+ };
118
+ }
119
+ const record = error;
120
+ // ai-sdk's APICallError: lowercase header names, the body as text.
121
+ const responseHeaders = record["responseHeaders"];
122
+ if (responseHeaders && typeof responseHeaders === "object") {
123
+ const code = headerOf(responseHeaders, GATEWAY_ERROR_HEADER);
124
+ if (!code)
125
+ return null;
126
+ return refusalOf(numberOf(record["statusCode"]), code, parseJson(record["responseBody"]), messageOf(error));
127
+ }
128
+ // An OpenAI SDK APIError: `headers` (Headers or a record), `status`,
129
+ // and `error`, the body's `error` object (which carries the same fields).
130
+ const headers = record["headers"];
131
+ if (headers && typeof headers === "object" && "status" in record) {
132
+ const code = headerOf(headers, GATEWAY_ERROR_HEADER);
133
+ if (!code)
134
+ return null;
135
+ return refusalOf(numberOf(record["status"]), code, record["error"], messageOf(error));
136
+ }
137
+ return null;
138
+ }
139
+ /** A refusal from its status, code and body (the Gateway's `{ code, message, … }`, or OpenAI's `{ error: {…} }`). */
140
+ function refusalOf(status, code, body, fallback) {
141
+ const top = recordOf(body);
142
+ const inner = recordOf(top?.["error"]);
143
+ const field = (name) => top?.[name] ?? inner?.[name];
144
+ const message = stringOf(top?.["message"]) ??
145
+ stringOf(inner?.["message"]) ??
146
+ fallback ??
147
+ `The EveryApp gateway refused the call (${code}).`;
148
+ const settings = field("settings");
149
+ return {
150
+ status,
151
+ code,
152
+ message,
153
+ settings: Array.isArray(settings)
154
+ ? settings.filter((name) => typeof name === "string")
155
+ : [],
156
+ setup: stringOf(field("setup")) ?? null,
157
+ command: stringOf(field("command")) ?? null,
158
+ };
159
+ }
160
+ function headerOf(headers, name) {
161
+ if (typeof headers.get === "function") {
162
+ return headers.get(name);
163
+ }
164
+ for (const [key, value] of Object.entries(headers)) {
165
+ if (key.toLowerCase() === name && typeof value === "string")
166
+ return value;
167
+ }
168
+ return null;
169
+ }
170
+ function recordOf(value) {
171
+ return value && typeof value === "object" && !Array.isArray(value)
172
+ ? value
173
+ : null;
174
+ }
175
+ function stringOf(value) {
176
+ return typeof value === "string" && value ? value : undefined;
177
+ }
178
+ function numberOf(value) {
179
+ return typeof value === "number" ? value : 0;
180
+ }
181
+ function parseJson(value) {
182
+ if (typeof value !== "string")
183
+ return null;
184
+ try {
185
+ return JSON.parse(value);
186
+ }
187
+ catch {
188
+ return null;
189
+ }
190
+ }
191
+ function messageOf(error) {
192
+ return error instanceof Error && error.message ? error.message : undefined;
193
+ }
@@ -35,5 +35,5 @@ export interface SendEmailOptions {
35
35
  * `.dev.vars` it goes out for real through Email Sending's REST API, from
36
36
  * the developer's own account.
37
37
  */
38
- export declare function sendEmail({ env, for: target, message, }: SendEmailOptions): Promise<SendEmailResult>;
38
+ export declare function sendEmail({ env, for: explicitTarget, message, }: SendEmailOptions): Promise<SendEmailResult>;
39
39
  //# sourceMappingURL=sendEmail.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sendEmail.d.ts","sourceRoot":"","sources":["../../src/server/sendEmail.ts"],"names":[],"mappings":"AAAA,OAAO,EAeL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,SAAS,CAAC,EAC9B,GAAG,EACH,GAAG,EAAE,MAAM,EACX,OAAO,GACR,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAoB7C"}
1
+ {"version":3,"file":"sendEmail.d.ts","sourceRoot":"","sources":["../../src/server/sendEmail.ts"],"names":[],"mappings":"AAAA,OAAO,EAeL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAQ1B,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,SAAS,CAAC,EAC9B,GAAG,EACH,GAAG,EAAE,cAAc,EACnB,OAAO,GACR,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAkB7C"}
@@ -1,7 +1,7 @@
1
1
  import { ConfigurationError, EMAIL_SENDERS_ENV, emailDomain, emailProviderRefusal, emailRestBody, emailRestUrl, emailSenderRefusal, parseEmailList, parseEmailSender, parseSendEmailMessage, readEmailRestResponse, senderAllowed, serviceRoutePath, } from "../internal/index.js";
2
- import { applyAttribution, checkAttribution, } from "./attribution.js";
3
- import { BINDING_ORIGIN } from "./gatewayFetch.js";
4
- import { GatewayRefusalError, gatewayRefusal } from "./integrationFetch.js";
2
+ import { applyAttribution, attributionFor, } from "./attribution.js";
3
+ import { BINDING_ORIGIN, gatewayBinding, } from "./gatewayFetch.js";
4
+ import { GatewayRefusalError, gatewayRefusal } from "./refusal.js";
5
5
  /**
6
6
  * Send an email through the gateway's `email` capability: its sender
7
7
  * (EMAIL_FROM) unless `message.from` names an address the installation's
@@ -19,10 +19,10 @@ import { GatewayRefusalError, gatewayRefusal } from "./integrationFetch.js";
19
19
  * `.dev.vars` it goes out for real through Email Sending's REST API, from
20
20
  * the developer's own account.
21
21
  */
22
- export async function sendEmail({ env, for: target, message, }) {
23
- checkAttribution(env, target, "sendEmail");
22
+ export async function sendEmail({ env, for: explicitTarget, message, }) {
23
+ const target = attributionFor(env, explicitTarget, "sendEmail");
24
24
  const values = env;
25
- const binding = values["EVERY_APP_GATEWAY"];
25
+ const binding = gatewayBinding(env);
26
26
  if (binding) {
27
27
  if (typeof binding.fetch !== "function") {
28
28
  throw new ConfigurationError("EVERY_APP_GATEWAY is configured but is not a valid service binding.");
@@ -49,7 +49,7 @@ async function sendThroughGateway(binding, target, message) {
49
49
  throw new GatewayRefusalError({
50
50
  status: response.status,
51
51
  code: "email_send_failed",
52
- message: `The Every App gateway answered ${response.status} to the send.`,
52
+ message: `The EveryApp gateway answered ${response.status} to the send.`,
53
53
  });
54
54
  }
55
55
  return (await response.json());
@@ -17,7 +17,8 @@
17
17
  *
18
18
  * Apps never speak MCP. The gateway snapshots this catalog at deploy, serves
19
19
  * MCP clients from the snapshot, and calls a tool over the internal tools
20
- * contract (../internal/tools.ts) with a verified `chan: "mcp"` identity.
20
+ * contract (../internal/tools.ts) with a verified `chan: "mcp"` or
21
+ * `chan: "agent"` identity.
21
22
  *
22
23
  * `input` and `output` accept any validator implementing Standard Schema and
23
24
  * Standard JSON Schema (zod >= 4.2 does both), or a plain
@@ -81,7 +82,11 @@ export interface PlainToolSchema<Output = unknown> {
81
82
  export type ToolSchema<Output = unknown> = StandardSchemaWithJSON<unknown, Output> | PlainToolSchema<Output>;
82
83
  /** What a tool handler receives besides its validated input. */
83
84
  export interface ToolContext<TEnv = Cloudflare.Env> {
84
- /** The verified caller. `channel` is "mcp"; `toolCall` names this call. */
85
+ /**
86
+ * The verified caller. `channel` is "mcp" (an AI client) or "agent" (an
87
+ * agent principal: `isAgentCall(user)`, `actor.sub` `agent:<id>`, `id`
88
+ * its sponsor); `toolCall` names this call.
89
+ */
85
90
  user: EveryAppUser;
86
91
  env: TEnv;
87
92
  ctx: ExecutionContextLike;
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,8 @@
17
17
  *
18
18
  * Apps never speak MCP. The gateway snapshots this catalog at deploy, serves
19
19
  * MCP clients from the snapshot, and calls a tool over the internal tools
20
- * contract (../internal/tools.ts) with a verified `chan: "mcp"` identity.
20
+ * contract (../internal/tools.ts) with a verified `chan: "mcp"` or
21
+ * `chan: "agent"` identity.
21
22
  *
22
23
  * `input` and `output` accept any validator implementing Standard Schema and
23
24
  * Standard JSON Schema (zod >= 4.2 does both), or a plain
@@ -7,7 +7,9 @@
7
7
  * - `/__everyapp/tools/list` needs the gateway's system token for this app
8
8
  * (purpose "tools.list"). It describes tools; it never runs them.
9
9
  * - `/__everyapp/tools/call` needs an identity token minted for this exact
10
- * call: `chan: "mcp"` plus a `tc` claim naming the tool and call id. The
10
+ * call: `chan: "mcp"` (an AI client's MCP connection) or `chan: "agent"`
11
+ * (an agent principal, `act.sub` `agent:<id>`, with its sponsor as `sub`),
12
+ * plus a `tc` claim naming the tool and call id. The
11
13
  * token's scopes must include the scope the tool's risk requires; `*` does
12
14
  * not count, because the ToolBus only ever mints explicit scopes.
13
15
  *
@@ -1 +1 @@
1
- {"version":3,"file":"toolsEndpoint.d.ts","sourceRoot":"","sources":["../../src/server/toolsEndpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAcL,KAAK,sBAAsB,EAO5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAOL,KAAK,OAAO,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,sBAAsB,CAAC;CAClC;AAoFD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,oBAAoB,EACzB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAyB1B"}
1
+ {"version":3,"file":"toolsEndpoint.d.ts","sourceRoot":"","sources":["../../src/server/toolsEndpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAgBL,KAAK,sBAAsB,EAO5B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAOL,KAAK,OAAO,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,sBAAsB,CAAC;CAClC;AAoFD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,oBAAoB,EACzB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAyB1B"}
@@ -7,14 +7,17 @@
7
7
  * - `/__everyapp/tools/list` needs the gateway's system token for this app
8
8
  * (purpose "tools.list"). It describes tools; it never runs them.
9
9
  * - `/__everyapp/tools/call` needs an identity token minted for this exact
10
- * call: `chan: "mcp"` plus a `tc` claim naming the tool and call id. The
10
+ * call: `chan: "mcp"` (an AI client's MCP connection) or `chan: "agent"`
11
+ * (an agent principal, `act.sub` `agent:<id>`, with its sponsor as `sub`),
12
+ * plus a `tc` claim naming the tool and call id. The
11
13
  * token's scopes must include the scope the tool's risk requires; `*` does
12
14
  * not count, because the ToolBus only ever mints explicit scopes.
13
15
  *
14
16
  * The perimeter also refuses these paths from outside and strips inbound
15
17
  * `x-everyapp-*` headers, so only the gateway's ToolBus ever reaches them.
16
18
  */
17
- import { ConfigurationError, IDENTITY_HEADER, IdentityError, SYSTEM_HEADER, TOOLS_CALL_PATH, TOOLS_LIST_PATH, TOOLS_PROTOCOL_VERSION, catalogHash, requiredScopeForRisk, resolveVerifyOptions, verifyIdentityJwt, verifySystemJwt, } from "../internal/index.js";
19
+ import { ConfigurationError, IDENTITY_HEADER, IdentityError, SYSTEM_HEADER, TOOL_CALL_CHANNELS, TOOLS_CALL_PATH, TOOLS_LIST_PATH, TOOLS_PROTOCOL_VERSION, assertOrganizationPin, catalogHash, isAgentCall, requiredScopeForRisk, resolveVerifyOptions, verifyIdentity, verifySystemJwt, } from "../internal/index.js";
20
+ import { serveRequest } from "./context.js";
18
21
  import { SDK_VERSION, ToolError, toToolResult, toolSetInternals, validateWithSchema, } from "./tools.js";
19
22
  function toolsJson(status, body, headers = {}) {
20
23
  return Response.json(body, {
@@ -148,9 +151,12 @@ function parseCallRequest(body) {
148
151
  return { v: TOOLS_PROTOCOL_VERSION, name, arguments: args, callId };
149
152
  }
150
153
  async function callTool(request, env, ctx, verify, options) {
151
- let user;
154
+ let user, expiresAt;
152
155
  try {
153
- user = await verifyIdentityJwt(request.headers.get(IDENTITY_HEADER) ?? "", verify);
156
+ ({ user, expiresAt } = await verifyIdentity(request.headers.get(IDENTITY_HEADER) ?? "", verify));
157
+ // The same pin as the handler path: a call for another organization's
158
+ // install never runs a tool here.
159
+ assertOrganizationPin(user, options.identity.organizationId);
154
160
  }
155
161
  catch (error) {
156
162
  if (error instanceof IdentityError) {
@@ -158,7 +164,11 @@ async function callTool(request, env, ctx, verify, options) {
158
164
  }
159
165
  throw error;
160
166
  }
161
- if (user.channel !== "mcp" || !user.toolCall) {
167
+ if (!TOOL_CALL_CHANNELS.includes(user.channel) ||
168
+ !user.toolCall ||
169
+ // An agent call names its agent; a `chan: "agent"` token without one
170
+ // is not something the ToolBus mints.
171
+ (user.channel === "agent" && !isAgentCall(user))) {
162
172
  return toolsError(403, "forbidden", "Tool calls need an identity the gateway minted for this call.");
163
173
  }
164
174
  const call = parseCallRequest(await readJsonBody(request));
@@ -194,13 +204,15 @@ async function callTool(request, env, ctx, verify, options) {
194
204
  });
195
205
  let result;
196
206
  try {
197
- const value = await tool.handler(input.value, {
207
+ // The call runs in the request context like a page would: currentUser()
208
+ // is the caller, and its Gateway calls are attributed to them.
209
+ const value = await serveRequest({ request, user, expiresAt }, () => tool.handler(input.value, {
198
210
  user,
199
211
  env: env,
200
212
  ctx,
201
213
  request,
202
214
  callId: call.callId,
203
- });
215
+ }));
204
216
  result = await toToolResult(tool, value);
205
217
  }
206
218
  catch (error) {
@@ -0,0 +1,56 @@
1
+ export type WebhookProvider = "slack" | "github" | "everyapp";
2
+ export interface VerifyWebhookOptions {
3
+ provider: WebhookProvider;
4
+ /** The signing secret, or several while one rotates. Empty ones are ignored. */
5
+ secret: string | readonly string[];
6
+ /** How far a signed timestamp may be from now (Slack, EveryApp). Default 300 s. */
7
+ toleranceSeconds?: number;
8
+ /** The largest body read before giving up. Default 5 MiB. */
9
+ maxBytes?: number;
10
+ /** The clock, for tests. */
11
+ now?: Date;
12
+ }
13
+ export type WebhookRefusalReason =
14
+ /** No usable secret was passed: a configuration fault, never the sender's. */
15
+ "no_secret"
16
+ /** The provider's signature header is absent. */
17
+ | "missing_signature"
18
+ /** A signature or timestamp header that isn't the provider's shape. */
19
+ | "malformed"
20
+ /** The signed timestamp is outside the tolerance. */
21
+ | "expired"
22
+ /** The body is larger than `maxBytes`. */
23
+ | "too_large"
24
+ /** The body was already read, or its stream failed mid-read. */
25
+ | "unreadable"
26
+ /** No secret verifies the signature. */
27
+ | "mismatch";
28
+ export type WebhookVerification = {
29
+ ok: true;
30
+ /** The body exactly as signed. The request's own body is consumed: parse this. */
31
+ body: string;
32
+ /** The provider's id for this delivery, for deduplication; null when it sends none. */
33
+ deliveryId: string | null;
34
+ /** The signed timestamp in seconds; null for GitHub, which signs none. */
35
+ timestamp: number | null;
36
+ } | {
37
+ ok: false;
38
+ reason: WebhookRefusalReason;
39
+ };
40
+ /** The default body limit: well above Slack's payloads and most of GitHub's (whose cap is 25 MB). */
41
+ export declare const WEBHOOK_MAX_BYTES_DEFAULT: number;
42
+ /**
43
+ * Verify `request` as a `provider` webhook signed with `secret`. Reads the
44
+ * body (at most `maxBytes`) and returns it on success; never throws for a
45
+ * bad delivery, so a handler answers `401` on `{ ok: false }`. Throws a
46
+ * `TypeError` only for a programming error: an unknown `provider`, or a
47
+ * `toleranceSeconds` or `maxBytes` that is negative, NaN or infinite.
48
+ *
49
+ * ```ts
50
+ * const check = await verifyWebhook(request, { provider: "slack", secret: env.SLACK_SIGNING_SECRET });
51
+ * if (!check.ok) return new Response(null, { status: 401 });
52
+ * const params = new URLSearchParams(check.body);
53
+ * ```
54
+ */
55
+ export declare function verifyWebhook(request: Request, options: VerifyWebhookOptions): Promise<WebhookVerification>;
56
+ //# sourceMappingURL=webhooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/server/webhooks.ts"],"names":[],"mappings":"AAiCA,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,eAAe,CAAC;IAC1B,gFAAgF;IAChF,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACnC,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,MAAM,oBAAoB;AAC9B,8EAA8E;AAC5E,WAAW;AACb,iDAAiD;GAC/C,mBAAmB;AACrB,uEAAuE;GACrE,WAAW;AACb,qDAAqD;GACnD,SAAS;AACX,0CAA0C;GACxC,WAAW;AACb,gEAAgE;GAC9D,YAAY;AACd,wCAAwC;GACtC,UAAU,CAAC;AAEf,MAAM,MAAM,mBAAmB,GAC3B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0EAA0E;IAC1E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAEhD,qGAAqG;AACrG,eAAO,MAAM,yBAAyB,QAAkB,CAAC;AAMzD;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CA4D9B"}