@databricks/appkit 0.83.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 (210) hide show
  1. package/CLAUDE.md +15 -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/routing-pool.d.ts.map +1 -1
  19. package/dist/connectors/lakebase/routing-pool.js +4 -10
  20. package/dist/connectors/lakebase/routing-pool.js.map +1 -1
  21. package/dist/context/caller-context.d.ts +4 -1
  22. package/dist/context/caller-context.d.ts.map +1 -1
  23. package/dist/context/caller-context.js.map +1 -1
  24. package/dist/context/execution-context.d.ts +29 -1
  25. package/dist/context/execution-context.d.ts.map +1 -1
  26. package/dist/context/execution-context.js +60 -8
  27. package/dist/context/execution-context.js.map +1 -1
  28. package/dist/context/index.d.ts +2 -2
  29. package/dist/context/index.js +2 -1
  30. package/dist/context/request-scope.d.ts +2 -0
  31. package/dist/context/request-scope.js +39 -0
  32. package/dist/context/request-scope.js.map +1 -0
  33. package/dist/context/resource-capabilities.js +59 -0
  34. package/dist/context/resource-capabilities.js.map +1 -0
  35. package/dist/context/scoped-api.js +104 -0
  36. package/dist/context/scoped-api.js.map +1 -0
  37. package/dist/context/service-context.d.ts.map +1 -1
  38. package/dist/context/service-context.js +1 -1
  39. package/dist/context/service-context.js.map +1 -1
  40. package/dist/context/user-context.d.ts +16 -19
  41. package/dist/context/user-context.d.ts.map +1 -1
  42. package/dist/context/user-context.js +30 -3
  43. package/dist/context/user-context.js.map +1 -1
  44. package/dist/core/agent/load-agents.d.ts.map +1 -1
  45. package/dist/core/agent/load-agents.js +5 -2
  46. package/dist/core/agent/load-agents.js.map +1 -1
  47. package/dist/core/agent/run-agent.d.ts +19 -6
  48. package/dist/core/agent/run-agent.d.ts.map +1 -1
  49. package/dist/core/agent/run-agent.js +53 -17
  50. package/dist/core/agent/run-agent.js.map +1 -1
  51. package/dist/core/agent/types.d.ts +18 -1
  52. package/dist/core/agent/types.d.ts.map +1 -1
  53. package/dist/core/agent/types.js.map +1 -1
  54. package/dist/core/appkit.d.ts +4 -3
  55. package/dist/core/appkit.d.ts.map +1 -1
  56. package/dist/core/appkit.js +30 -9
  57. package/dist/core/appkit.js.map +1 -1
  58. package/dist/core/plugin-context.d.ts +14 -15
  59. package/dist/core/plugin-context.d.ts.map +1 -1
  60. package/dist/core/plugin-context.js +24 -14
  61. package/dist/core/plugin-context.js.map +1 -1
  62. package/dist/errors/base.d.ts +2 -2
  63. package/dist/errors/base.js +2 -2
  64. package/dist/errors/base.js.map +1 -1
  65. package/dist/errors/identity-expired.d.ts +14 -0
  66. package/dist/errors/identity-expired.d.ts.map +1 -0
  67. package/dist/errors/identity-expired.js +33 -0
  68. package/dist/errors/identity-expired.js.map +1 -0
  69. package/dist/errors/index.js +1 -0
  70. package/dist/index.d.ts +8 -5
  71. package/dist/index.js +5 -2
  72. package/dist/logging/logger.js +1 -1
  73. package/dist/plugin/execution-result.d.ts +4 -1
  74. package/dist/plugin/execution-result.d.ts.map +1 -1
  75. package/dist/plugin/interceptors/telemetry.js +6 -4
  76. package/dist/plugin/interceptors/telemetry.js.map +1 -1
  77. package/dist/plugin/plugin.d.ts +13 -21
  78. package/dist/plugin/plugin.d.ts.map +1 -1
  79. package/dist/plugin/plugin.js +41 -122
  80. package/dist/plugin/plugin.js.map +1 -1
  81. package/dist/plugins/agents/agents.d.ts +12 -0
  82. package/dist/plugins/agents/agents.d.ts.map +1 -1
  83. package/dist/plugins/agents/agents.js +65 -15
  84. package/dist/plugins/agents/agents.js.map +1 -1
  85. package/dist/plugins/agents/auth-mode.js +42 -0
  86. package/dist/plugins/agents/auth-mode.js.map +1 -0
  87. package/dist/plugins/agents/index.d.ts +1 -1
  88. package/dist/plugins/agents/mlflow.js +11 -3
  89. package/dist/plugins/agents/mlflow.js.map +1 -1
  90. package/dist/plugins/agents/tool-dispatch.js +9 -1
  91. package/dist/plugins/agents/tool-dispatch.js.map +1 -1
  92. package/dist/plugins/ai-search/ai-search.d.ts.map +1 -1
  93. package/dist/plugins/ai-search/ai-search.js +4 -4
  94. package/dist/plugins/ai-search/ai-search.js.map +1 -1
  95. package/dist/plugins/analytics/analytics.d.ts +2 -2
  96. package/dist/plugins/analytics/analytics.js +6 -6
  97. package/dist/plugins/analytics/analytics.js.map +1 -1
  98. package/dist/plugins/database/crud/contract.js +2 -2
  99. package/dist/plugins/database/crud/contract.js.map +1 -1
  100. package/dist/plugins/files/plugin.d.ts +10 -4
  101. package/dist/plugins/files/plugin.d.ts.map +1 -1
  102. package/dist/plugins/files/plugin.js +34 -13
  103. package/dist/plugins/files/plugin.js.map +1 -1
  104. package/dist/plugins/genie/genie.d.ts +9 -0
  105. package/dist/plugins/genie/genie.d.ts.map +1 -1
  106. package/dist/plugins/genie/genie.js +12 -3
  107. package/dist/plugins/genie/genie.js.map +1 -1
  108. package/dist/plugins/genie/manifest.js +1 -0
  109. package/dist/plugins/jobs/plugin.js +2 -2
  110. package/dist/plugins/jobs/plugin.js.map +1 -1
  111. package/dist/plugins/lakebase/lakebase.d.ts +10 -17
  112. package/dist/plugins/lakebase/lakebase.d.ts.map +1 -1
  113. package/dist/plugins/lakebase/lakebase.js +12 -17
  114. package/dist/plugins/lakebase/lakebase.js.map +1 -1
  115. package/dist/plugins/server/client-config-sanitizer.js +1 -4
  116. package/dist/plugins/server/client-config-sanitizer.js.map +1 -1
  117. package/dist/plugins/server/dev-obo-middleware.js +60 -0
  118. package/dist/plugins/server/dev-obo-middleware.js.map +1 -0
  119. package/dist/plugins/server/index.d.ts.map +1 -1
  120. package/dist/plugins/server/index.js +5 -2
  121. package/dist/plugins/server/index.js.map +1 -1
  122. package/dist/plugins/server/remote-tunnel/remote-tunnel-manager.js +3 -3
  123. package/dist/plugins/server/remote-tunnel/remote-tunnel-manager.js.map +1 -1
  124. package/dist/plugins/server/static-server.js +3 -3
  125. package/dist/plugins/server/static-server.js.map +1 -1
  126. package/dist/plugins/server/utils.js +3 -3
  127. package/dist/plugins/server/utils.js.map +1 -1
  128. package/dist/plugins/server/vite-dev-server.js +4 -4
  129. package/dist/plugins/server/vite-dev-server.js.map +1 -1
  130. package/dist/plugins/serving/manifest.js +1 -0
  131. package/dist/plugins/serving/serving.js +6 -6
  132. package/dist/plugins/serving/serving.js.map +1 -1
  133. package/dist/schemas/manifest.d.ts +35 -1
  134. package/dist/schemas/manifest.d.ts.map +1 -1
  135. package/dist/schemas/manifest.js +112 -4
  136. package/dist/schemas/manifest.js.map +1 -1
  137. package/dist/shared/src/dev-obo.js +86 -0
  138. package/dist/shared/src/dev-obo.js.map +1 -0
  139. package/dist/shared/src/index.d.ts +1 -1
  140. package/dist/shared/src/plugin.d.ts +12 -1
  141. package/dist/shared/src/plugin.d.ts.map +1 -1
  142. package/dist/shared/src/schemas/manifest.d.ts +41 -33
  143. package/dist/shared/src/schemas/manifest.d.ts.map +1 -1
  144. package/dist/shared/src/schemas/manifest.js +43 -4
  145. package/dist/shared/src/schemas/manifest.js.map +1 -1
  146. package/dist/stream/stream-manager.d.ts.map +1 -1
  147. package/dist/stream/stream-manager.js +5 -2
  148. package/dist/stream/stream-manager.js.map +1 -1
  149. package/dist/telemetry/execution-span-processor.js +21 -0
  150. package/dist/telemetry/execution-span-processor.js.map +1 -0
  151. package/dist/telemetry/telemetry-manager.js +2 -1
  152. package/dist/telemetry/telemetry-manager.js.map +1 -1
  153. package/dist/testing/create-test-app.d.ts +2 -2
  154. package/dist/testing/create-test-app.js.map +1 -1
  155. package/dist/testing/test-plugin-context.d.ts +3 -12
  156. package/dist/testing/test-plugin-context.d.ts.map +1 -1
  157. package/dist/testing/test-plugin-context.js +24 -16
  158. package/dist/testing/test-plugin-context.js.map +1 -1
  159. package/dist/type-generator/database/generate.js +3 -3
  160. package/dist/type-generator/database/generate.js.map +1 -1
  161. package/dist/type-generator/migration.js +2 -2
  162. package/dist/type-generator/migration.js.map +1 -1
  163. package/dist/type-generator/serving/server-file-extractor.js +3 -3
  164. package/dist/type-generator/serving/server-file-extractor.js.map +1 -1
  165. package/dist/utils/is-plain-object.js +11 -0
  166. package/dist/utils/is-plain-object.js.map +1 -0
  167. package/docs/api/appkit/Class.AppKitError.md +2 -1
  168. package/docs/api/appkit/Class.AuthenticationError.md +1 -1
  169. package/docs/api/appkit/Class.ConfigurationError.md +1 -1
  170. package/docs/api/appkit/Class.ConnectionError.md +1 -1
  171. package/docs/api/appkit/Class.DatabaseValidationError.md +1 -1
  172. package/docs/api/appkit/Class.ExecutionError.md +1 -1
  173. package/docs/api/appkit/Class.IdentityExpiredError.md +190 -0
  174. package/docs/api/appkit/Class.InitializationError.md +1 -1
  175. package/docs/api/appkit/Class.Plugin.md +8 -12
  176. package/docs/api/appkit/Class.ServerError.md +1 -1
  177. package/docs/api/appkit/Class.ServiceContext.md +169 -0
  178. package/docs/api/appkit/Class.TunnelError.md +1 -1
  179. package/docs/api/appkit/Class.ValidationError.md +1 -1
  180. package/docs/api/appkit/Function.createApp.md +12 -12
  181. package/docs/api/appkit/Function.getCallerContext.md +12 -0
  182. package/docs/api/appkit/Function.getCurrentUserId.md +14 -0
  183. package/docs/api/appkit/Function.getExecutionContext.md +1 -1
  184. package/docs/api/appkit/Function.getUserContext.md +16 -0
  185. package/docs/api/appkit/Function.isInUserContext.md +12 -0
  186. package/docs/api/appkit/Function.isUserContext.md +20 -0
  187. package/docs/api/appkit/Function.runAgent.md +1 -1
  188. package/docs/api/appkit/Function.runInCallerContext.md +27 -0
  189. package/docs/api/appkit/Function.runInUserContext.md +29 -0
  190. package/docs/api/appkit/Interface.AgentDefinition.md +11 -0
  191. package/docs/api/appkit/Interface.AgentsPluginConfig.md +11 -0
  192. package/docs/api/appkit/Interface.CallerContext.md +13 -0
  193. package/docs/api/appkit/Interface.IndexConfig.md +1 -1
  194. package/docs/api/appkit/Interface.PluginManifest.md +9 -1
  195. package/docs/api/appkit/Interface.RegisteredAgent.md +11 -0
  196. package/docs/api/appkit/Interface.RunAgentInput.md +45 -1
  197. package/docs/api/appkit/TypeAlias.AgentAuth.md +8 -0
  198. package/docs/api/appkit/TypeAlias.AppKitApi.md +35 -0
  199. package/docs/api/appkit/TypeAlias.ExecutionContext.md +4 -1
  200. package/docs/api/appkit/TypeAlias.ExecutionResult.md +65 -0
  201. package/docs/api/appkit/TypeAlias.ScopedPluginMap.md +12 -0
  202. package/docs/api/appkit/TypeAlias.UserContext.md +109 -0
  203. package/docs/api/appkit/TypeAlias.UserScopedApp.md +39 -0
  204. package/docs/api/appkit.md +14 -0
  205. package/docs/plugins/agents.md +45 -0
  206. package/docs/plugins/execution-context.md +101 -50
  207. package/docs/plugins/lakebase.md +6 -82
  208. package/llms.txt +15 -1
  209. package/package.json +1 -1
  210. package/sbom.cdx.json +1 -1
@@ -1,6 +1,10 @@
1
+ import { AuthenticationError } from "../../errors/authentication.js";
2
+ import { IdentityExpiredError } from "../../errors/identity-expired.js";
3
+ import "../../errors/index.js";
1
4
  import { createLogger } from "../../logging/logger.js";
2
- import { getWorkspaceClient } from "../../context/execution-context.js";
5
+ import { getWorkspaceClient, normalizeIdentityError, runOutsideCallerScope } from "../../context/execution-context.js";
3
6
  import "../../context/index.js";
7
+ import { createRequestScope } from "../../context/request-scope.js";
4
8
  import { Plugin } from "../../plugin/plugin.js";
5
9
  import { toPlugin } from "../../plugin/to-plugin.js";
6
10
  import "../../plugin/index.js";
@@ -22,6 +26,7 @@ import { loadAgentsFromDir } from "../../core/agent/load-agents.js";
22
26
  import { ActiveStreamTracker } from "./active-stream-tracker.js";
23
27
  import { buildAdapterExtensions, supervisorToolDescription, warnOnCapabilityMismatch } from "./adapter-extensions.js";
24
28
  import { requiresApproval } from "./approval.js";
29
+ import { isOnBehalfOfUser, modelClientProvider, requireOboCaller, runInOboAgentRun } from "./auth-mode.js";
25
30
  import { LOAD_SKILL_TOOL_DEF, READ_SKILL_FILE_TOOL_DEF } from "./builtin-tools.js";
26
31
  import { agentStreamDefaults } from "./defaults.js";
27
32
  import { EventChannel } from "./event-channel.js";
@@ -276,6 +281,8 @@ var AgentsPlugin = class extends Plugin {
276
281
  }
277
282
  async buildRegisteredAgent(name, def, src) {
278
283
  const adapter = await this.resolveAdapter(def, name);
284
+ const auth = def.auth ?? this.config.auth;
285
+ if (isOnBehalfOfUser(auth) && (await import("../../agents/databricks.js")).hasFixedWorkspaceClient(adapter)) throw new Error(`Agent '${name}' is on-behalf-of-user, but its model adapter has a fixed workspaceClient, so the model would run as the service principal. Pass \`workspaceClient: () => getWorkspaceClient()\` to the adapter, or use a model string.`);
279
286
  const skills = await this.resolveAgentSkills(name, def, src);
280
287
  const toolIndex = await this.buildToolIndex(name, def, src, skills);
281
288
  warnOnCapabilityMismatch(name, adapter, toolIndex);
@@ -289,7 +296,8 @@ var AgentsPlugin = class extends Plugin {
289
296
  maxTokens: def.maxTokens,
290
297
  generationParams: def.generationParams,
291
298
  ephemeral: def.ephemeral,
292
- skills
299
+ skills,
300
+ ...auth && { auth }
293
301
  };
294
302
  }
295
303
  /** Loads the shared global skill pool from `<agentsDir>/skills/`. */
@@ -329,7 +337,10 @@ var AgentsPlugin = class extends Plugin {
329
337
  if (!source) throw new Error(`Agent '${name}' has no model configured and no DATABRICKS_SERVING_ENDPOINT_NAME default available`);
330
338
  if (typeof source === "string") {
331
339
  const { adapterFromModelString } = await import("../../agents/databricks.js");
332
- return adapterFromModelString(source, adapterOptions);
340
+ return adapterFromModelString(source, {
341
+ ...adapterOptions,
342
+ workspaceClient: modelClientProvider()
343
+ });
333
344
  }
334
345
  return await source;
335
346
  }
@@ -629,6 +640,7 @@ var AgentsPlugin = class extends Plugin {
629
640
  res.status(400).json({ error: agentName ? `Agent "${agentName}" not found` : "No agent registered" });
630
641
  return;
631
642
  }
643
+ if (!this.allowsCaller(registered, req, res)) return;
632
644
  const userId = this.resolveUserId(req);
633
645
  const limits = this.resolvedLimits;
634
646
  if (this.countUserStreams(userId) >= limits.maxConcurrentStreamsPerUser) {
@@ -656,7 +668,7 @@ var AgentsPlugin = class extends Plugin {
656
668
  res.status(500).json({ error: "Thread operation failed" });
657
669
  return;
658
670
  }
659
- return this._streamAgent(req, res, registered, thread, userId, mlflowRunId, skill);
671
+ return this.runInAgentScope(registered, req, () => this._streamAgent(req, res, registered, thread, userId, mlflowRunId, skill));
660
672
  }
