Skip to content

[PoC] feat: agent plugin#217

Draft
MarioCadenas wants to merge 2 commits intomainfrom
agent-plugin
Draft

[PoC] feat: agent plugin#217
MarioCadenas wants to merge 2 commits intomainfrom
agent-plugin

Conversation

@MarioCadenas
Copy link
Collaborator

@MarioCadenas MarioCadenas commented Mar 26, 2026

Summary

Add a framework-agnostic AI agent plugin to AppKit with auto-tool-discovery from existing plugins, a Databricks Model Serving adapter, three framework adapters (Databricks, Vercel AI, LangChain), and a createAgent() convenience API.

Main changes

Agent plugin core (packages/appkit/src/plugins/agent/):
New deferred-phase plugin that scans all registered plugins for ToolProvider implementations, collects their tools with pluginName.toolName namespacing, and exposes 7 HTTP routes (chat via SSE, cancel, threads CRUD, tools list, agents list). Manages in-memory threads per userId and supports multiple named agents with a configurable default. The chat handler builds an executeTool closure over the request for user-context-aware tool execution.

DatabricksAdapter (packages/appkit/src/agents/databricks.ts):
Adapter that talks directly to Databricks Model Serving /invocations endpoints using raw fetch(). Authenticates per-request via an authenticate() callback (no stale tokens), sanitizes tool names (dots to double-underscores) for the Databricks API, and handles both structured tool_calls responses and text-based tool call fallback parsing (Llama JSON format and Python-style). Includes a fromServingEndpoint() async factory and a createDatabricksModel() helper for Vercel AI SDK integration.

ToolProvider on existing plugins (packages/appkit/src/plugins/{analytics,files,genie,lakebase}/):
All four existing plugins now implement the ToolProvider interface with getAgentTools() and executeAgentTool(). Analytics exposes query (1 tool), Files generates per-volume tools (6 per volume), Genie generates per-space tools (2 per space), and Lakebase exposes query (1 tool).

createAgent() wrapper (packages/appkit/src/core/create-agent.ts):
Higher-level API that wraps createApp with server() and agent() pre-configured. Supports single-agent shorthand (adapter) or multi-agent (agents record), flat server config (port, host), and returns an AgentHandle with registerAgent, getTools, getThreads, and plugins namespace.

Supporting infrastructure

  • packages/shared/src/agent.ts — Core types: ToolProvider, AgentToolDefinition, AgentAdapter, AgentEvent (7-event SSE protocol), Message, Thread, ThreadStore.
  • packages/appkit/src/agents/vercel-ai.ts — Adapter bridging Vercel AI SDK's streamText().fullStream to AgentEvent.
  • packages/appkit/src/agents/langchain.ts — Adapter bridging LangChain's streamEvents v2 to AgentEvent, with JSON Schema to Zod converter.
  • packages/appkit/src/plugins/agent/thread-store.tsInMemoryThreadStore implementation (Map-based, userId-scoped).
  • apps/agent-app/ — Standalone agent app project using createAgent(), with chat UI, markdown rendering, event stream panel, and theme selector.
  • apps/dev-playground/client/src/routes/agent.route.tsx — Agent chat page in dev-playground with inline autocomplete and event stream sidebar.

Examples

2 ways of building agents

in app:

import {
  agent,
  analytics,
  createApp,
  files,
  genie,
  server,
} from "@databricks/appkit";

createApp({
  plugins: [
    server(),
    analytics({}),
    genie({
      spaces: { demo: process.env.DATABRICKS_GENIE_SPACE_ID ?? "placeholder" },
    }),
    files(),
    agent({
      agents: {
        assistant: DatabricksAdapter.fromServingEndpoint({
          workspaceClient: wsClient,
          endpointName,
          systemPrompt:
            "You are a helpful data assistant. Use the available tools to query data and help users with their analysis.",
        }),
        autocomplete: DatabricksAdapter.fromServingEndpoint({
          workspaceClient: wsClient,
          endpointName: "databricks-gemini-3-1-flash-lite",
          systemPrompt: [
            "You are an autocomplete engine.",
            "The user will give you the beginning of a sentence or paragraph.",
            "Continue the text naturally, as if you are the same author.",
            "Do NOT repeat the input. Only output the continuation.",
            "Do NOT use tools. Do NOT explain. Just write the next words.",
          ].join(" "),
          maxSteps: 1,
        }),
      },
      defaultAgent: "assistant",
    }),
  ],
});
Screen.Recording.2026-03-26.at.18.17.40.mov

dedicated agent:

import { analytics, createAgent, files } from "@databricks/appkit";
import { DatabricksAdapter } from "@databricks/appkit/agents/databricks";

createAgent({
  plugins: [analytics(), files()],
  adapter: DatabricksAdapter.fromServingEndpoint({
    workspaceClient: new WorkspaceClient({}),
    endpointName,
    systemPrompt:
      "You are a helpful data assistant. Use the available tools to query data and help users with their analysis.",
  }),
  port: 8003,
})
Screen.Recording.2026-03-26.at.18.20.03.mov

@MarioCadenas MarioCadenas changed the title feat: agent plugin [PoC] feat: agent plugin Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant