@databricks/appkit 0.82.0 → 0.84.0

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 (225) hide show
  1. package/CLAUDE.md +21 -1
  2. package/dist/agents/databricks.d.ts +15 -3
  3. package/dist/agents/databricks.d.ts.map +1 -1
  4. package/dist/agents/databricks.js +25 -8
  5. package/dist/agents/databricks.js.map +1 -1
  6. package/dist/appkit/package.js +1 -1
  7. package/dist/beta.d.ts +2 -2
  8. package/dist/cache/index.d.ts.map +1 -1
  9. package/dist/cache/index.js +6 -1
  10. package/dist/cache/index.js.map +1 -1
  11. package/dist/cli/commands/agent/eval.js +1 -1
  12. package/dist/cli/commands/generate-types.js +1 -1
  13. package/dist/cli/commands/plugin/sync/sync.js +28 -15
  14. package/dist/cli/commands/plugin/sync/sync.js.map +1 -1
  15. package/dist/cli/commands/registry/add.js +3 -11
  16. package/dist/cli/commands/registry/add.js.map +1 -1
  17. package/dist/cli/commands/registry/config-writer.js +1 -1
  18. package/dist/connectors/lakebase/index.js +1 -1
  19. package/dist/connectors/lakebase/routing-pool.d.ts +1 -1
  20. package/dist/connectors/lakebase/routing-pool.d.ts.map +1 -1
  21. package/dist/connectors/lakebase/routing-pool.js +6 -12
  22. package/dist/connectors/lakebase/routing-pool.js.map +1 -1
  23. package/dist/context/caller-context.d.ts +25 -0
  24. package/dist/context/caller-context.d.ts.map +1 -0
  25. package/dist/context/caller-context.js +21 -0
  26. package/dist/context/caller-context.js.map +1 -0
  27. package/dist/context/deprecation.js +14 -0
  28. package/dist/context/deprecation.js.map +1 -0
  29. package/dist/context/execution-context.d.ts +40 -4
  30. package/dist/context/execution-context.d.ts.map +1 -1
  31. package/dist/context/execution-context.js +87 -33
  32. package/dist/context/execution-context.js.map +1 -1
  33. package/dist/context/index.d.ts +3 -2
  34. package/dist/context/index.js +3 -1
  35. package/dist/context/request-scope.d.ts +2 -0
  36. package/dist/context/request-scope.js +39 -0
  37. package/dist/context/request-scope.js.map +1 -0
  38. package/dist/context/resource-capabilities.js +59 -0
  39. package/dist/context/resource-capabilities.js.map +1 -0
  40. package/dist/context/scoped-api.js +104 -0
  41. package/dist/context/scoped-api.js.map +1 -0
  42. package/dist/context/service-context.d.ts +18 -12
  43. package/dist/context/service-context.d.ts.map +1 -1
  44. package/dist/context/service-context.js +45 -55
  45. package/dist/context/service-context.js.map +1 -1
  46. package/dist/context/user-context.d.ts +16 -22
  47. package/dist/context/user-context.d.ts.map +1 -1
  48. package/dist/context/user-context.js +57 -3
  49. package/dist/context/user-context.js.map +1 -1
  50. package/dist/core/agent/load-agents.d.ts.map +1 -1
  51. package/dist/core/agent/load-agents.js +5 -2
  52. package/dist/core/agent/load-agents.js.map +1 -1
  53. package/dist/core/agent/run-agent.d.ts +19 -6
  54. package/dist/core/agent/run-agent.d.ts.map +1 -1
  55. package/dist/core/agent/run-agent.js +53 -17
  56. package/dist/core/agent/run-agent.js.map +1 -1
  57. package/dist/core/agent/types.d.ts +18 -1
  58. package/dist/core/agent/types.d.ts.map +1 -1
  59. package/dist/core/agent/types.js.map +1 -1
  60. package/dist/core/appkit.d.ts +4 -3
  61. package/dist/core/appkit.d.ts.map +1 -1
  62. package/dist/core/appkit.js +34 -11
  63. package/dist/core/appkit.js.map +1 -1
  64. package/dist/core/plugin-context.d.ts +14 -15
  65. package/dist/core/plugin-context.d.ts.map +1 -1
  66. package/dist/core/plugin-context.js +24 -14
  67. package/dist/core/plugin-context.js.map +1 -1
  68. package/dist/errors/base.d.ts +2 -2
  69. package/dist/errors/base.js +2 -2
  70. package/dist/errors/base.js.map +1 -1
  71. package/dist/errors/identity-expired.d.ts +14 -0
  72. package/dist/errors/identity-expired.d.ts.map +1 -0
  73. package/dist/errors/identity-expired.js +33 -0
  74. package/dist/errors/identity-expired.js.map +1 -0
  75. package/dist/errors/index.js +1 -0
  76. package/dist/index.d.ts +12 -6
  77. package/dist/index.js +7 -2
  78. package/dist/logging/logger.js +1 -1
  79. package/dist/plugin/execution-result.d.ts +4 -1
  80. package/dist/plugin/execution-result.d.ts.map +1 -1
  81. package/dist/plugin/interceptors/telemetry.js +6 -4
  82. package/dist/plugin/interceptors/telemetry.js.map +1 -1
  83. package/dist/plugin/plugin.d.ts +14 -22
  84. package/dist/plugin/plugin.d.ts.map +1 -1
  85. package/dist/plugin/plugin.js +42 -123
  86. package/dist/plugin/plugin.js.map +1 -1
  87. package/dist/plugins/agents/agents.d.ts +13 -1
  88. package/dist/plugins/agents/agents.d.ts.map +1 -1
  89. package/dist/plugins/agents/agents.js +65 -15
  90. package/dist/plugins/agents/agents.js.map +1 -1
  91. package/dist/plugins/agents/auth-mode.js +42 -0
  92. package/dist/plugins/agents/auth-mode.js.map +1 -0
  93. package/dist/plugins/agents/index.d.ts +1 -1
  94. package/dist/plugins/agents/mlflow.js +11 -3
  95. package/dist/plugins/agents/mlflow.js.map +1 -1
  96. package/dist/plugins/agents/tool-dispatch.js +9 -1
  97. package/dist/plugins/agents/tool-dispatch.js.map +1 -1
  98. package/dist/plugins/ai-search/ai-search.d.ts +1 -1
  99. package/dist/plugins/ai-search/ai-search.d.ts.map +1 -1
  100. package/dist/plugins/ai-search/ai-search.js +4 -4
  101. package/dist/plugins/ai-search/ai-search.js.map +1 -1
  102. package/dist/plugins/analytics/analytics.d.ts +3 -3
  103. package/dist/plugins/analytics/analytics.d.ts.map +1 -1
  104. package/dist/plugins/analytics/analytics.js +9 -7
  105. package/dist/plugins/analytics/analytics.js.map +1 -1
  106. package/dist/plugins/database/crud/contract.js +2 -2
  107. package/dist/plugins/database/crud/contract.js.map +1 -1
  108. package/dist/plugins/database/database.d.ts +1 -1
  109. package/dist/plugins/files/plugin.d.ts +21 -15
  110. package/dist/plugins/files/plugin.d.ts.map +1 -1
  111. package/dist/plugins/files/plugin.js +50 -29
  112. package/dist/plugins/files/plugin.js.map +1 -1
  113. package/dist/plugins/genie/genie.d.ts +10 -1
  114. package/dist/plugins/genie/genie.d.ts.map +1 -1
  115. package/dist/plugins/genie/genie.js +12 -3
  116. package/dist/plugins/genie/genie.js.map +1 -1
  117. package/dist/plugins/genie/manifest.js +1 -0
  118. package/dist/plugins/jobs/plugin.d.ts +1 -1
  119. package/dist/plugins/jobs/plugin.js +2 -2
  120. package/dist/plugins/jobs/plugin.js.map +1 -1
  121. package/dist/plugins/lakebase/lakebase.d.ts +11 -18
  122. package/dist/plugins/lakebase/lakebase.d.ts.map +1 -1
  123. package/dist/plugins/lakebase/lakebase.js +16 -21
  124. package/dist/plugins/lakebase/lakebase.js.map +1 -1
  125. package/dist/plugins/server/client-config-sanitizer.js +1 -4
  126. package/dist/plugins/server/client-config-sanitizer.js.map +1 -1
  127. package/dist/plugins/server/dev-obo-middleware.js +60 -0
  128. package/dist/plugins/server/dev-obo-middleware.js.map +1 -0
  129. package/dist/plugins/server/index.d.ts +1 -1
  130. package/dist/plugins/server/index.d.ts.map +1 -1
  131. package/dist/plugins/server/index.js +3 -0
  132. package/dist/plugins/server/index.js.map +1 -1
  133. package/dist/plugins/serving/manifest.js +1 -0
  134. package/dist/plugins/serving/serving.d.ts +1 -1
  135. package/dist/plugins/serving/serving.js +6 -6
  136. package/dist/plugins/serving/serving.js.map +1 -1
  137. package/dist/resources/index.d.ts +1 -0
  138. package/dist/resources/index.js +3 -0
  139. package/dist/resources/warehouse.d.ts +16 -0
  140. package/dist/resources/warehouse.d.ts.map +1 -0
  141. package/dist/resources/warehouse.js +93 -0
  142. package/dist/resources/warehouse.js.map +1 -0
  143. package/dist/schemas/manifest.d.ts +44 -1
  144. package/dist/schemas/manifest.d.ts.map +1 -1
  145. package/dist/schemas/manifest.js +122 -3
  146. package/dist/schemas/manifest.js.map +1 -1
  147. package/dist/shared/src/dev-obo.js +86 -0
  148. package/dist/shared/src/dev-obo.js.map +1 -0
  149. package/dist/shared/src/index.d.ts +1 -1
  150. package/dist/shared/src/plugin.d.ts +12 -1
  151. package/dist/shared/src/plugin.d.ts.map +1 -1
  152. package/dist/shared/src/schemas/manifest.d.ts +17 -0
  153. package/dist/shared/src/schemas/manifest.d.ts.map +1 -1
  154. package/dist/shared/src/schemas/manifest.js +53 -3
  155. package/dist/shared/src/schemas/manifest.js.map +1 -1
  156. package/dist/stream/stream-manager.d.ts.map +1 -1
  157. package/dist/stream/stream-manager.js +5 -2
  158. package/dist/stream/stream-manager.js.map +1 -1
  159. package/dist/telemetry/execution-span-processor.js +21 -0
  160. package/dist/telemetry/execution-span-processor.js.map +1 -0
  161. package/dist/telemetry/telemetry-manager.js +2 -1
  162. package/dist/telemetry/telemetry-manager.js.map +1 -1
  163. package/dist/testing/create-test-app.d.ts +2 -2
  164. package/dist/testing/create-test-app.js +2 -2
  165. package/dist/testing/create-test-app.js.map +1 -1
  166. package/dist/testing/fixtures.d.ts +3 -2
  167. package/dist/testing/fixtures.d.ts.map +1 -1
  168. package/dist/testing/fixtures.js +21 -14
  169. package/dist/testing/fixtures.js.map +1 -1
  170. package/dist/testing/reset-singletons.js +1 -1
  171. package/dist/testing/test-plugin-context.d.ts +3 -12
  172. package/dist/testing/test-plugin-context.d.ts.map +1 -1
  173. package/dist/testing/test-plugin-context.js +24 -16
  174. package/dist/testing/test-plugin-context.js.map +1 -1
  175. package/dist/utils/is-plain-object.js +11 -0
  176. package/dist/utils/is-plain-object.js.map +1 -0
  177. package/docs/api/appkit/Class.AppKitError.md +2 -1
  178. package/docs/api/appkit/Class.AuthenticationError.md +1 -1
  179. package/docs/api/appkit/Class.ConfigurationError.md +1 -1
  180. package/docs/api/appkit/Class.ConnectionError.md +1 -1
  181. package/docs/api/appkit/Class.DatabaseValidationError.md +1 -1
  182. package/docs/api/appkit/Class.ExecutionError.md +1 -1
  183. package/docs/api/appkit/Class.IdentityExpiredError.md +190 -0
  184. package/docs/api/appkit/Class.InitializationError.md +1 -1
  185. package/docs/api/appkit/Class.Plugin.md +9 -13
  186. package/docs/api/appkit/Class.ServerError.md +1 -1
  187. package/docs/api/appkit/Class.ServiceContext.md +169 -0
  188. package/docs/api/appkit/Class.TunnelError.md +1 -1
  189. package/docs/api/appkit/Class.ValidationError.md +1 -1
  190. package/docs/api/appkit/Function.createApp.md +12 -12
  191. package/docs/api/appkit/Function.getCallerContext.md +12 -0
  192. package/docs/api/appkit/Function.getCurrentActorId.md +12 -0
  193. package/docs/api/appkit/Function.getCurrentPrincipalKey.md +12 -0
  194. package/docs/api/appkit/Function.getCurrentUserId.md +14 -0
  195. package/docs/api/appkit/Function.getExecutionContext.md +5 -3
  196. package/docs/api/appkit/Function.getUserContext.md +16 -0
  197. package/docs/api/appkit/Function.getWarehouseId.md +20 -0
  198. package/docs/api/appkit/Function.isInUserContext.md +12 -0
  199. package/docs/api/appkit/Function.isUserContext.md +20 -0
  200. package/docs/api/appkit/Function.runAgent.md +1 -1
  201. package/docs/api/appkit/Function.runInCallerContext.md +27 -0
  202. package/docs/api/appkit/Function.runInUserContext.md +29 -0
  203. package/docs/api/appkit/Interface.AgentDefinition.md +11 -0
  204. package/docs/api/appkit/Interface.AgentsPluginConfig.md +11 -0
  205. package/docs/api/appkit/Interface.CallerContext.md +54 -0
  206. package/docs/api/appkit/Interface.IndexConfig.md +1 -1
  207. package/docs/api/appkit/Interface.PluginManifest.md +33 -2
  208. package/docs/api/appkit/Interface.RegisteredAgent.md +11 -0
  209. package/docs/api/appkit/Interface.RunAgentInput.md +45 -1
  210. package/docs/api/appkit/TypeAlias.AgentAuth.md +8 -0
  211. package/docs/api/appkit/TypeAlias.AppKitApi.md +35 -0
  212. package/docs/api/appkit/TypeAlias.CallerPrincipal.md +13 -0
  213. package/docs/api/appkit/TypeAlias.ExecutionContext.md +9 -0
  214. package/docs/api/appkit/TypeAlias.ExecutionResult.md +65 -0
  215. package/docs/api/appkit/TypeAlias.ScopedPluginMap.md +12 -0
  216. package/docs/api/appkit/TypeAlias.UserContext.md +109 -0
  217. package/docs/api/appkit/TypeAlias.UserScopedApp.md +39 -0
  218. package/docs/api/appkit.md +20 -0
  219. package/docs/plugins/agents.md +45 -0
  220. package/docs/plugins/analytics.md +8 -0
  221. package/docs/plugins/execution-context.md +101 -50
  222. package/docs/plugins/lakebase.md +6 -82
  223. package/llms.txt +21 -1
  224. package/package.json +1 -1
  225. package/sbom.cdx.json +1 -1
