@databricks/appkit-ui 0.83.0 → 0.85.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 (58) hide show
  1. package/CLAUDE.md +15 -1
  2. package/dist/cli/commands/agent/eval.js +1 -1
  3. package/dist/cli/commands/generate-types.js +1 -1
  4. package/dist/cli/commands/plugin/sync/sync.js +28 -15
  5. package/dist/cli/commands/plugin/sync/sync.js.map +1 -1
  6. package/dist/cli/commands/registry/add.js +3 -11
  7. package/dist/cli/commands/registry/add.js.map +1 -1
  8. package/dist/cli/commands/registry/config-writer.js +1 -1
  9. package/dist/schemas/manifest.d.ts +35 -1
  10. package/dist/schemas/manifest.d.ts.map +1 -1
  11. package/dist/schemas/manifest.js +112 -4
  12. package/dist/schemas/manifest.js.map +1 -1
  13. package/dist/shared/src/plugin.d.ts.map +1 -1
  14. package/docs/api/appkit/Class.AppKitError.md +2 -1
  15. package/docs/api/appkit/Class.AuthenticationError.md +1 -1
  16. package/docs/api/appkit/Class.ConfigurationError.md +1 -1
  17. package/docs/api/appkit/Class.ConnectionError.md +1 -1
  18. package/docs/api/appkit/Class.DatabaseValidationError.md +1 -1
  19. package/docs/api/appkit/Class.ExecutionError.md +1 -1
  20. package/docs/api/appkit/Class.IdentityExpiredError.md +190 -0
  21. package/docs/api/appkit/Class.InitializationError.md +1 -1
  22. package/docs/api/appkit/Class.Plugin.md +8 -12
  23. package/docs/api/appkit/Class.ServerError.md +1 -1
  24. package/docs/api/appkit/Class.ServiceContext.md +169 -0
  25. package/docs/api/appkit/Class.TunnelError.md +1 -1
  26. package/docs/api/appkit/Class.ValidationError.md +1 -1
  27. package/docs/api/appkit/Function.createApp.md +12 -12
  28. package/docs/api/appkit/Function.getCallerContext.md +12 -0
  29. package/docs/api/appkit/Function.getCurrentUserId.md +14 -0
  30. package/docs/api/appkit/Function.getExecutionContext.md +1 -1
  31. package/docs/api/appkit/Function.getUserContext.md +16 -0
  32. package/docs/api/appkit/Function.isInUserContext.md +12 -0
  33. package/docs/api/appkit/Function.isUserContext.md +20 -0
  34. package/docs/api/appkit/Function.runAgent.md +1 -1
  35. package/docs/api/appkit/Function.runInCallerContext.md +27 -0
  36. package/docs/api/appkit/Function.runInUserContext.md +29 -0
  37. package/docs/api/appkit/Interface.AgentDefinition.md +11 -0
  38. package/docs/api/appkit/Interface.AgentsPluginConfig.md +11 -0
  39. package/docs/api/appkit/Interface.CallerContext.md +13 -0
  40. package/docs/api/appkit/Interface.IndexConfig.md +1 -1
  41. package/docs/api/appkit/Interface.PluginManifest.md +9 -1
  42. package/docs/api/appkit/Interface.RegisteredAgent.md +11 -0
  43. package/docs/api/appkit/Interface.RunAgentInput.md +45 -1
  44. package/docs/api/appkit/TypeAlias.AgentAuth.md +8 -0
  45. package/docs/api/appkit/TypeAlias.AppKitApi.md +35 -0
  46. package/docs/api/appkit/TypeAlias.ExecutionContext.md +4 -1
  47. package/docs/api/appkit/TypeAlias.ExecutionResult.md +65 -0
  48. package/docs/api/appkit/TypeAlias.ScopedPluginMap.md +12 -0
  49. package/docs/api/appkit/TypeAlias.UserContext.md +109 -0
  50. package/docs/api/appkit/TypeAlias.UserScopedApp.md +39 -0
  51. package/docs/api/appkit.md +14 -0
  52. package/docs/plugins/agents.md +45 -0
  53. package/docs/plugins/database.md +3 -1
  54. package/docs/plugins/execution-context.md +101 -50
  55. package/docs/plugins/lakebase.md +8 -82
  56. package/llms.txt +15 -1
  57. package/package.json +1 -1
  58. package/sbom.cdx.json +1 -1