661
673
  /**
662
674
  * Returns the names of tools in `registered.toolIndex` whose annotations
@@ -700,6 +712,7 @@ var AgentsPlugin = class extends Plugin {
700
712
  res.status(400).json({ error: "No agent registered" });
701
713
  return;
702
714
  }
715
+ if (!this.allowsCaller(registered, req, res)) return;
703
716
  const approvalGated = this.collectApprovalRequiredToolNames(registered);
704
717
  if (approvalGated.length > 0) {
705
718
  res.status(400).json({ error: `Agent '${registered.name}' exposes ${approvalGated.length} approval-gated tool(s) (${approvalGated.join(", ")}); /invocations and /responses are non-streaming and cannot run HITL. Use POST /chat for HITL-capable agents, or disable approval via agents({ approval: { requireForDestructive: false } }).` });
@@ -737,7 +750,35 @@ var AgentsPlugin = class extends Plugin {
737
750
  res.status(500).json({ error: "Thread operation failed" });
738
751
  return;
739
752
  }
740
- return this._runAgentNonStreaming(req, res, registered, thread, userId, mlflowRunId);
753
+ return this.runInAgentScope(registered, req, () => this._runAgentNonStreaming(req, res, registered, thread, userId, mlflowRunId));
754
+ }
755
+ /**
756
+ * Fail closed for an on-behalf-of-user agent: without a forwarded user token
757
+ * the request is rejected with 401 before any model or tool call, in
758
+ * production and in development. Other agents are unaffected.
759
+ */
760
+ allowsCaller(registered, req, res) {
761
+ if (!isOnBehalfOfUser(registered.auth)) return true;
762
+ try {
763
+ requireOboCaller(req);
764
+ return true;
765
+ } catch (error) {
766
+ const failure = error instanceof AuthenticationError ? error : AuthenticationError.missingToken("user token");
767
+ res.status(401).json({
768
+ error: failure.clientMessage,
769
+ code: failure.code
770
+ });
771
+ return false;
772
+ }
773
+ }
774
+ /**
775
+ * Run an on-behalf-of-user agent inside the request's user scope, so the
776
+ * model call, hand-rolled tools, and sub-agents all act as the user. Other
777
+ * agents run exactly as before.
778
+ */
779
+ runInAgentScope(registered, req, fn) {
780
+ if (!isOnBehalfOfUser(registered.auth)) return fn();
781
+ return createRequestScope(req).run(() => runInOboAgentRun(fn));
741
782
  }
