@databricks/appkit 0.47.1 → 0.49.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 (78) hide show
  1. package/CLAUDE.md +11 -1
  2. package/dist/agents/databricks.d.ts +24 -7
  3. package/dist/agents/databricks.d.ts.map +1 -1
  4. package/dist/agents/databricks.js +25 -0
  5. package/dist/agents/databricks.js.map +1 -1
  6. package/dist/agents/supervisor-api.d.ts +362 -0
  7. package/dist/agents/supervisor-api.d.ts.map +1 -0
  8. package/dist/agents/supervisor-api.js +498 -0
  9. package/dist/agents/supervisor-api.js.map +1 -0
  10. package/dist/appkit/package.js +1 -1
  11. package/dist/beta.d.ts +2 -1
  12. package/dist/beta.js +2 -1
  13. package/dist/cli/commands/lint.js +6 -0
  14. package/dist/cli/commands/lint.js.map +1 -1
  15. package/dist/connectors/serving/client.d.ts +24 -0
  16. package/dist/connectors/serving/client.d.ts.map +1 -0
  17. package/dist/connectors/serving/client.js +34 -14
  18. package/dist/connectors/serving/client.js.map +1 -1
  19. package/dist/core/agent/run-agent.d.ts.map +1 -1
  20. package/dist/core/agent/run-agent.js +51 -2
  21. package/dist/core/agent/run-agent.js.map +1 -1
  22. package/dist/core/agent/types.d.ts +19 -3
  23. package/dist/core/agent/types.d.ts.map +1 -1
  24. package/dist/core/agent/types.js.map +1 -1
  25. package/dist/core/appkit.d.ts.map +1 -1
  26. package/dist/core/appkit.js +39 -1
  27. package/dist/core/appkit.js.map +1 -1
  28. package/dist/index.js +2 -2
  29. package/dist/plugins/agents/agents.d.ts.map +1 -1
  30. package/dist/plugins/agents/agents.js +65 -5
  31. package/dist/plugins/agents/agents.js.map +1 -1
  32. package/dist/plugins/files/plugin.js +2 -2
  33. package/dist/plugins/jobs/plugin.js +2 -2
  34. package/dist/plugins/serving/serving.js +2 -2
  35. package/dist/plugins/ui-variants/choice-sink.js +70 -0
  36. package/dist/plugins/ui-variants/choice-sink.js.map +1 -0
  37. package/dist/plugins/ui-variants/index.js +94 -0
  38. package/dist/plugins/ui-variants/index.js.map +1 -0
  39. package/dist/plugins/ui-variants/manifest.js +17 -0
  40. package/dist/plugins/ui-variants/manifest.js.map +1 -0
  41. package/dist/registry/manifest-loader.d.ts +1 -1
  42. package/dist/schemas/manifest.d.ts +1 -0
  43. package/dist/schemas/manifest.d.ts.map +1 -1
  44. package/dist/schemas/manifest.js +1 -0
  45. package/dist/schemas/manifest.js.map +1 -1
  46. package/dist/shared/src/agent.d.ts +28 -0
  47. package/dist/shared/src/agent.d.ts.map +1 -1
  48. package/dist/shared/src/plugin.d.ts +3 -1
  49. package/dist/shared/src/plugin.d.ts.map +1 -1
  50. package/dist/shared/src/schemas/manifest.d.ts +3 -2
  51. package/dist/shared/src/schemas/manifest.d.ts.map +1 -1
  52. package/dist/stream/index.js +1 -0
  53. package/dist/stream/sse-reader.js +86 -0
  54. package/dist/stream/sse-reader.js.map +1 -0
  55. package/docs/api/appkit/Class.DatabricksAdapter.md +34 -0
  56. package/docs/api/appkit/Class.SupervisorApiAdapter.md +121 -0
  57. package/docs/api/appkit/Function.fromSupervisorApi.md +63 -0
  58. package/docs/api/appkit/Function.isSupervisorTool.md +18 -0
  59. package/docs/api/appkit/Interface.AgentAdapter.md +24 -0
  60. package/docs/api/appkit/Interface.AgentInput.md +13 -0
  61. package/docs/api/appkit/Interface.HostedSupervisorTool.md +21 -0
  62. package/docs/api/appkit/Interface.PluginManifest.md +27 -9
  63. package/docs/api/appkit/Interface.SupervisorApiAdapterOptions.md +38 -0
  64. package/docs/api/appkit/Interface.SupervisorExtension.md +12 -0
  65. package/docs/api/appkit/Interface.WorkspaceClientLike.md +67 -0
  66. package/docs/api/appkit/TypeAlias.AgentTool.md +3 -2
  67. package/docs/api/appkit/TypeAlias.ResolvedToolEntry.md +167 -0
  68. package/docs/api/appkit/TypeAlias.SupervisorTool.md +45 -0
  69. package/docs/api/appkit/Variable.SUPERVISOR_EXTENSION_KEY.md +8 -0
  70. package/docs/api/appkit/Variable.supervisorTools.md +176 -0
  71. package/docs/api/appkit.md +118 -108
  72. package/docs/plugins/agents.md +131 -1
  73. package/docs/plugins/manifest.md +12 -11
  74. package/llms.txt +11 -1
  75. package/package.json +2 -1
  76. package/sbom.cdx.json +1 -1
  77. package/scripts/postinstall.js +0 -1
  78. package/skills/appkit-ui-variants/SKILL.md +183 -0