@@ -0,0 +1,35 @@
1
+ # Type Alias: AppKitApi\<U>
2
+
3
+ ```ts
4
+ type AppKitApi<U> = PluginMap<U> & {
5
+ asUser: UserScopedApp<U>;
6
+ };
7
+
8
+ ```
9
+
10
+ App instance with plugin exports and an explicit caller-scoped entry point.
11
+
12
+ ## Type Declaration[​](#type-declaration "Direct link to Type Declaration")
13
+
14
+ ### asUser()[​](#asuser "Direct link to asUser()")
15
+
16
+ ```ts
17
+ asUser(req: IAppRequest): UserScopedApp<U>;
18
+
19
+ ```
20
+
21
+ #### Parameters[​](#parameters "Direct link to Parameters")
22
+
23
+ | Parameter | Type |
24
+ | --------- | ------------- |
25
+ | `req` | `IAppRequest` |
26
+
27
+ #### Returns[​](#returns "Direct link to Returns")
28
+
29
+ [`UserScopedApp`](./docs/api/appkit/TypeAlias.UserScopedApp.md)<`U`>
30
+
31
+ ## Type Parameters[​](#type-parameters "Direct link to Type Parameters")
32
+
33
+ | Type Parameter |
34
+ | ----------------------------------------------------------------------------------------------------------------------------------- |
35
+ | `U` *extends* readonly [`PluginData`](./docs/api/appkit/TypeAlias.PluginData.md)<`PluginConstructor`, `unknown`, `string`>\[] |
@@ -1,6 +1,9 @@
1
1
  # Type Alias: ExecutionContext
2
2
 
3
3
  ```ts
4
- type ExecutionContext = ServiceContextState | CallerContext;
4
+ type ExecutionContext =
5
+ | ServiceContextState
6
+ | CallerContext
7
+ | UserContext;
5
8
 
6
9
  ```
@@ -7,6 +7,7 @@ type ExecutionResult<T> =
7
7
  ok: true;
8
8
  }