742
783
  async _streamAgent(req, res, registered, thread, userId, mlflowRunId, forcedSkill) {
743
784
  const abortController = new AbortController();
@@ -811,12 +852,12 @@ var AgentsPlugin = class extends Plugin {
811
852
  role: "assistant",
812
853
  content: fullContent
813
854
  });
814
- await this.threadStore.addMessage(thread.id, userId, {
855
+ await runOutsideCallerScope(() => this.threadStore.addMessage(thread.id, userId, {
815
856
  id: randomUUID(),
816
857
  role: "assistant",
817
858
  content: fullContent,
818
859
  createdAt: /* @__PURE__ */ new Date()
819
- });
860
+ }));
820
861
  }
821
862
  const mlflowTraceId = currentTraceId();
822
863
  if (mlflowTraceId) for (const evt of translator.translate({
@@ -830,14 +871,15 @@ var AgentsPlugin = class extends Plugin {
830
871
  outboundEvents.close();
831
872
  return;
832
873
  }
833
- logger.error("Agent chat error: %O", error);
834
- outboundEvents.close(error);
874
+ const failure = normalizeIdentityError(error);
875
+ logger.error("Agent chat error: %O", failure);
876
+ outboundEvents.close(failure);
835
877
  return;
836
878
  } finally {
837
879
  this.approvalGate.abortStream(requestId);
838
880
  this.untrackStream(requestId);
839
881
  if (registered.ephemeral) try {
840
- await this.threadStore.delete(thread.id, userId);
882
+ await runOutsideCallerScope(() => this.threadStore.delete(thread.id, userId));
841
883
  } catch (err) {
842
884
  logger.warn("Failed to delete ephemeral thread %s: %O", thread.id, err);
843
885
  }
@@ -939,12 +981,12 @@ var AgentsPlugin = class extends Plugin {
939
981
  role: "assistant",
940
982
  content: fullContent
941
983
  });
942
- await this.threadStore.addMessage(thread.id, userId, {
984
+ await runOutsideCallerScope(() => this.threadStore.addMessage(thread.id, userId, {
943
985
  id: randomUUID(),
944
986
  role: "assistant",
945
987
  content: fullContent,
946
988
  createdAt: /* @__PURE__ */ new Date()
947
- });
989
+ }));
948
990
  }
949
991
  mlflowTraceId = currentTraceId();
950
992
  });
@@ -953,7 +995,15 @@ var AgentsPlugin = class extends Plugin {
953
995
  res.status(499).json({ error: "Request aborted" });
954
996
  return;
955
997
  }
956
- logger.error("Agent invoke error: %O", error);
998
+ const failure = normalizeIdentityError(error);
999
+ if (failure instanceof IdentityExpiredError) {
1000
+ res.status(401).json({
1001
+ error: failure.clientMessage,
1002
+ code: failure.code
1003
+ });
1004
+ return;
1005
+ }
1006
+ logger.error("Agent invoke error: %O", failure);
957
1007
  const message = process.env.NODE_ENV === "production" ? "Internal server error" : error instanceof Error ? error.message : String(error);
958
1008
  res.status(500).json({ error: message });
959
1009
  return;
@@ -961,7 +1011,7 @@ var AgentsPlugin = class extends Plugin {
961
1011
  this.approvalGate.abortStream(requestId);
962
1012
  this.untrackStream(requestId);
963
1013
  if (registered.ephemeral) try {
964
- await this.threadStore.delete(thread.id, userId);
1014
+ await runOutsideCallerScope(() => this.threadStore.delete(thread.id, userId));
965
1015
  } catch (err) {
966
1016
  logger.warn("Failed to delete ephemeral thread %s: %O", thread.id, err);
967
1017
  }
@@ -989,7 +1039,7 @@ var AgentsPlugin = class extends Plugin {
989
1039
  });
990
1040
  }
991
1041
  dispatchSkillTool(entry, args) {
992
- return dispatchSkillTool(entry, args, () => this.skillWorkspaceClient());
1042
+ return runOutsideCallerScope(() => dispatchSkillTool(entry, args, () => this.skillWorkspaceClient()));
993
1043
  }
994
1044
  /**
995
1045
  * Renders the prompt addendum for a force-loaded skill (`/skill-name`).