feat(appkit): auto-discover code agents from server/agents/ - #533
Open
MarioCadenas wants to merge 6 commits into
Open
feat(appkit): auto-discover code agents from server/agents/#533MarioCadenas wants to merge 6 commits into
MarioCadenas wants to merge 6 commits into
Conversation
MarioCadenas
force-pushed
the
agents-discovery-dx
branch
from
August 13, 2026 14:31
8c9faed to
d956f58
Compare
Contributor
📦 Bundle size reportCompared against
|
| dist | raw | gzip |
|---|---|---|
| JS (runtime) | 905 KB (+13 KB) | 317 KB (+5.1 KB) |
| Type declarations | 344 KB (+4.3 KB) | 120 KB (+1.8 KB) |
| Source maps | 1.8 MB (+25 KB) | 596 KB (+9.5 KB) |
| Other | 11 KB | 3.7 KB |
| Total | 3.0 MB (+42 KB) | 1.0 MB (+16 KB) |
Per-entry composition (own code — deps external (as shipped))
| Entry | Initial (gz) | Lazy (gz) | Total (gz) | node_modules (min) | Own code (min) |
|---|---|---|---|---|---|
. |
88 KB | 2.5 KB | 91 KB | external | 288 KB |
./beta |
50 KB (+1.7 KB) | 457 B | 51 KB (+1.7 KB) | external | 147 KB (+4.3 KB) |
./testing |
17 KB | 0 B | 17 KB | external | 50 KB |
./tsdown |
520 B | 0 B | 520 B | external | 813 B |
./type-generator |
21 KB | 0 B | 21 KB | external | 61 KB |
Chunks:
| Entry | Chunk | Load | Size (gz) |
|---|---|---|---|
. |
index.js |
initial | 84 KB |
. |
utils.js |
initial | 4.0 KB |
. |
remote-tunnel-manager.js |
lazy | 2.5 KB |
./beta |
beta.js |
initial | 34 KB |
./beta |
stream-manager.js |
initial | 5.8 KB |
./beta |
wide-event-emitter.js |
initial | 3.2 KB |
./beta |
databricks.js |
initial | 3.0 KB |
./beta |
configuration.js |
initial | 2.1 KB |
./beta |
service-context.js |
initial | 1.3 KB |
./beta |
client.js |
initial | 434 B |
./beta |
client-options.js |
initial | 220 B |
./beta |
supervisor-api.js |
lazy | 192 B |
./beta |
databricks.js |
lazy | 142 B |
./beta |
index.js |
lazy | 123 B |
./testing |
index.js |
initial | 17 KB |
./tsdown |
index.js |
initial | 520 B |
./type-generator |
index.js |
initial | 21 KB |
@databricks/appkit-ui
npm tarball (packed): 348 KB (+2 B) — gzipped download (dist + bin; excludes release-only docs/NOTICE).
| dist | raw | gzip |
|---|---|---|
| JS (runtime) | 394 KB | 132 KB |
| Type declarations | 228 KB | 83 KB |
| Source maps | 764 KB | 252 KB |
| CSS | 16 KB | 3.2 KB |
| Total | 1.4 MB | 471 KB |
Per-entry composition (consumer bundle — deps bundled, peerDeps external)
| Entry | Initial (gz) | Lazy (gz) | Total (gz) | node_modules (min) | Own code (min) |
|---|---|---|---|---|---|
./js |
5.3 KB | 49 KB | 55 KB | 208 KB | 14 KB |
./js/beta |
20 B | 0 B | 20 B | 0 B | 0 B |
./react |
432 KB | 49 KB | 481 KB | 1.3 MB | 177 KB |
./react/beta |
1.0 KB | 0 B | 1.0 KB | 0 B | 1.9 KB |
Chunks:
| Entry | Chunk | Load | Size (gz) |
|---|---|---|---|
./js |
index.js |
initial | 5.2 KB |
./js |
chunk |
initial | 120 B |
./js |
apache-arrow |
lazy | 49 KB |
./js/beta |
beta.js |
initial | 20 B |
./react |
index.js |
initial | 430 KB |
./react |
tslib |
initial | 2.1 KB |
./react |
apache-arrow |
lazy | 49 KB |
./react/beta |
beta.js |
initial | 1.0 KB |
Contributor
🤖 AppKit PR bot🔬 Run evalsStart an eval for this PR from the evals-monitor app: Go to Evals Monitor → 📦 Try this PR's app templateScaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh run download 32393214595 -R databricks/appkit -n appkit-template-0.63.0-pr.440c3a5-agents-discovery-dx-533 -D appkit-pr-533 \
&& unzip -o "appkit-pr-533/appkit-template-0.63.0-pr.440c3a5-agents-discovery-dx-533.zip" -d "appkit-pr-533" \
&& databricks apps init --template "appkit-pr-533"The template pins |
MarioCadenas
force-pushed
the
agents-discovery-dx
branch
2 times, most recently
from
August 18, 2026 09:04
45e7284 to
55e3bcd
Compare
MarioCadenas
marked this pull request as ready for review
August 18, 2026 15:34
MarioCadenas
force-pushed
the
agents-discovery-dx
branch
from
August 20, 2026 12:07
643b7f9 to
4b886ca
Compare
…er/agents
Every agent is a folder under server/agents/<id>/ holding agent.md (markdown)
or agent.ts (code); the folder name is the id.
- Code loader scans <id>/agent.{ts,tsx,js,mjs}, built-first: a relative dir
resolves dist/<name>|build/<name> before source, an absolute dir is verbatim,
so a bundled server never imports .ts under plain Node.
- Markdown loader skips folders without agent.md so code + asset dirs coexist;
drop the RESERVED_DIRS list.
- One `dir` knob (default server/agents) feeds both loaders; codeAgentsDir
retired. config/agents is read as a deprecated fallback (per-agent merge, new
location wins, one-time warning); cross-location sub-agent refs resolve.
- Cross-kind sub-agent references resolve by folder id.
- Migrate template, dev-playground, docs, and tests to the folder layout; add
fallback / built-first / cross-dir test coverage.
Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
Follow-up to the review + inconsistency fan-out: - findEntryFile now rethrows non-ENOENT/ENOTDIR errors (an unreadable agent folder no longer silently vanishes in prod). - Clearer discovered-vs-markdown collision message (covers the cross-root config/agents fallback case, not just one folder). - Template tsdown: scope clean:true to the agents case so a non-agents scaffold's build config is unchanged. - Docs: fix DATABRICKS_SERVING_ENDPOINT_NAME, the auto-inherit default (off for both), cycle-rejection scope, /api/agents/approve path, defaultAgent precedence, dir:false wording, stale-dist note, and add the agents/generationParams frontmatter keys + toolCallTimeoutMs limit. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
Ships the server build wiring from the package so a scaffolded app's
tsdown.server.config.ts is a one-liner instead of hand-maintained config:
import { appkitServerConfig } from '@databricks/appkit/tsdown';
export default appkitServerConfig();
- appkitServerConfig(overrides?, opts?) auto-detects server/agents/<id>/agent.ts
and adds the entry glob + clean only when code agents exist.
- Object overrides merge with intent (entry unioned so the agent glob can't be
clobbered, external composed, other keys win); a function override receives
the computed base for full control.
- Dependency-free (node: builtins only) so it stays lean at build time.
- New ./tsdown export subpath (attw + publint clean); template drops its
{{if .plugins.agents}} conditional.
Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
Markdown agents need no build change; code agents require the server build to emit them (dev via tsx hides this — only a bundled build breaks). Points at the appkitServerConfig() preset as the one-line fix, notes the manual entry-glob alternative, and the startup warning that catches a forgotten build change. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
…ion .ts-only From the /simplify pass: - Extract agentDirNames() so both loaders share one folder-selection policy (dir + symlink) instead of duplicating the subtle filter + comment. - Code-agent source detection is .ts-only (resolveCodeAgentsDir source exts + hasCodeAgentSources), matching the build entry glob — an agent.tsx would otherwise load in dev but never be emitted for a prod bundle. Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
MarioCadenas
force-pushed
the
agents-discovery-dx
branch
from
August 20, 2026 16:24
4b886ca to
c3f6872
Compare
…r option)
Remove the agents({ dir }) config option and make server/agents a fixed
convention. This deletes the build<->runtime dir disconnect at the root:
the tsdown build glob and the runtime scan can no longer disagree about
where agents live, since the path is now a single constant.
- resolveCodeAgentsDir drops the override param; always built-first from
server/agents (dist/agents | build/agents, then source .ts).
- config/agents/ is still read as the deprecated markdown fallback and
still emits the one-time deprecation warning.
- dir:false (disable discovery) is gone too; a map-only app works via an
absent server/agents folder.
Tests point discovery at fixtures via chdir + a symlinked server/agents
instead of an absolute dir.
Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Every agent is now a folder under
server/agents/<id>/, discovered at startup —agent.mdfor a markdown agent,agent.ts(export default createAgent(...)) for a code agent. The folder name is the id, so the plugin call collapses toagents()with no map and no imports, and neither form restates its id.Markdown and code agents live side by side under the same root; a markdown
agent.mdand codeagent.tsare just two entry-file kinds.How
server/agentsis a fixed convention, not a config knob. There is nodiroption to relocate the root — the build glob and the runtime scan reference the same constant, so they can't disagree about where agents live. (Discovery has no disable toggle either; a map-only app simply has noserver/agents/folder.)import()s a.ts(plain Node can't). Dev (tsx) loadsserver/agents/<id>/agent.ts; a build loads the compileddist/agents/<id>/agent.js(orbuild/agents).createAgentstamps a non-enumerableSymbol.for("appkit.agent"); the loader keeps branded exports and skips helpers/chunks. A folder is an agent iff it holdsagent.mdoragent.ts; one holding both errors at boot (one kind per id).server/agents/*/agent.tsas entries and the compileddist/agents/*/agent.jsexist for the scan. That wiring now ships in the package (below), not hand-copied into every scaffold.New:
@databricks/appkit/tsdownbuild presetA scaffolded app's
tsdown.server.config.tsis a one-liner:appkitServerConfig()auto-detectsserver/agents/and adds the entry glob +cleanonly when code agents exist; object overrides merge with intent (entryunioned so the glob can't be dropped,externalcomposed), and a function form gives full control. The build wiring lives in the package, so it reaches existing apps on upgrade instead of being maintained per-scaffold.Backward compatibility
config/agents/is read as a deprecated fallback — merged per-agent withserver/agents(new location wins on an id clash), with a one-time deprecation warning. Cross-location sub-agent refs resolve one direction (a parent moved toserver/agentscan reference a child still inconfig/agents).agents({ agents: { ... } })map still works, one-time deprecation warning; discovery wins on an id clash.createAgent({ name })still honored (the registry key wins).Also in this PR
server/agents/<id>/folders) and the template (helper/agent.ts+planner/agent.md, tsdown one-liner).agentsplugin page for the folder model and adds an "Adding agents to an existing app" section (markdown = no build change; code = adopt the preset).dirconfig option entirely —server/agentsis a fixed convention (this also retires the never-shippedcodeAgentsDirknob).config/agentsremains a read-only deprecated fallback.Verification
pnpm -r typecheckclean ·oxlint+oxfmtclean · appkit 3246 tests pass ·pnpm build+pnpm docs:buildsucceed.databricks-appkit-0.62.0.tgz) in a fresh app installed from the.tgz:dist/agents/<id>/agent.jsexactly where the runtime probes;tsx, source.ts) and prod (node, compiled.js— no TS loader) both discover the code agent, the markdown agent, and theconfig/agentsfallback (deprecation warning fires);diris absent from the publishedtypes.d.ts;./tsdown+./betaexports resolve.Notes
agentsis a beta plugin (@databricks/appkit/beta) — the config-surface changes ride the beta stability tier.