9
9
  | {
10
+ error?: IdentityExpiredError;
10
11
  message: string;
11
12
  ok: false;
12
13
  status: number;
@@ -34,3 +35,67 @@ In production, error messages from non-AppKitError sources are handled as:
34
35
  | Type Parameter |
35
36
  | -------------- |
36
37
  | `T` |
38
+
39
+ ## Type Declaration[​](#type-declaration "Direct link to Type Declaration")
40
+
41
+ ```ts
42
+ {
43
+ data: T;
44
+ ok: true;
45
+ }
46
+
47
+ ```
48
+
49
+ ### data[​](#data "Direct link to data")
50
+
51
+ ```ts
52
+ data: T;
53
+
54
+ ```
55
+
56
+ ### ok[​](#ok "Direct link to ok")
57
+
58
+ ```ts
59
+ ok: true;
60
+
61
+ ```
62
+
63
+ ```ts
64
+ {
65
+ error?: IdentityExpiredError;
66
+ message: string;
67
+ ok: false;
68
+ status: number;
69
+ }
70
+
71
+ ```
72
+
73
+ ### error?[​](#error "Direct link to error?")
74
+
75
+ ```ts
76
+ optional error: IdentityExpiredError;
77
+
78
+ ```
79
+
80
+ Typed credential expiry without changing the existing failure envelope.
81
+
82
+ ### message[​](#message "Direct link to message")
83
+
84
+ ```ts
85
+ message: string;
86
+
87
+ ```
88
+
89
+ ### ok[​](#ok-1 "Direct link to ok")
90
+
91
+ ```ts
92
+ ok: false;
93
+
94
+ ```
95
+
96
+ ### status[​](#status "Direct link to status")
97
+
98
+ ```ts
99
+ status: number;
100
+
101
+ ```
@@ -0,0 +1,12 @@
1
+ # Type Alias: ScopedPluginMap\<U>
2
+
3
+ ```ts
4
+ type ScopedPluginMap<U> = { [P in U[number] as P["name"]]: ScopedExports<PluginExports<InstanceType<P["plugin"]>>> };
5
+
6
+ ```
7
+
8
+ ## Type Parameters[​](#type-parameters "Direct link to Type Parameters")
9
+
10
+ | Type Parameter |
11
+ | ----------------------------------------------------------------------------------------------------------------------------------- |
12
+ | `U` *extends* readonly [`PluginData`](./docs/api/appkit/TypeAlias.PluginData.md)<`PluginConstructor`, `unknown`, `string`>\[] |
@@ -0,0 +1,109 @@
1
+ # ~~Type Alias: UserContext~~
2
+
3
+ ```ts
4
+ type UserContext = {
5
+ client: ServiceContextState["client"];
6
+ isUserContext: true;
7
+ tokenFingerprint?: string;
8
+ userEmail?: string;
9
+ userId: string;
10
+ userName?: string;
11
+ warehouseId?: Promise<string>;
12
+ workspaceId: Promise<string>;
13
+ };
14
+
15
+ ```
16
+
17
+ ## Deprecated[​](#deprecated "Direct link to Deprecated")
18
+
19
+ Use CallerContext and its principal field. Kept for callers that construct the legacy shape or read its flat identity fields.
20
+
21
+ ## Properties[​](#properties "Direct link to Properties")
22
+
23
+ ### ~~client~~[​](#client "Direct link to client")
24
+
25
+ ```ts
26
+ client: ServiceContextState["client"];
27
+
28
+ ```
29
+
30
+ WorkspaceClient authenticated as the user
31
+
32
+ ***
33
+
34
+ ### ~~isUserContext~~[​](#isusercontext "Direct link to isusercontext")
35
+
36
+ ```ts
37
+ isUserContext: true;
38
+
39
+ ```
40
+
41
+ Flag indicating this is a user context
42
+
43
+ ***
44
+
45
+ ### ~~tokenFingerprint?~~[​](#tokenfingerprint "Direct link to tokenfingerprint")
46
+
47
+ ```ts
48
+ optional tokenFingerprint: string;
49
+
50
+ ```
51
+
52
+ Truncated SHA-256 hash of the user's OBO token, used to detect token rotation
53
+
54
+ ***
55
+
56
+ ### ~~userEmail?~~[​](#useremail "Direct link to useremail")
57
+
58
+ ```ts
59
+ optional userEmail: string;
60
+
61
+ ```
62
+
63
+ The user's email (from `x-forwarded-email` header)
64
+
65
+ ***
66
+
67
+ ### ~~userId~~[​](#userid "Direct link to userid")
68
+
69
+ ```ts
70
+ userId: string;
71
+
72
+ ```
73
+
74
+ The user's ID (from request headers)
75
+
76
+ ***
77
+
78
+ ### ~~userName?~~[​](#username "Direct link to username")
79
+
80
+ ```ts
81
+ optional userName: string;
82
+
83
+ ```
84
+
85
+ The user's name (from request headers)
86
+
87
+ ***
88
+
89
+ ### ~~warehouseId?~~[​](#warehouseid "Direct link to warehouseid")
90
+
91
+ ```ts
92
+ optional warehouseId: Promise<string>;
93
+
94
+ ```
95
+
96
+ #### Deprecated[​](#deprecated-1 "Direct link to Deprecated")
97
+
98
+ Use getWarehouseId() from @databricks/appkit.
99
+
100
+ ***
101
+
102
+ ### ~~workspaceId~~[​](#workspaceid "Direct link to workspaceid")
103
+
104
+ ```ts
105
+ workspaceId: Promise<string>;
106
+
107
+ ```
108
+
109
+ Promise that resolves to the workspace ID (inherited from service context)
@@ -0,0 +1,39 @@
1
+ # Type Alias: UserScopedApp\<U>
2
+
3
+ ```ts
4
+ type UserScopedApp<U> = ScopedPluginMap<U> & {
5
+ run: Promise<T>;
6
+ };
7
+
8
+ ```
9
+
10
+ ## Type Declaration[​](#type-declaration "Direct link to Type Declaration")
11
+
12
+ ### run()[​](#run "Direct link to run()")
13
+
14
+ ```ts
15
+ run<T>(fn: (kit: ScopedPluginMap<U>) => T | Promise<T>): Promise<T>;
16
+
17
+ ```
18
+
19
+ #### Type Parameters[​](#type-parameters "Direct link to Type Parameters")
20
+
21
+ | Type Parameter |
22
+ | -------------- |
23
+ | `T` |
24
+
25
+ #### Parameters[​](#parameters "Direct link to Parameters")
26
+
27
+ | Parameter | Type |
28
+ | --------- | ---------------------------------------------------------------------------------------------------------------- |
29
+ | `fn` | (`kit`: [`ScopedPluginMap`](./docs/api/appkit/TypeAlias.ScopedPluginMap.md)<`U`>) => `T` \| `Promise`<`T`> |
30
+
31
+ #### Returns[​](#returns "Direct link to Returns")
32
+
33
+ `Promise`<`T`>
34
+
35
+ ## Type Parameters[​](#type-parameters-1 "Direct link to Type Parameters")
36
+
37
+ | Type Parameter |
38
+ | ----------------------------------------------------------------------------------------------------------------------------------- |
39
+ | `U` *extends* readonly [`PluginData`](./docs/api/appkit/TypeAlias.PluginData.md)<`PluginConstructor`, `unknown`, `string`>\[] |
@@ -21,12 +21,14 @@ Documentation merge entry for Typedoc — combines the stable `@databricks/appki
21
21
  | [DatabaseValidationError](./docs/api/appkit/Class.DatabaseValidationError.md) | Deliberate validation failure raised by a database mutation hook. Generated routes answer `422` and echo only the issues naming a public column; every other failure raised inside a hook stays an opaque server error. |
22
22
  | [DatabricksAdapter](./docs/api/appkit/Class.DatabricksAdapter.md) | Adapter that talks directly to Databricks Model Serving `/invocations` endpoint. |
23
23
  | [ExecutionError](./docs/api/appkit/Class.ExecutionError.md) | Error thrown when an operation execution fails. Use for statement failures, canceled operations, or unexpected states. |
24
+ | [IdentityExpiredError](./docs/api/appkit/Class.IdentityExpiredError.md) | The downstream service rejected the active caller's credentials. |
24
25
  | [InitializationError](./docs/api/appkit/Class.InitializationError.md) | Error thrown when a service or component is not properly initialized. Use when accessing services before they are ready. |
25
26
  | [MlflowClient](./docs/api/appkit/Class.MlflowClient.md) | A thin client over the Databricks workspace REST API, owning the host + bearer token so callers (eval-run creation, assessment writes, the judge's serving endpoint) don't each re-derive URLs or re-attach auth. The host is normalized once at construction. |
26
27
  | [Plugin](./docs/api/appkit/Class.Plugin.md) | Base abstract class for creating AppKit plugins. |
27
28
  | [PolicyDeniedError](./docs/api/appkit/Class.PolicyDeniedError.md) | Thrown when a policy denies an action. |
28
29
  | [ResourceRegistry](./docs/api/appkit/Class.ResourceRegistry.md) | Central registry for tracking plugin resource requirements. Deduplication uses type + resourceKey (machine-stable); alias is for display only. |
29
30
  | [ServerError](./docs/api/appkit/Class.ServerError.md) | Error thrown when server lifecycle operations fail. Use for server start/stop issues, configuration conflicts, etc. |
31
+ | [ServiceContext](./docs/api/appkit/Class.ServiceContext.md) | ServiceContext is a singleton that manages the service principal's WorkspaceClient and workspace ID. WarehouseResource owns warehouse bindings. |
30
32
  | [SupervisorApiAdapter](./docs/api/appkit/Class.SupervisorApiAdapter.md) | Adapter that calls the Databricks AI Gateway Responses API (`/ai-gateway/mlflow/v1/responses`). |
31
33
  | [TunnelError](./docs/api/appkit/Class.TunnelError.md) | Error thrown when remote tunnel operations fail. Use for tunnel connection issues, message parsing failures, etc. |
32
34
  | [ValidationError](./docs/api/appkit/Class.ValidationError.md) | Error thrown when input validation fails. Use for invalid parameters, missing required fields, or type mismatches. |
@@ -135,10 +137,12 @@ Documentation merge entry for Typedoc — combines the stable `@databricks/appki
135
137
 
136
138
  | Type Alias | Description |
137
139
  | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
140
+ | [AgentAuth](./docs/api/appkit/TypeAlias.AgentAuth.md) | Identity an agent runs under. The only value is on-behalf-of-user. |
138
141
  | [AgentEvent](./docs/api/appkit/TypeAlias.AgentEvent.md) | - |
139
142
  | [AgentTool](./docs/api/appkit/TypeAlias.AgentTool.md) | Any tool an agent can invoke: inline function tools (`tool()`), hosted MCP tools (`mcpServer()` / raw hosted), toolkit references from plugins (`analytics().toolkit()`), or adapter-hosted Supervisor-API tools (`supervisorTools.*`). |
140
143
  | [AgentTools](./docs/api/appkit/TypeAlias.AgentTools.md) | Per-agent tool record. String keys map to inline tools, toolkit entries, hosted tools, etc. |
141
144
  | [AgentToolsFn](./docs/api/appkit/TypeAlias.AgentToolsFn.md) | Function form of `AgentDefinition.tools`. Receives the typed [Plugins](./docs/api/appkit/TypeAlias.Plugins.md) map and returns a tool record. Invoked exactly once at setup (or once per `runAgent` call in standalone mode); the result is cached as the agent's resolved tool record. |
145
+ | [AppKitApi](./docs/api/appkit/TypeAlias.AppKitApi.md) | App instance with plugin exports and an explicit caller-scoped entry point. |
142
146
  | [BaseSystemPromptOption](./docs/api/appkit/TypeAlias.BaseSystemPromptOption.md) | - |
143
147
  | [CallerPrincipal](./docs/api/appkit/TypeAlias.CallerPrincipal.md) | The caller identity whose permissions authorize execution, not its resources. |
144
148
  | [ConfigSchema](./docs/api/appkit/TypeAlias.ConfigSchema.md) | Configuration schema definition for plugin config. Re-exported from the standard JSON Schema Draft 7 types. |
@@ -163,6 +167,7 @@ Documentation merge entry for Typedoc — combines the stable `@databricks/appki
163
167
  | [ResolvedToolEntry](./docs/api/appkit/TypeAlias.ResolvedToolEntry.md) | Internal tool-index entry after a tool record has been resolved to a dispatchable form. |
164
168
  | [ResourceFieldEntry](./docs/api/appkit/TypeAlias.ResourceFieldEntry.md) | - |
165
169
  | [ResourcePermission](./docs/api/appkit/TypeAlias.ResourcePermission.md) | Union of all possible permission levels across all resource types. |
170
+ | [ScopedPluginMap](./docs/api/appkit/TypeAlias.ScopedPluginMap.md) | - |
166
171
  | [SearchFilters](./docs/api/appkit/TypeAlias.SearchFilters.md) | - |
167
172
  | [ServingFactory](./docs/api/appkit/TypeAlias.ServingFactory.md) | Factory function returned by `AppKit.serving`. |
168
173
  | [Severity](./docs/api/appkit/TypeAlias.Severity.md) | Whether an assertion fails the eval (`gate`) or is tracked only (`soft`). |
@@ -170,6 +175,8 @@ Documentation merge entry for Typedoc — combines the stable `@databricks/appki
170
175
  | [ToolRegistry](./docs/api/appkit/TypeAlias.ToolRegistry.md) | - |
171
176
  | [ToPlugin](./docs/api/appkit/TypeAlias.ToPlugin.md) | Factory function type returned by `toPlugin()`. Accepts optional config and returns a PluginData tuple. |
172
177
  | [TransactionClient](./docs/api/appkit/TypeAlias.TransactionClient.md) | Entity and SQL capabilities bound to one transaction. |
178
+ | [~~UserContext~~](./docs/api/appkit/TypeAlias.UserContext.md) | - |
179
+ | [UserScopedApp](./docs/api/appkit/TypeAlias.UserScopedApp.md) | - |
173
180
 
174
181
  ## Variables[​](#variables "Direct link to Variables")
175
182
 
@@ -226,13 +233,16 @@ Documentation merge entry for Typedoc — combines the stable `@databricks/appki
226
233
  | [fromSupervisorApi](./docs/api/appkit/Function.fromSupervisorApi.md) | Creates an [AgentAdapter](./docs/api/appkit/Interface.AgentAdapter.md) backed by the Databricks AI Gateway Responses API (`/ai-gateway/mlflow/v1/responses`). |
227
234
  | [functionToolToDefinition](./docs/api/appkit/Function.functionToolToDefinition.md) | - |
228
235
  | [generateDatabaseCredential](./docs/api/appkit/Function.generateDatabaseCredential.md) | Generate OAuth credentials for Postgres database connection using the proper Postgres API. |
236
+ | [getCallerContext](./docs/api/appkit/Function.getCallerContext.md) | Get the caller context if one is active, otherwise `undefined`. Unlike `getExecutionContext()`, this does not require `ServiceContext` to be initialized and never throws. |
229
237
  | [getCurrentActorId](./docs/api/appkit/Function.getCurrentActorId.md) | The initiating user in a caller scope; no user actor exists in service scope. |
230
238
  | [getCurrentPrincipalKey](./docs/api/appkit/Function.getCurrentPrincipalKey.md) | Get the principal key for future cache keying: `app` or `user:<id>`. |
239
+ | [~~getCurrentUserId~~](./docs/api/appkit/Function.getCurrentUserId.md) | - |
231
240
  | [getExecutionContext](./docs/api/appkit/Function.getExecutionContext.md) | Get the current execution context. |
232
241
  | [getLakebaseOrmConfig](./docs/api/appkit/Function.getLakebaseOrmConfig.md) | Get Lakebase connection configuration for ORMs that don't accept pg.Pool directly. |
233
242
  | [getLakebasePgConfig](./docs/api/appkit/Function.getLakebasePgConfig.md) | Get Lakebase connection configuration for PostgreSQL clients. |
234
243
  | [getPluginManifest](./docs/api/appkit/Function.getPluginManifest.md) | Loads and validates the manifest from a plugin constructor. Normalizes string type/permission to strict ResourceType/ResourcePermission. |
235
244
  | [getResourceRequirements](./docs/api/appkit/Function.getResourceRequirements.md) | Gets the resource requirements from a plugin's manifest. |
245
+ | [~~getUserContext~~](./docs/api/appkit/Function.getUserContext.md) | - |
236
246
  | [getUsernameWithApiLookup](./docs/api/appkit/Function.getUsernameWithApiLookup.md) | Resolves the PostgreSQL username for a Lakebase connection. |
237
247
  | [getWarehouseId](./docs/api/appkit/Function.getWarehouseId.md) | Get the configured SQL warehouse ID after app initialization. The warehouse is an app resource; SP and caller executions use the same binding. Deprecated user-context scopes retain support for explicit warehouse overrides. |
238
248
  | [getWorkspaceClient](./docs/api/appkit/Function.getWorkspaceClient.md) | Get workspace client from config or SDK default auth chain |
@@ -241,10 +251,12 @@ Documentation merge entry for Typedoc — combines the stable `@databricks/appki
241
251
  | [integer](./docs/api/appkit/Function.integer.md) | - |
242
252
  | [isFunctionTool](./docs/api/appkit/Function.isFunctionTool.md) | - |
243
253
  | [isHostedTool](./docs/api/appkit/Function.isHostedTool.md) | - |
254
+ | [isInUserContext](./docs/api/appkit/Function.isInUserContext.md) | Check if currently running in a user context. |
244
255
  | [isJudgeConfigured](./docs/api/appkit/Function.isJudgeConfigured.md) | - |
245
256
  | [isSQLTypeMarker](./docs/api/appkit/Function.isSQLTypeMarker.md) | Type guard to check if a value is a SQL type marker |
246
257
  | [isSupervisorTool](./docs/api/appkit/Function.isSupervisorTool.md) | Type guard for [HostedSupervisorTool](./docs/api/appkit/Interface.HostedSupervisorTool.md). Used by the agents plugin (`buildToolIndex`) and standalone `runAgent` (`classifyTool`) to route supervisor-hosted tools to the extensions payload rather than the adapter's `tools` array. |
247
258
  | [isToolkitEntry](./docs/api/appkit/Function.isToolkitEntry.md) | Type guard for `ToolkitEntry` — used by the agents plugin to differentiate toolkit references from inline tools in a mixed `tools` record. |
259
+ | [~~isUserContext~~](./docs/api/appkit/Function.isUserContext.md) | - |
248
260
  | [jsonb](./docs/api/appkit/Function.jsonb.md) | - |
249
261
  | [loadAgentFromFile](./docs/api/appkit/Function.loadAgentFromFile.md) | Loads a single markdown agent file and resolves its frontmatter against registered plugin toolkits + ambient tool library. |
250
262
  | [loadAgentsFromDir](./docs/api/appkit/Function.loadAgentsFromDir.md) | Scans a directory for one subdirectory per agent, each containing `agent.md` (frontmatter + body). Produces an `AgentDefinition` record keyed by agent id (folder name). Throws on frontmatter errors or unresolved references. Returns an empty map if the directory does not exist. |
@@ -261,6 +273,8 @@ Documentation merge entry for Typedoc — combines the stable `@databricks/appki
261
273
  | [runAgent](./docs/api/appkit/Function.runAgent.md) | Standalone agent execution without `createApp`. Resolves the adapter, binds inline tools, and drives the adapter's `run()` loop to completion. |
262
274
  | [runEval](./docs/api/appkit/Function.runEval.md) | Run a single eval against a driver. Never throws for assertion or agent failures — those become a non-passing [EvalResult](./docs/api/appkit/Interface.EvalResult.md). Only a malformed eval definition surfaces as `result.error`. |
263
275
  | [runEvalsInDir](./docs/api/appkit/Function.runEvalsInDir.md) | Discover, load, and run every eval under each agent's `evals/` dir, driving the agents on a running app. Never throws for an individual eval — load/run failures become non-passing [EvalResult](./docs/api/appkit/Interface.EvalResult.md)s. |
276
+ | [runInCallerContext](./docs/api/appkit/Function.runInCallerContext.md) | Run a function with an immutable snapshot of the caller context. Nested and concurrent scopes keep their own identities. |
277
+ | [~~runInUserContext~~](./docs/api/appkit/Function.runInUserContext.md) | - |
264
278
  | [runWithRetries](./docs/api/appkit/Function.runWithRetries.md) | Run `attempt` up to `1 + retries` times, stopping as soon as it returns a result that is neither a thrown error / per-eval timeout (`error`) nor a transport/agent turn failure (`infraFailure`). Assertion failures set neither, so a failed-but-completed eval is returned on the first try and never retried. Returns the last result when every attempt failed on infra. |
265
279
  | [summarize](./docs/api/appkit/Function.summarize.md) | - |
266
280
  | [text](./docs/api/appkit/Function.text.md) | - |
@@ -326,6 +326,49 @@ const result = await runAgent(classifier, {
326
326
 
327
327
  MCP hosted tools (`mcpServer(...)`) still require `agents()` (they need a live MCP client). Supervisor-API hosted tools (`supervisorTools.*`), by contrast, **work in standalone `runAgent`** — the adapter has everything it needs to execute them server-side. This makes batch-eval / CI use of supervisor agents possible without `createApp`. Plugin tool dispatch in standalone mode runs as the service principal (no OBO) and **bypasses the agents-plugin approval gate** — treat standalone runAgent as a trusted-prompt environment (CI, batch eval, internal scripts), not as an exposed user-facing surface.
328
328
 
329
+ ## Execution identity[​](#execution-identity "Direct link to Execution identity")
330
+
331
+ By default an agent runs **mixed**: the model call and hand-rolled `tool({ execute })` tools run as the app's service principal, and plugin-toolkit tools run as the requesting user. Set `auth: "on-behalf-of-user"` to run the whole agent as the user:
332
+
333
+ ```ts
334
+ agents({ auth: "on-behalf-of-user" }); // default for every agent
335
+ createAgent({ instructions: "...", auth: "on-behalf-of-user" }); // one agent
336
+
337
+ ```
338
+
339
+ In markdown, set `auth: on-behalf-of-user` in the frontmatter. A per-agent value overrides the plugin default. Omitting `auth` keeps the mixed behavior; there is no all-service-principal mode.
340
+
341
+ | Piece | Default (mixed) | `on-behalf-of-user` |
342
+ | ------------------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------- |
343
+ | Model call | service principal | user |
344
+ | Plugin-toolkit tools | user | user |
345
+ | Hand-rolled `tool({ execute })` | service principal | user |
346
+ | Sub-agents | own mode | own mode, never service principal |
347
+ | Standalone `runAgent` | service principal, or user tools with `caller` | requires `caller` (or an ambient user scope); model and tools as user |
348
+ | MLflow tracing | service principal | service principal (exception) |
349
+ | Thread store | service principal | service principal (exception) |
350
+ | Catalog skills volume | service principal | service principal (exception) |
351
+ | Missing user token | plugin tools reject; the rest runs as the service principal | the request is rejected with 401 before any model or tool call |
352
+
353
+ An on-behalf-of-user agent fails closed:
354
+
355
+ * No forwarded user token: `401` before any model or tool call, in production and in development. There is no service-principal fallback.
356
+ * A `401` from the model mid-run becomes an `IDENTITY_EXPIRED` error event and the stream ends. The run is not retried as the service principal.
357
+ * A sub-agent never widens: under an on-behalf-of-user parent, a mixed sub-agent also runs as the user.
358
+
359
+ **Exceptions.** MLflow tracing, the thread store, and catalog skills (see [Catalog skills](#catalog-skills-unity-catalog-volume)) are app-owned and stay service principal in every mode. Thread rows are keyed by the user id.
360
+
361
+ **Pre-built adapters.** The user's client is applied when AppKit builds the adapter from a model string (`model: "my-endpoint"`, `defaultModel`, or `DATABRICKS_SERVING_ENDPOINT_NAME`). If you build a `DatabricksAdapter` yourself with a fixed `workspaceClient`, an on-behalf-of-user agent throws at boot instead of running the model as the service principal. Pass a provider so the client resolves per call, or use a model string. Mixed agents accept fixed-client adapters as before:
362
+
363
+ ```ts
364
+ DatabricksAdapter.fromModelServing("my-endpoint", {
365
+ workspaceClient: () => getWorkspaceClient(),
366
+ });
367
+
368
+ ```
369
+
370
+ **Provisioning.** Each user needs the `model-serving` user API scope on the app, and `CAN_QUERY` on any custom serving endpoint the agent calls. Plugin tools still need their own scopes and grants as in mixed mode.
371
+
329
372
  ## Adding agents to an existing app[​](#adding-agents-to-an-existing-app "Direct link to Adding agents to an existing app")
330
373
 
331
374
  Already have an app and want to add agents? What you touch depends on the kind:
@@ -492,6 +535,7 @@ agents({
492
535
  agents?: Record<string, AgentDefinition>, // DEPRECATED — use server/agents/<id>/ discovery
493
536
  defaultAgent?: string,
494
537
  defaultModel?: AgentAdapter | Promise<AgentAdapter> | string,
538
+ auth?: "on-behalf-of-user", // default: mixed (see Execution identity)
495
539
  tools?: Record<string, AgentTool>,
496
540
  autoInheritTools?: boolean | { file?: boolean, code?: boolean },
497
541
  autoInheritSkills?: boolean | { file?: boolean, code?: boolean }, // default off
@@ -956,6 +1000,7 @@ Skip `--experiment` (and `MLFLOW_EXPERIMENT_ID`) to run evals purely locally wit
956
1000
  | `maxTokens` | number | Adapter max-token hint. |
957
1001
  | `generationParams` | object | Adapter generation params (e.g. `temperature`, `top_p`) passed through when AppKit builds the adapter. |
958
1002
  | `baseSystemPrompt` | false \| string | Per-agent override. `false` disables the AppKit base prompt. |
1003
+ | `auth` | string | `on-behalf-of-user` runs this agent as the user. Any other value throws at boot. See [Execution identity](#execution-identity). |
959
1004
  | `ephemeral` | boolean | If `true`, the thread created for a chat request against this agent is deleted from `ThreadStore` after the stream finishes. Use for stateless one-shot agents (e.g. autocomplete) so history does not accumulate or contaminate future calls. Defaults to `false`. |
960
1005
 
961
1006
  Unknown keys are logged and ignored. Invalid YAML and missing plugin/tool references throw at boot.
@@ -14,7 +14,9 @@ Restrict access to the app and grant its service principal only the database per
14
14
 
15
15
  ## Basic usage[​](#basic-usage "Direct link to Basic usage")
16
16
 
17
- Configure a Lakebase `postgres` resource and its connection environment variables as described in [Lakebase configuration](./docs/plugins/lakebase.md#environment-variables). The database tables must already exist and match the declared schema. This plugin checks connectivity during setup; it does not create or migrate tables.
17
+ Configure a Lakebase `postgres` resource and its connection environment variables as described in [Lakebase configuration](./docs/plugins/lakebase.md#environment-variables).
18
+
19
+ When a query fails at runtime, the client receives only a stable message such as `Database operation failed`. The server log records the SQLSTATE and only identifier-only messages for known missing-column or missing-table errors (for example `column notes.board_id does not exist`). Other driver messages, details, and hints are omitted because they may contain row values.
18
20
 
19
21
  Apps scaffolded with the Database plugin selected include an empty `config/database/schema.ts`, so `database()` can start without requiring sample tables. Replace the empty declaration with your models when their PostgreSQL tables are ready.
20
22