@@ -1,10 +1,10 @@
1
1
  import { ApiError } from "../../shared/src/workspace-client/errors.js";
2
2
  import { AuthenticationError } from "../../errors/authentication.js";
3
3
  import "../../errors/index.js";
4
- import { ServiceContext } from "../../context/service-context.js";
4
+ import { isCallerContext } from "../../context/caller-context.js";
5
5
  import { createLogger } from "../../logging/logger.js";
6
- import { isUserContext } from "../../context/user-context.js";
7
- import { getCurrentUserId, getExecutionContext, getWorkspaceClient, runInUserContext } from "../../context/execution-context.js";
6
+ import { ServiceContext } from "../../context/service-context.js";
7
+ import { getCallerContext, getCurrentPrincipalId, getExecutionContext, getWorkspaceClient, runInCallerContext } from "../../context/execution-context.js";
8
8
  import "../../context/index.js";
9
9
  import { Plugin } from "../../plugin/plugin.js";
10
10
  import { toPlugin } from "../../plugin/to-plugin.js";
@@ -22,8 +22,8 @@ import { FILES_DOWNLOAD_DEFAULTS, FILES_MAX_UPLOAD_SIZE, FILES_READ_DEFAULTS, FI
22
22
  import { parentDirectory, sanitizeFilename } from "./helpers.js";
23
23
  import manifest_default from "./manifest.js";
24
24
  import { z } from "zod";
25
- import { STATUS_CODES } from "node:http";
26
25
  import { Readable } from "node:stream";
26
+ import { STATUS_CODES } from "node:http";
27
27
 
28
28
  //#region src/plugins/files/plugin.ts
29
29
  const logger = createLogger("files");
@@ -113,7 +113,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
113
113
  * return a policy user explicitly marked `isServicePrincipal: true`, so
114
114
  * even in dev a `usersOnly`-style policy that gates on
115
115
  * `!user.isServicePrincipal` cannot be tricked. The matching SDK execution
116
- * path also falls through to the SP client (no `runInUserContext` wrap),
116
+ * path also falls through to the SP client (no `runInCallerContext` wrap),
117
117
  * so the policy user and the SDK identity stay aligned.
118
118
  */
119
119
  _extractUser(req) {
@@ -126,7 +126,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
126
126
  if (process.env.NODE_ENV === "development") {
127
127
  logger.warn("asUser(req) called without complete x-forwarded-user + x-forwarded-access-token headers — falling back to service principal identity (dev mode). In production this request would 401.");
128
128
  return {
129
- id: getCurrentUserId(),
129
+ id: getCurrentPrincipalId(),
130
130
  isServicePrincipal: true
131
131
  };
132
132
  }
@@ -153,7 +153,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
153
153
  if (!token && process.env.NODE_ENV === "development") {
154
154
  logger.warn("OBO volume requested without x-forwarded-access-token — falling back to service principal identity (dev mode). In production this request would 401.");
155
155
  return {
156
- id: getCurrentUserId(),
156
+ id: getCurrentPrincipalId(),
157
157
  isServicePrincipal: true
158
158
  };
159
159
  }
@@ -191,7 +191,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
191
191
  * NOTE: This method only selects which identity the *policy* sees. The
192
192
  * matching SDK execution identity is selected separately by
193
193
  * `_resolveAuthForRequest` and applied via `_runWithAuth` /
194
- * `runInUserContext` in each handler. The two selections are designed to
194
+ * `runInCallerContext` in each handler. The two selections are designed to
195
195
  * converge on the same identity per the policy-user matrix in the docs —
196
196
  * see `docs/docs/plugins/files.md#policy-user-matrix`.
197
197
  */
@@ -205,7 +205,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
205
205
  else {
206
206
  logger.debug("No x-forwarded-user header — proceeding with service principal identity for policy evaluation.");
207
207
  user = {
208
- id: getCurrentUserId(),
208
+ id: getCurrentPrincipalId(),
209
209
  isServicePrincipal: true
210
210
  };
211
211
  }
@@ -481,7 +481,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
481
481
  *
482
482
  * On OBO volumes the read cache is disabled (see `_readSettings`), so
483
483
  * invalidation is a no-op here for `mode === "on-behalf-of-user"`. The
484
- * cache layer is keyed by `getCurrentUserId()`, so user A's writes can
484
+ * cache layer is keyed by `getCurrentPrincipalId()`, so user A's writes can
485
485
  * only invalidate user A's cache entry — user B would otherwise see stale
486
486
  * data for the same volume/path until TTL. Disabling the cache on OBO
487
487
  * trades read performance for correctness; the alternative is a
@@ -501,7 +501,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
501
501
  async _invalidateListCache(volumeKey, writtenPath, connector, mode = "service-principal") {
502
502
  if (mode === "on-behalf-of-user") return;
503
503
  const parent = parentDirectory(writtenPath);
504
- const userKey = getCurrentUserId();
504
+ const userKey = getCurrentPrincipalId();
505
505
  const tryDelete = async (segment) => {
506
506
  try {
507
507
  await this.cache.delete(this.cache.generateKey([`files:${volumeKey}:list`, segment], userKey));
@@ -942,7 +942,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
942
942
  return this.volumeConfigs[volumeKey]?.auth ?? this.config.auth ?? "service-principal";
943
943
  }
944
944
  /**
945
- * Build a `UserContext` from request headers when both
945
+ * Build a `CallerContext` from request headers when both
946
946
  * `x-forwarded-access-token` and `x-forwarded-user` are present, otherwise
947
947
  * return `null`. Used by OBO route handlers to wrap SDK calls in the
948
948
  * end-user's identity. A `null` result means "fall back to the service
@@ -954,12 +954,12 @@ var FilesPlugin = class FilesPlugin extends Plugin {
954
954
  const token = req.header("x-forwarded-access-token")?.trim();
955
955
  const userId = req.header("x-forwarded-user")?.trim();
956
956
  if (!token || !userId) return null;
957
- return ServiceContext.createUserContext(token, userId);
957
+ return ServiceContext.createCallerContext(token, userId);
958
958
  }
959
959
  /**
960
960
  * Build the telemetry attribute hash for the `files.auth_mode` span
961
961
  * attribute. The value reflects what operationally happened — i.e.
962
- * whether `runInUserContext` actually wrapped the SDK call:
962
+ * whether `runInCallerContext` actually wrapped the SDK call:
963
963
  * - HTTP route on OBO volume + valid token → `"on-behalf-of-user"`.
964
964
  * - HTTP route on OBO volume + dev-fallback (no token) →
965
965
  * `"service-principal"` (the route falls through to the SP client).
@@ -973,12 +973,12 @@ var FilesPlugin = class FilesPlugin extends Plugin {
973
973
  }
974
974
  /**
975
975
  * One-shot resolver for HTTP route handlers. Builds the request's
976
- * `UserContext` AT MOST ONCE (when the volume is OBO and the headers are
976
+ * `CallerContext` AT MOST ONCE (when the volume is OBO and the headers are
977
977
  * present) and returns both the operationally-effective auth mode and the
978
- * pre-built `UserContext`.
978
+ * pre-built `CallerContext`.
979
979
  *
980
980
  * Handlers thread the `userCtx` into `_runWithAuth(userCtx, fn)` to avoid
981
- * a second `ServiceContext.createUserContext()` allocation — that call
981
+ * a second `ServiceContext.createCallerContext()` allocation. That call
982
982
  * builds a fresh `WorkspaceClient` per invocation, so doing it twice per
983
983
  * request was pure throwaway overhead.
984
984
  */
@@ -999,11 +999,11 @@ var FilesPlugin = class FilesPlugin extends Plugin {
999
999
  /**
1000
1000
  * Run `fn` under the correct execution context.
1001
1001
  * - `userCtx` is `null`: invokes `fn` directly so the service-principal
1002
- * `WorkspaceClient` and `getCurrentUserId()` are used — identical
1002
+ * `WorkspaceClient` and `getCurrentPrincipalId()` are used, identical
1003
1003
  * behavior to pre-OBO releases. This covers both SP volumes and the
1004
1004
  * OBO dev-fallback path (where headers were missing).
1005
- * - `userCtx` is a `UserContext`: wraps `fn` in `runInUserContext(userCtx)`,
1006
- * so SDK calls execute as the end user and `getCurrentUserId()` (and
1005
+ * - `userCtx` is a `CallerContext`: wraps `fn` in `runInCallerContext(userCtx)`,
1006
+ * so SDK calls execute as the end user and `getCurrentPrincipalId()` (and
1007
1007
  * therefore cache keys) resolve to the user's ID.
1008
1008
  *
1009
1009
  * The caller is responsible for building `userCtx` exactly once per
@@ -1011,7 +1011,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
1011
1011
  * NOT take a `req` so it cannot accidentally re-build the context.
1012
1012
  */
1013
1013
  async _runWithAuth(userCtx, fn) {
1014
- if (userCtx) return runInUserContext(userCtx, fn);
1014
+ if (userCtx) return runInCallerContext(userCtx, fn);
1015
1015
  return fn();
1016
1016
  }
1017
1017
  /**
@@ -1042,6 +1042,25 @@ var FilesPlugin = class FilesPlugin extends Plugin {
1042
1042
  * additional parent span is opened, so each call produces exactly one
1043
1043
  * `files.<operation>` span instead of two.
1044
1044
  */
1045
+ /**
1046
+ * Like `_wrapVolumeAPIWithSPSpan`, but picks `files.auth_mode` from the
1047
+ * active scope at call time: "on-behalf-of-user" inside a caller scope
1048
+ * (for example `appkit.asUser(req)`), "service-principal" otherwise.
1049
+ */
1050
+ _wrapVolumeAPIWithScopeSpan(api) {
1051
+ const wrap = (operation, fn) => (...args) => this._withAuthModeAttributes(operation, getCallerContext() ? "on-behalf-of-user" : "service-principal", () => fn(...args));
1052
+ return {
1053
+ list: wrap("list", api.list),
1054
+ read: wrap("read", api.read),
1055
+ download: wrap("download", api.download),
1056
+ exists: wrap("exists", api.exists),
1057
+ metadata: wrap("metadata", api.metadata),
1058
+ upload: wrap("upload", api.upload),
1059
+ createDirectory: wrap("createDirectory", api.createDirectory),
1060
+ delete: wrap("delete", api.delete),
1061
+ preview: wrap("preview", api.preview)
1062
+ };
1063
+ }
1045
1064
  _wrapVolumeAPIWithSPSpan(api) {
1046
1065
  const wrap = (operation, fn) => (...args) => this._withAuthModeAttributes(operation, "service-principal", () => fn(...args));
1047
1066
  return {
@@ -1058,10 +1077,10 @@ var FilesPlugin = class FilesPlugin extends Plugin {
1058
1077
  }
1059
1078
  /**
1060
1079
  * Wrap each `VolumeAPI` method so its execution runs inside
1061
- * `runInUserContext(userCtx, ...)`. Used by `VolumeHandle.asUser(req)` to
1080
+ * `runInCallerContext(userCtx, ...)`. Used by `VolumeHandle.asUser(req)` to
1062
1081
  * force the SDK identity to the end user regardless of the volume's
1063
1082
  * `auth` setting. The policy check baked into each method (via
1064
- * `createVolumeAPI`) runs inside the same scope, so `getCurrentUserId()`
1083
+ * `createVolumeAPI`) runs inside the same scope, so `getCurrentPrincipalId()`
1065
1084
  * and any cache `userKey` derived from it also resolve to the user.
1066
1085
  *
1067
1086
  * Each wrapped invocation tags the connector's span with
@@ -1069,7 +1088,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
1069
1088
  * propagation — no additional parent span is opened.
1070
1089
  */
1071
1090
  _wrapVolumeAPIInUserContext(api, userCtx) {
1072
- const wrap = (operation, fn) => (...args) => this._withAuthModeAttributes(operation, "on-behalf-of-user", () => runInUserContext(userCtx, () => fn(...args)));
1091
+ const wrap = (operation, fn) => (...args) => this._withAuthModeAttributes(operation, "on-behalf-of-user", () => runInCallerContext(userCtx, () => fn(...args)));
1073
1092
  return {
1074
1093
  list: wrap("list", api.list),
1075
1094
  read: wrap("read", api.read),
@@ -1142,7 +1161,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
1142
1161
  _defineVolumeTools(volumeKey) {
1143
1162
  const buildUser = () => {
1144
1163
  const ctx = getExecutionContext();
1145
- return isUserContext(ctx) ? { id: ctx.userId } : {
1164
+ return isCallerContext(ctx) ? { id: ctx.principal.userId } : {
1146
1165
  id: ctx.serviceUserId,
1147
1166
  isServicePrincipal: true
1148
1167
  };
@@ -1265,7 +1284,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
1265
1284
  * through the HTTP routes run as the end user; for programmatic calls
1266
1285
  * outside a route, use `asUser(req)` to opt into per-user execution.
1267
1286
  * `asUser(req)` is a hard override at the SDK level: it forces every
1268
- * subsequent call to execute as the end user inside `runInUserContext`,
1287
+ * subsequent call to execute as the end user inside `runInCallerContext`,
1269
1288
  * regardless of the volume's `auth` setting. Policies control per-user
1270
1289
  * access in either mode.
1271
1290
  *
@@ -1283,11 +1302,13 @@ var FilesPlugin = class FilesPlugin extends Plugin {
1283
1302
  const resolveVolume = (volumeKey) => {
1284
1303
  if (!this.volumeKeys.includes(volumeKey)) throw new Error(`Unknown volume "${volumeKey}". Available volumes: ${this.volumeKeys.join(", ")}`);
1285
1304
  return {
1286
- ...this._wrapVolumeAPIWithSPSpan(this.createVolumeAPI(volumeKey, {
1305
+ ...this._wrapVolumeAPIWithScopeSpan(this.createVolumeAPI(volumeKey, {
1287
1306
  get id() {
1288
- return getCurrentUserId();
1307
+ return getCurrentPrincipalId();
1289
1308
  },
1290
- isServicePrincipal: true
1309
+ get isServicePrincipal() {
1310
+ return getCallerContext() === void 0;
1311
+ }
1291
1312
  })),
1292
1313
  asUser: (req) => {
1293
1314
  const user = this._extractUser(req);