@@ -0,0 +1,86 @@
1
+ //#region src/stream/sse-reader.ts
2
+ const DEFAULT_MAX_SSE_LINE_CHARS = 1024 * 1024;
3
+ const DEFAULT_MAX_SSE_BUFFER_CHARS = 8 * 1024 * 1024;
4
+ /**
5
+ * Async-iterates Server-Sent Events from a UTF-8 byte stream.
6
+ *
7
+ * Block-oriented parser: events are delimited by blank lines (`\n\n` after
8
+ * CRLF normalization), so an `event:` line in chunk N pairs correctly with a
9
+ * `data:` line in chunk N+1 — no hoisted state needed.
10
+ *
11
+ * The reader passes through the sentinel string `[DONE]` as `event=""`,
12
+ * `data="[DONE]"`. Callers that care about it should match `data === "[DONE]"`
13
+ * after destructuring.
14
+ *
15
+ * Terminates when the stream closes or `signal` aborts; releases the reader
16
+ * lock in either case. Throws when {@link ReadSseEventsOptions.maxLineChars}
17
+ * or {@link ReadSseEventsOptions.maxBufferChars} are exceeded.
18
+ */
19
+ async function* readSseEvents(stream, signal, options) {
20
+ const maxLineChars = options?.maxLineChars ?? DEFAULT_MAX_SSE_LINE_CHARS;
21
+ const maxBufferChars = options?.maxBufferChars ?? DEFAULT_MAX_SSE_BUFFER_CHARS;
22
+ const reader = stream.getReader();
23
+ const decoder = new TextDecoder();
24
+ let buffer = "";
25
+ const onAbort = () => {
26
+ reader.cancel().catch(() => {});
27
+ };
28
+ if (signal) if (signal.aborted) onAbort();
29
+ else signal.addEventListener("abort", onAbort, { once: true });
30
+ try {
31
+ while (true) {
32
+ if (signal?.aborted) break;
33
+ const { done, value } = await reader.read();
34
+ if (done) {
35
+ if (buffer.length > maxLineChars) throw new Error(`readSseEvents: trailing SSE block exceeds maxLineChars (${maxLineChars} UTF-16 code units)`);
36
+ const tail = parseSseBlock(buffer);
37
+ if (tail) yield tail;
38
+ break;
39
+ }
40
+ buffer += decoder.decode(value, { stream: true });
41
+ const blocks = (buffer.indexOf("\r") !== -1 ? buffer.replace(/\r\n/g, "\n") : buffer).split("\n\n");
42
+ buffer = blocks.pop() ?? "";
43
+ if (buffer.length > maxBufferChars) throw new Error(`readSseEvents: incomplete SSE block exceeds maxBufferChars (${maxBufferChars} UTF-16 code units) without a terminator`);
44
+ for (const block of blocks) {
45
+ if (block.length > maxLineChars) throw new Error(`readSseEvents: SSE block exceeds maxLineChars (${maxLineChars} UTF-16 code units)`);
46
+ const event = parseSseBlock(block);
47
+ if (event) yield event;
48
+ }
49
+ }
50
+ } finally {
51
+ if (signal) signal.removeEventListener("abort", onAbort);
52
+ reader.releaseLock();
53
+ }
54
+ }
55
+ /**
56
+ * Per the SSE spec, only a single leading `U+0020` is stripped from a field
57
+ * value — not arbitrary whitespace. `trimStart()` would also strip tabs,
58
+ * NBSP, etc.; for callers that feed binary or whitespace-prefixed payloads
59
+ * this is a footgun.
60
+ */
61
+ function stripOneLeadingSpace(s) {
62
+ return s.startsWith(" ") ? s.slice(1) : s;
63
+ }
64
+ function parseSseBlock(block) {
65
+ if (block.length === 0) return null;
66
+ const lines = block.split("\n");
67
+ let eventName = "";
68
+ let id;
69
+ const dataLines = [];
70
+ for (const line of lines) {
71
+ if (line === "" || line.startsWith(":")) continue;
72
+ if (line.startsWith("event:")) eventName = stripOneLeadingSpace(line.slice(6));
73
+ else if (line.startsWith("data:")) dataLines.push(stripOneLeadingSpace(line.slice(5)));
74
+ else if (line.startsWith("id:")) id = stripOneLeadingSpace(line.slice(3));
75
+ }
76
+ if (dataLines.length === 0) return null;
77
+ return {
78
+ event: eventName,
79
+ data: dataLines.join("\n"),
80
+ id
81
+ };
82
+ }
83
+
84
+ //#endregion
85
+ export { readSseEvents };
86
+ //# sourceMappingURL=sse-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-reader.js","names":[],"sources":["../../src/stream/sse-reader.ts"],"sourcesContent":["/**\n * One parsed Server-Sent Event. Field names follow the spec:\n * https://html.spec.whatwg.org/multipage/server-sent-events.html\n *\n * The reader does not interpret `data` (no JSON parsing), so callers control\n * the wire shape they expect.\n */\nexport interface SseEvent {\n /** Value of the most recent `event:` field, or `\"\"` for an unnamed event. */\n event: string;\n /** Joined `data:` lines for the event (empty string when no data was set). */\n data: string;\n /** Value of the most recent `id:` field, or `undefined` if none. */\n id?: string;\n}\n\n/**\n * Configuration for {@link readSseEvents}. All limits are in UTF-16 code\n * units (JS string `.length`) and exist as a DoS guard (CWE-770) for\n * untrusted upstreams that might stream arbitrarily large lines or never\n * emit a block terminator.\n */\ninterface ReadSseEventsOptions {\n /**\n * Maximum length of any single SSE event block (i.e. the text between\n * two `\\n\\n` separators). Exceeding this throws.\n *\n * @default 1 MiB (1_048_576)\n */\n maxLineChars?: number;\n /**\n * Maximum length of the rolling input buffer when no block terminator\n * has been seen yet. Exceeding this throws — protects against an\n * upstream that streams indefinitely without ever sending `\\n\\n`.\n *\n * @default 8 MiB (8_388_608)\n */\n maxBufferChars?: number;\n}\n\nconst DEFAULT_MAX_SSE_LINE_CHARS = 1024 * 1024;\nconst DEFAULT_MAX_SSE_BUFFER_CHARS = 8 * 1024 * 1024;\n\n/**\n * Async-iterates Server-Sent Events from a UTF-8 byte stream.\n *\n * Block-oriented parser: events are delimited by blank lines (`\\n\\n` after\n * CRLF normalization), so an `event:` line in chunk N pairs correctly with a\n * `data:` line in chunk N+1 — no hoisted state needed.\n *\n * The reader passes through the sentinel string `[DONE]` as `event=\"\"`,\n * `data=\"[DONE]\"`. Callers that care about it should match `data === \"[DONE]\"`\n * after destructuring.\n *\n * Terminates when the stream closes or `signal` aborts; releases the reader\n * lock in either case. Throws when {@link ReadSseEventsOptions.maxLineChars}\n * or {@link ReadSseEventsOptions.maxBufferChars} are exceeded.\n */\nexport async function* readSseEvents(\n stream: ReadableStream<Uint8Array>,\n signal?: AbortSignal,\n options?: ReadSseEventsOptions,\n): AsyncGenerator<SseEvent, void, unknown> {\n const maxLineChars = options?.maxLineChars ?? DEFAULT_MAX_SSE_LINE_CHARS;\n const maxBufferChars =\n options?.maxBufferChars ?? DEFAULT_MAX_SSE_BUFFER_CHARS;\n\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n // Cancel the reader on abort so an in-flight `reader.read()` returns\n // immediately instead of waiting for the next chunk. Without this, an\n // aborted consumer would only notice between reads — fine for chatty\n // streams, but unbounded for an idle/heartbeat-less upstream.\n const onAbort = () => {\n reader.cancel().catch(() => {\n // `cancel()` rejects if the stream is already errored/closed; ignore.\n });\n };\n if (signal) {\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n try {\n while (true) {\n if (signal?.aborted) break;\n const { done, value } = await reader.read();\n if (done) {\n if (buffer.length > maxLineChars) {\n throw new Error(\n `readSseEvents: trailing SSE block exceeds maxLineChars (${maxLineChars} UTF-16 code units)`,\n );\n }\n const tail = parseSseBlock(buffer);\n if (tail) yield tail;\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n\n // Gate the CRLF normalize on `\\r` presence — saves a full-buffer\n // regex scan on every chunk for the common LF-only steady state.\n const normalized =\n buffer.indexOf(\"\\r\") !== -1 ? buffer.replace(/\\r\\n/g, \"\\n\") : buffer;\n const blocks = normalized.split(\"\\n\\n\");\n // Last entry is either an incomplete block or \"\" (when the chunk ended\n // exactly on a boundary). Either way, keep it for the next iteration.\n buffer = blocks.pop() ?? \"\";\n\n if (buffer.length > maxBufferChars) {\n throw new Error(\n `readSseEvents: incomplete SSE block exceeds maxBufferChars (${maxBufferChars} UTF-16 code units) without a terminator`,\n );\n }\n\n for (const block of blocks) {\n if (block.length > maxLineChars) {\n throw new Error(\n `readSseEvents: SSE block exceeds maxLineChars (${maxLineChars} UTF-16 code units)`,\n );\n }\n const event = parseSseBlock(block);\n if (event) yield event;\n }\n }\n } finally {\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n reader.releaseLock();\n }\n}\n\n/**\n * Per the SSE spec, only a single leading `U+0020` is stripped from a field\n * value — not arbitrary whitespace. `trimStart()` would also strip tabs,\n * NBSP, etc.; for callers that feed binary or whitespace-prefixed payloads\n * this is a footgun.\n */\nfunction stripOneLeadingSpace(s: string): string {\n return s.startsWith(\" \") ? s.slice(1) : s;\n}\n\nfunction parseSseBlock(block: string): SseEvent | null {\n if (block.length === 0) return null;\n // CRLF was already normalised at the buffer level, so each `line` here is\n // already free of trailing `\\r` — no per-line strip needed.\n const lines = block.split(\"\\n\");\n\n let eventName = \"\";\n let id: string | undefined;\n const dataLines: string[] = [];\n\n for (const line of lines) {\n if (line === \"\" || line.startsWith(\":\")) continue;\n\n if (line.startsWith(\"event:\")) {\n eventName = stripOneLeadingSpace(line.slice(6));\n } else if (line.startsWith(\"data:\")) {\n dataLines.push(stripOneLeadingSpace(line.slice(5)));\n } else if (line.startsWith(\"id:\")) {\n id = stripOneLeadingSpace(line.slice(3));\n }\n // Other fields (`retry:`, custom) are ignored by design.\n }\n\n // Per the SSE spec, a block is only dispatched when the data buffer is\n // non-empty. Blocks containing only `event:`/`id:` (or comments) do not\n // surface as events.\n if (dataLines.length === 0) return null;\n\n return {\n event: eventName,\n data: dataLines.join(\"\\n\"),\n id,\n };\n}\n"],"mappings":";AAwCA,MAAM,6BAA6B,OAAO;AAC1C,MAAM,+BAA+B,IAAI,OAAO;;;;;;;;;;;;;;;;AAiBhD,gBAAuB,cACrB,QACA,QACA,SACyC;CACzC,MAAM,eAAe,SAAS,gBAAgB;CAC9C,MAAM,iBACJ,SAAS,kBAAkB;CAE7B,MAAM,SAAS,OAAO,WAAW;CACjC,MAAM,UAAU,IAAI,aAAa;CACjC,IAAI,SAAS;CAMb,MAAM,gBAAgB;AACpB,SAAO,QAAQ,CAAC,YAAY,GAE1B;;AAEJ,KAAI,OACF,KAAI,OAAO,QAAS,UAAS;KACxB,QAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,MAAM,CAAC;AAGhE,KAAI;AACF,SAAO,MAAM;AACX,OAAI,QAAQ,QAAS;GACrB,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,OAAI,MAAM;AACR,QAAI,OAAO,SAAS,aAClB,OAAM,IAAI,MACR,2DAA2D,aAAa,qBACzE;IAEH,MAAM,OAAO,cAAc,OAAO;AAClC,QAAI,KAAM,OAAM;AAChB;;AAGF,aAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,MAAM,CAAC;GAMjD,MAAM,UADJ,OAAO,QAAQ,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,KAAK,GAAG,QACtC,MAAM,OAAO;AAGvC,YAAS,OAAO,KAAK,IAAI;AAEzB,OAAI,OAAO,SAAS,eAClB,OAAM,IAAI,MACR,+DAA+D,eAAe,0CAC/E;AAGH,QAAK,MAAM,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,aACjB,OAAM,IAAI,MACR,kDAAkD,aAAa,qBAChE;IAEH,MAAM,QAAQ,cAAc,MAAM;AAClC,QAAI,MAAO,OAAM;;;WAGb;AACR,MAAI,OAAQ,QAAO,oBAAoB,SAAS,QAAQ;AACxD,SAAO,aAAa;;;;;;;;;AAUxB,SAAS,qBAAqB,GAAmB;AAC/C,QAAO,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,EAAE,GAAG;;AAG1C,SAAS,cAAc,OAAgC;AACrD,KAAI,MAAM,WAAW,EAAG,QAAO;CAG/B,MAAM,QAAQ,MAAM,MAAM,KAAK;CAE/B,IAAI,YAAY;CAChB,IAAI;CACJ,MAAM,YAAsB,EAAE;AAE9B,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,SAAS,MAAM,KAAK,WAAW,IAAI,CAAE;AAEzC,MAAI,KAAK,WAAW,SAAS,CAC3B,aAAY,qBAAqB,KAAK,MAAM,EAAE,CAAC;WACtC,KAAK,WAAW,QAAQ,CACjC,WAAU,KAAK,qBAAqB,KAAK,MAAM,EAAE,CAAC,CAAC;WAC1C,KAAK,WAAW,MAAM,CAC/B,MAAK,qBAAqB,KAAK,MAAM,EAAE,CAAC;;AAQ5C,KAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,QAAO;EACL,OAAO;EACP,MAAM,UAAU,KAAK,KAAK;EAC1B;EACD"}
@@ -149,3 +149,37 @@ Routes through the shared `connectors/serving/stream` helper, which delegates to
149
149
  #### Returns[​](#returns-3 "Direct link to Returns")
150
150
 
151
151
  `Promise`<`DatabricksAdapter`>
152
+
153
+ ***
154
+
155
+ ### fromSupervisorApi()[​](#fromsupervisorapi "Direct link to fromSupervisorApi()")
156
+
157
+ ```ts
158
+ static fromSupervisorApi(options: SupervisorApiAdapterOptions): Promise<AgentAdapter>;
159
+
160
+ ```
161
+
162
+ Discoverability shim for the Supervisor API adapter. Returns an [AgentAdapter](./docs/api/appkit/Interface.AgentAdapter.md) (a `SupervisorApiAdapter` at runtime), NOT a DatabricksAdapter — the two are separate classes (different wire formats, different lifecycle). The return type is the [AgentAdapter](./docs/api/appkit/Interface.AgentAdapter.md) interface so callers aren't bound to the concrete class. Surfaced here so application developers see a single `DatabricksAdapter.from*` autocomplete root.
163
+
164
+ Dynamic-imports `./supervisor-api` to avoid forming a load-time cycle: both files share `connectors/serving/client.ts`.
165
+
166
+ #### Parameters[​](#parameters-4 "Direct link to Parameters")
167
+
168
+ | Parameter | Type |
169
+ | --------- | ------------------------------------------------------------------------------------------------- |
170
+ | `options` | [`SupervisorApiAdapterOptions`](./docs/api/appkit/Interface.SupervisorApiAdapterOptions.md) |
171
+
172
+ #### Returns[​](#returns-4 "Direct link to Returns")
173
+
174
+ `Promise`<[`AgentAdapter`](./docs/api/appkit/Interface.AgentAdapter.md)>
175
+
176
+ #### Example[​](#example-1 "Direct link to Example")
177
+
178
+ ```ts
179
+ import { DatabricksAdapter } from "@databricks/appkit/beta";
180
+
181
+ const model = await DatabricksAdapter.fromSupervisorApi({
182
+ model: "databricks-claude-sonnet-4-5",
183
+ });
184
+
185
+ ```
@@ -0,0 +1,121 @@
1
+ # Class: SupervisorApiAdapter
2
+
3
+ Adapter that calls the Databricks AI Gateway Responses API (`/ai-gateway/mlflow/v1/responses`).
4
+
5
+ Streams SSE events in the OpenAI Responses API wire format and maps them to the AppKit `AgentEvent` protocol. Tool execution is handled server-side, so the adapter ignores the agents-plugin tool index.
6
+
7
+ Authentication is handled via the Databricks SDK credential chain — the same mechanism used by `DatabricksAdapter.fromModelServing`. The transport is injected via SupervisorApiAdapterCtorOptions.streamBody; the [fromSupervisorApi](./docs/api/appkit/Function.fromSupervisorApi.md) factory wires it through the SDK's `apiClient.request({ raw: true })`.
8
+
9
+ Set `DEBUG=appkit:agents:supervisor-api` to log the outbound request shape (model, instructions length, input shape, tool count) and to be notified when the recovery path engages (no incremental deltas, text pulled from `response.completed.output[]`). The no-delta warning includes a per-turn event-type histogram and the SA-reported status/error/ incomplete\_details, so it's already actionable without DEBUG.
10
+
11
+ Tools are not configured on the adapter. Declare them via `createAgent({ tools: () => ({ key: supervisorTools.genieSpace({...}) }) })` (or markdown frontmatter referencing an ambient `supervisorTools.*` entry); the agents plugin / standalone `runAgent` aggregates hosted-supervisor entries and routes them to the adapter via `AgentInput.extensions[SUPERVISOR_EXTENSION_KEY]`. Advanced callers invoking `adapter.run(...)` directly populate that key themselves.
12
+
13
+ ## Example[​](#example "Direct link to Example")
14
+
15
+ ```ts
16
+ import { createApp, createAgent } from "@databricks/appkit";
17
+ import {
18
+ agents,
19
+ DatabricksAdapter,
20
+ supervisorTools,
21
+ } from "@databricks/appkit/beta";
22
+
23
+ await createApp({
24
+ plugins: [
25
+ agents({
26
+ agents: {
27
+ assistant: createAgent({
28
+ instructions: "You are a helpful assistant.",
29
+ model: DatabricksAdapter.fromSupervisorApi({
30
+ model: "databricks-claude-sonnet-4",
31
+ }),
32
+ tools: () => ({
33
+ nyc: supervisorTools.genieSpace({
34
+ id: "01ABCDEF12345678",
35
+ description: "NYC taxi trip records and zones",
36
+ }),
37
+ }),
38
+ }),
39
+ },
40
+ }),
41
+ ],
42
+ });
43
+
44
+ ```
45
+
46
+ ## Implements[​](#implements "Direct link to Implements")
47
+
48
+ * [`AgentAdapter`](./docs/api/appkit/Interface.AgentAdapter.md)
49
+
50
+ ## Constructors[​](#constructors "Direct link to Constructors")
51
+
52
+ ### Constructor[​](#constructor "Direct link to Constructor")
53
+
54
+ ```ts
55
+ new SupervisorApiAdapter(options: SupervisorApiAdapterCtorOptions): SupervisorApiAdapter;
56
+
57
+ ```
58
+
59
+ #### Parameters[​](#parameters "Direct link to Parameters")
60
+
61
+ | Parameter | Type |
62
+ | --------- | --------------------------------- |
63
+ | `options` | `SupervisorApiAdapterCtorOptions` |
64
+
65
+ #### Returns[​](#returns "Direct link to Returns")
66
+
67
+ `SupervisorApiAdapter`
68
+
69
+ ## Properties[​](#properties "Direct link to Properties")
70
+
71
+ ### acceptsExtensions[​](#acceptsextensions "Direct link to acceptsExtensions")
72
+
73
+ ```ts
74
+ readonly acceptsExtensions: readonly ["databricks.supervisor"];
75
+
76
+ ```
77
+
78
+ Capability negotiation: the adapter reads its hosted-tool payload from [AgentInput.extensions](./docs/api/appkit/Interface.AgentInput.md#extensions) under [SUPERVISOR\_EXTENSION\_KEY](./docs/api/appkit/Variable.SUPERVISOR_EXTENSION_KEY.md). The agents plugin uses this list to warn at registration when the tool index produces extensions the adapter wouldn't consume.
79
+
80
+ #### Implementation of[​](#implementation-of "Direct link to Implementation of")
81
+
82
+ [`AgentAdapter`](./docs/api/appkit/Interface.AgentAdapter.md).[`acceptsExtensions`](./docs/api/appkit/Interface.AgentAdapter.md#acceptsextensions)
83
+
84
+ ***
85
+
86
+ ### consumesInputTools[​](#consumesinputtools "Direct link to consumesInputTools")
87
+
88
+ ```ts
89
+ readonly consumesInputTools: false = false;
90
+
91
+ ```
92
+
93
+ Capability negotiation: the adapter does not consume `input.tools`. Tool execution is owned by the Databricks AI Gateway server-side, so any function tools or local sub-agents declared on this agent would be silently dropped — the agents plugin warns at registration when that combination is detected.
94
+
95
+ #### Implementation of[​](#implementation-of-1 "Direct link to Implementation of")
96
+
97
+ [`AgentAdapter`](./docs/api/appkit/Interface.AgentAdapter.md).[`consumesInputTools`](./docs/api/appkit/Interface.AgentAdapter.md#consumesinputtools)
98
+
99
+ ## Methods[​](#methods "Direct link to Methods")
100
+
101
+ ### run()[​](#run "Direct link to run()")
102
+
103
+ ```ts
104
+ run(input: AgentInput, context: AgentRunContext): AsyncGenerator<AgentEvent, void, unknown>;
105
+
106
+ ```
107
+
108
+ #### Parameters[​](#parameters-1 "Direct link to Parameters")
109
+
110
+ | Parameter | Type |
111
+ | --------- | ------------------------------------------------------------------------- |
112
+ | `input` | [`AgentInput`](./docs/api/appkit/Interface.AgentInput.md) |
113
+ | `context` | [`AgentRunContext`](./docs/api/appkit/Interface.AgentRunContext.md) |
114
+
115
+ #### Returns[​](#returns-1 "Direct link to Returns")
116
+
117
+ `AsyncGenerator`<[`AgentEvent`](./docs/api/appkit/TypeAlias.AgentEvent.md), `void`, `unknown`>
118
+
119
+ #### Implementation of[​](#implementation-of-2 "Direct link to Implementation of")
120
+
121
+ [`AgentAdapter`](./docs/api/appkit/Interface.AgentAdapter.md).[`run`](./docs/api/appkit/Interface.AgentAdapter.md#run)
@@ -0,0 +1,63 @@
1
+ # Function: fromSupervisorApi()
2
+
3
+ ```ts
4
+ function fromSupervisorApi(options: SupervisorApiAdapterOptions): Promise<AgentAdapter>;
5
+
6
+ ```
7
+
8
+ Creates an [AgentAdapter](./docs/api/appkit/Interface.AgentAdapter.md) backed by the Databricks AI Gateway Responses API (`/ai-gateway/mlflow/v1/responses`).
9
+
10
+ Uses the SDK's default credential chain for auth (reads DATABRICKS\_HOST, DATABRICKS\_TOKEN, OAuth config, etc.). Tools are declared on the agent (via `createAgent({ tools })`), not on this factory.
11
+
12
+ Application code should prefer the [DatabricksAdapter.fromSupervisorApi](./docs/api/appkit/Class.DatabricksAdapter.md#fromsupervisorapi) static — it delegates here and keeps a single `DatabricksAdapter.from*` autocomplete root for all Databricks-backed adapters. This free function is the implementation behind the static and remains exported for callers that want to import it directly without pulling in [DatabricksAdapter](./docs/api/appkit/Class.DatabricksAdapter.md).
13
+
14
+ ## Parameters[​](#parameters "Direct link to Parameters")
15
+
16
+ | Parameter | Type |
17
+ | --------- | ------------------------------------------------------------------------------------------------- |
18
+ | `options` | [`SupervisorApiAdapterOptions`](./docs/api/appkit/Interface.SupervisorApiAdapterOptions.md) |
19
+
20
+ ## Returns[​](#returns "Direct link to Returns")
21
+
22
+ `Promise`<[`AgentAdapter`](./docs/api/appkit/Interface.AgentAdapter.md)>
23
+
24
+ ## Example[​](#example "Direct link to Example")
25
+
26
+ ```ts
27
+ import { createApp, createAgent } from "@databricks/appkit";
28
+ import {
29
+ agents,
30
+ DatabricksAdapter,
31
+ supervisorTools,
32
+ } from "@databricks/appkit/beta";
33
+
34
+ await createApp({
35
+ plugins: [
36
+ agents({
37
+ agents: {
38
+ assistant: createAgent({
39
+ instructions: "You are a helpful assistant.",
40
+ model: DatabricksAdapter.fromSupervisorApi({
41
+ model: "databricks-claude-sonnet-4",
42
+ }),
43
+ tools: () => ({
44
+ nyc: supervisorTools.genieSpace({
45
+ id: "01ABCDEF12345678",
46
+ description: "NYC taxi trip records and zones",
47
+ }),
48
+ }),
49
+ }),
50
+ },
51
+ }),
52
+ ],
53
+ });
54
+
55
+ ```
56
+
57
+ ## Remarks[​](#remarks "Direct link to Remarks")
58
+
59
+ ⚠ When passing your own `workspaceClient`, see the warning on [SupervisorApiAdapterOptions.workspaceClient](./docs/api/appkit/Interface.SupervisorApiAdapterOptions.md#workspaceclient) — the client is captured once and reused, so per-request OBO clients would leak identity across requests.
60
+
61
+ ## See[​](#see "Direct link to See")
62
+
63
+ [DatabricksAdapter.fromSupervisorApi](./docs/api/appkit/Class.DatabricksAdapter.md#fromsupervisorapi) — the recommended application-facing entry point.
@@ -0,0 +1,18 @@
1
+ # Function: isSupervisorTool()
2
+
3
+ ```ts
4
+ function isSupervisorTool(value: unknown): value is HostedSupervisorTool;
5
+
6
+ ```
7
+
8
+ 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.
9
+
10
+ ## Parameters[​](#parameters "Direct link to Parameters")
11
+
12
+ | Parameter | Type |
13
+ | --------- | --------- |
14
+ | `value` | `unknown` |
15
+
16
+ ## Returns[​](#returns "Direct link to Returns")
17
+
18
+ `value is HostedSupervisorTool`
@@ -1,5 +1,29 @@
1
1
  # Interface: AgentAdapter
2
2
 
3
+ ## Properties[​](#properties "Direct link to Properties")
4
+
5
+ ### acceptsExtensions?[​](#acceptsextensions "Direct link to acceptsExtensions?")
6
+
7
+ ```ts
8
+ readonly optional acceptsExtensions: readonly string[];
9
+
10
+ ```
11
+
12
+ Extension keys this adapter consumes from [AgentInput.extensions](./docs/api/appkit/Interface.AgentInput.md#extensions). The agents plugin (and standalone `runAgent`) warns at registration if the tool index produces extensions whose keys aren't listed here.
13
+
14
+ Adapters that don't read extensions can omit this field.
15
+
16
+ ***
17
+
18
+ ### consumesInputTools?[​](#consumesinputtools "Direct link to consumesInputTools?")
19
+
20
+ ```ts
21
+ readonly optional consumesInputTools: boolean;
22
+
23
+ ```
24
+
25
+ Whether the adapter consumes tools from `input.tools`. Defaults to true. Adapters whose tool execution happens elsewhere (e.g. the Supervisor API, where SA owns the tool loop server-side) declare false; the agents plugin warns at registration if the agent declares function tools or local sub-agents alongside such an adapter, since those tools would never reach the model.
26
+
3
27
  ## Methods[​](#methods "Direct link to Methods")
4
28
 
5
29
  ### run()[​](#run "Direct link to run()")
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## Properties[​](#properties "Direct link to Properties")
4
4
 
5
+ ### extensions?[​](#extensions "Direct link to extensions?")
6
+
7
+ ```ts
8
+ optional extensions: Readonly<Record<string, unknown>>;
9
+
10
+ ```
11
+
12
+ Adapter-specific opaque payloads, keyed by adapter namespace. The shared contract intentionally does not enumerate keys — see each adapter's docs for which keys it reads and the shape of each value.
13
+
14
+ The agents plugin and standalone `runAgent` populate this from the agent's tool index when entries declare an adapter-side spec (e.g. Supervisor API hosted tools). Adapters that don't read extensions should leave it untouched.
15
+
16
+ ***
17
+
5
18
  ### messages[​](#messages "Direct link to messages")
6
19
 
7
20
  ```ts
@@ -0,0 +1,21 @@
1
+ # Interface: HostedSupervisorTool
2
+
3
+ Tagged record returned by every [supervisorTools](./docs/api/appkit/Variable.supervisorTools.md) factory. The `__kind` discriminator lets the agents plugin (and standalone `runAgent`) classify these tools without a structural match against the wire format — keeps the SA wire shape free to evolve and avoids namespace collisions with MCP hosted tools (which use `type: "genie-space"` hyphenated, vs SA's `type: "genie_space"` underscored).
4
+
5
+ ## Properties[​](#properties "Direct link to Properties")
6
+
7
+ ### \_\_kind[​](#__kind "Direct link to __kind")
8
+
9
+ ```ts
10
+ readonly __kind: "hosted-supervisor";
11
+
12
+ ```
13
+
14
+ ***
15
+
16
+ ### spec[​](#spec "Direct link to spec")
17
+
18
+ ```ts
19
+ readonly spec: SupervisorTool;
20
+
21
+ ```
@@ -75,6 +75,24 @@ Omit.description
75
75
 
76
76
  ***
77
77
 
78
+ ### devOnly?[​](#devonly "Direct link to devOnly?")
79
+
80
+ ```ts
81
+ optional devOnly: boolean;
82
+
83
+ ```
84
+
85
+ When true, this plugin is only registered when NODE\_ENV === "development". In any other environment createApp skips it entirely (not constructed, no routes, resources not validated). Use for dev-only tooling that must never run in a deployed app.
86
+
87
+ #### Inherited from[​](#inherited-from-2 "Direct link to Inherited from")
88
+
89
+ ```ts
90
+ Omit.devOnly
91
+
92
+ ```
93
+
94
+ ***
95
+
78
96
  ### displayName[​](#displayname "Direct link to displayName")
79
97
 
80
98
  ```ts
@@ -84,7 +102,7 @@ displayName: string;
84
102
 
85
103
  Human-readable display name for UI and CLI
86
104
 
87
- #### Inherited from[​](#inherited-from-2 "Direct link to Inherited from")
105
+ #### Inherited from[​](#inherited-from-3 "Direct link to Inherited from")
88
106
 
89
107
  ```ts
90
108
  Omit.displayName
@@ -102,7 +120,7 @@ optional hidden: boolean;
102
120
 
103
121
  When true, this plugin is excluded from the template plugins manifest (appkit.plugins.json) during sync.
104
122
 
105
- #### Inherited from[​](#inherited-from-3 "Direct link to Inherited from")
123
+ #### Inherited from[​](#inherited-from-4 "Direct link to Inherited from")
106
124
 
107
125
  ```ts
108
126
  Omit.hidden
@@ -120,7 +138,7 @@ optional keywords: string[];
120
138
 
121
139
  Keywords for plugin discovery
122
140
 
123
- #### Inherited from[​](#inherited-from-4 "Direct link to Inherited from")
141
+ #### Inherited from[​](#inherited-from-5 "Direct link to Inherited from")
124
142
 
125
143
  ```ts
126
144
  Omit.keywords
@@ -138,7 +156,7 @@ optional license: string;
138
156
 
139
157
  SPDX license identifier
140
158
 
141
- #### Inherited from[​](#inherited-from-5 "Direct link to Inherited from")
159
+ #### Inherited from[​](#inherited-from-6 "Direct link to Inherited from")
142
160
 
143
161
  ```ts
144
162
  Omit.license
@@ -174,7 +192,7 @@ optional onSetupMessage: string;
174
192
 
175
193
  Message displayed to the user after project initialization. Use this to inform about manual setup steps (e.g. environment variables, resource provisioning).
176
194
 
177
- #### Inherited from[​](#inherited-from-6 "Direct link to Inherited from")
195
+ #### Inherited from[​](#inherited-from-7 "Direct link to Inherited from")
178
196
 
179
197
  ```ts
180
198
  Omit.onSetupMessage
@@ -192,7 +210,7 @@ optional repository: string;
192
210
 
193
211
  URL to the plugin's source repository
194
212
 
195
- #### Inherited from[​](#inherited-from-7 "Direct link to Inherited from")
213
+ #### Inherited from[​](#inherited-from-8 "Direct link to Inherited from")
196
214
 
197
215
  ```ts
198
216
  Omit.repository
@@ -278,7 +296,7 @@ optional should: string[];
278
296
 
279
297
  ```
280
298
 
281
- #### Inherited from[​](#inherited-from-8 "Direct link to Inherited from")
299
+ #### Inherited from[​](#inherited-from-9 "Direct link to Inherited from")
282
300
 
283
301
  ```ts
284
302
  Omit.scaffolding
@@ -296,7 +314,7 @@ optional stability: "beta" | "ga";
296
314
 
297
315
  Plugin stability level. Beta plugins may have breaking API changes between minor releases but are on a path to GA. GA (general availability) plugins follow semver strictly.
298
316
 
299
- #### Inherited from[​](#inherited-from-9 "Direct link to Inherited from")
317
+ #### Inherited from[​](#inherited-from-10 "Direct link to Inherited from")
300
318
 
301
319
  ```ts
302
320
  Omit.stability
@@ -314,7 +332,7 @@ optional version: string;
314
332
 
315
333
  Plugin version (semver format)
316
334
 
317
- #### Inherited from[​](#inherited-from-10 "Direct link to Inherited from")
335
+ #### Inherited from[​](#inherited-from-11 "Direct link to Inherited from")
318
336
 
319
337
  ```ts
320
338
  Omit.version
@@ -0,0 +1,38 @@
1
+ # Interface: SupervisorApiAdapterOptions
2
+
3
+ ## Properties[​](#properties "Direct link to Properties")
4
+
5
+ ### model[​](#model "Direct link to model")
6
+
7
+ ```ts
8
+ model: string;
9
+
10
+ ```
11
+
12
+ Model identifier to pass in the request body (e.g. "databricks-claude-sonnet-4").
13
+
14
+ ***
15
+
16
+ ### timeoutMs?[​](#timeoutms "Direct link to timeoutMs?")
17
+
18
+ ```ts
19
+ optional timeoutMs: number;
20
+
21
+ ```
22
+
23
+ Total wall-clock budget (ms) for a single `run()`. When the SSE stream runs longer than this — e.g. an upstream that stalls without closing — the adapter aborts it and emits a terminal `transport` error rather than hanging the request indefinitely.
24
+
25
+ This is a total-duration cap, not an idle cap. Defaults to 5 minutes, generous enough for multi-tool server-side orchestration.
26
+
27
+ ***
28
+
29
+ ### workspaceClient?[​](#workspaceclient "Direct link to workspaceClient?")
30
+
31
+ ```ts
32
+ optional workspaceClient: WorkspaceClientLike;
33
+
34
+ ```
35
+
36
+ A WorkspaceClient (or structural equivalent) used for host resolution and per-request authentication. When omitted, a `WorkspaceClient({})` is created internally using the default SDK credential chain (`DATABRICKS_HOST`, OAuth, PAT, etc.).
37
+
38
+ ⚠ The `workspaceClient` is captured at construction and reused across every request. Passing a per-request OBO (On-Behalf-Of) client here would silently leak the first request's identity into all subsequent requests served by this adapter instance. Use the default credential chain or pass a service-principal client. (CWE-664)
@@ -0,0 +1,12 @@
1
+ # Interface: SupervisorExtension
2
+
3
+ Shape of the value at `AgentInput.extensions[SUPERVISOR_EXTENSION_KEY]`. The agents plugin / `runAgent` build this from the tool index; advanced callers invoking `adapter.run(...)` directly populate it themselves.
4
+
5
+ ## Properties[​](#properties "Direct link to Properties")
6
+
7
+ ### hostedTools?[​](#hostedtools "Direct link to hostedTools?")
8
+
9
+ ```ts
10
+ optional hostedTools: SupervisorTool[];
11
+
12
+ ```
@@ -0,0 +1,67 @@
1
+ # Interface: WorkspaceClientLike
2
+
3
+ Structural shape of a Databricks SDK client used by [fromSupervisorApi](./docs/api/appkit/Function.fromSupervisorApi.md). Only what we need: `apiClient.request` for streaming and `config.ensureResolved` to materialise the host/credentials.
4
+
5
+ Exported because [SupervisorApiAdapterOptions.workspaceClient](./docs/api/appkit/Interface.SupervisorApiAdapterOptions.md#workspaceclient) (a public type) references it — callers passing their own client can name the shape they need to satisfy.
6
+
7
+ ## Extends[​](#extends "Direct link to Extends")
8
+
9
+ * `ApiClientLike`
10
+
11
+ ## Properties[​](#properties "Direct link to Properties")
12
+
13
+ ### apiClient[​](#apiclient "Direct link to apiClient")
14
+
15
+ ```ts
16
+ apiClient: {
17
+ request: Promise<unknown>;
18
+ };
19
+
20
+ ```
21
+
22
+ #### request()[​](#request "Direct link to request()")
23
+
24
+ ```ts
25
+ request(options: Record<string, unknown>, context?: unknown): Promise<unknown>;
26
+
27
+ ```
28
+
29
+ ##### Parameters[​](#parameters "Direct link to Parameters")
30
+
31
+ | Parameter | Type |
32
+ | ---------- | ----------------------------- |
33
+ | `options` | `Record`<`string`, `unknown`> |
34
+ | `context?` | `unknown` |
35
+
36
+ ##### Returns[​](#returns "Direct link to Returns")
37
+
38
+ `Promise`<`unknown`>
39
+
40
+ #### Inherited from[​](#inherited-from "Direct link to Inherited from")
41
+
42
+ ```ts
43
+ ApiClientLike.apiClient
44
+
45
+ ```
46
+
47
+ ***
48
+
49
+ ### config[​](#config "Direct link to config")
50
+
51
+ ```ts
52
+ config: {
53
+ ensureResolved: Promise<void>;
54
+ };
55
+
56
+ ```
57
+
58
+ #### ensureResolved()[​](#ensureresolved "Direct link to ensureResolved()")
59
+
60
+ ```ts
61
+ ensureResolved(): Promise<void>;
62
+
63
+ ```
64
+
65
+ ##### Returns[​](#returns-1 "Direct link to Returns")
66
+
67
+ `Promise`<`void`>
@@ -4,8 +4,9 @@
4
4
  type AgentTool =
5
5
  | FunctionTool
6
6
  | HostedTool
7
- | ToolkitEntry;
7
+ | ToolkitEntry
8
+ | HostedSupervisorTool;
8
9
 
9
10
  ```
10
11
 
11
- Any tool an agent can invoke: inline function tools (`tool()`), hosted MCP tools (`mcpServer()` / raw hosted), or toolkit references from plugins (`analytics().toolkit()`).
12
+ 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.*`).