Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@
"**/*.css",
"packages/appkit/src/plugins/vector-search/**",
"packages/appkit/src/plugin/index.ts",
"packages/appkit/src/plugin/to-plugin.ts",
"packages/appkit/src/plugins/agents/index.ts",
"template/**",
"tools/**",
"docs/**",
".github/scripts/**",
"packages/appkit/src/core/agent/index.ts",
"packages/appkit/src/core/agent/tools/index.ts",
"packages/appkit/src/core/agent/from-plugin.ts",
"packages/appkit/src/core/agent/load-agents.ts",
"packages/appkit/src/connectors/mcp/index.ts",
"packages/appkit/src/plugin/to-plugin.ts"
"template/**",
"tools/**",
"docs/**",
".github/scripts/**"
],
"ignoreDependencies": ["json-schema-to-typescript"],
"ignoreBinaries": ["tarball"]
Expand Down
4 changes: 4 additions & 0 deletions packages/appkit/src/beta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ export type {
AgentDefinition,
AgentsPluginConfig,
AgentTool,
AgentTools,
AutoInheritToolsConfig,
BaseSystemPromptOption,
FromPluginMarker,
PromptContext,
RegisteredAgent,
ResolvedToolEntry,
Expand All @@ -62,6 +64,8 @@ export type {
} from "./plugins/agents";
export {
agentIdFromMarkdownPath,
fromPlugin,
isFromPluginMarker,
isToolkitEntry,
loadAgentFromFile,
loadAgentsFromDir,
Expand Down
2 changes: 1 addition & 1 deletion packages/appkit/src/connectors/mcp/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Input shape consumed by {@link AppKitMcpClient.connect}. Produced by the
* agents plugin from user-facing `HostedTool` declarations (see
* `plugins/agents/tools/hosted-tools.ts`) and accepted directly by the
* `core/agent/tools/hosted-tools.ts`) and accepted directly by the
* connector to keep its surface free of agent-layer concepts.
*/
export interface McpEndpointConfig {
Expand Down
97 changes: 97 additions & 0 deletions packages/appkit/src/core/agent/from-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type { NamedPluginFactory } from "../../plugin/to-plugin";
import type { ToolkitOptions } from "./types";

/**
* Symbol brand for the `fromPlugin` marker. Using a globally-interned symbol
* (`Symbol.for`) keeps the brand stable across module boundaries / bundle
* duplicates so `isFromPluginMarker` stays reliable.
*/
export const FROM_PLUGIN_MARKER = Symbol.for(
"@databricks/appkit.fromPluginMarker",
);

/**
* A lazy reference to a plugin's tools, produced by {@link fromPlugin} and
* resolved to concrete `ToolkitEntry`s at `AgentsPlugin.setup()` time.
*
* The marker is spread under a unique symbol key so multiple calls to
* `fromPlugin` (even for the same plugin) coexist in an `AgentDefinition.tools`
* record without colliding.
*/
export interface FromPluginMarker {
readonly [FROM_PLUGIN_MARKER]: true;
readonly pluginName: string;
readonly opts: ToolkitOptions | undefined;
}

/**
* Record shape returned by {@link fromPlugin} — a single symbol-keyed entry
* suitable for spreading into `AgentDefinition.tools`.
*/
export type FromPluginSpread = { readonly [key: symbol]: FromPluginMarker };

/**
* Reference a plugin's tools inside an `AgentDefinition.tools` record without
* naming the plugin instance. The returned spread-friendly object carries a
* symbol-keyed marker that the agents plugin resolves against registered
* `ToolProvider`s at setup time.
*
* The factory argument must come from `toPlugin` (or any function that
* carries a `pluginName` field). `fromPlugin` reads `factory.pluginName`
* synchronously — it does not construct an instance.
*
* If the referenced plugin is also registered in `createApp({ plugins })`, the
* same runtime instance is used for dispatch. If the plugin is missing,
* `AgentsPlugin.setup()` throws with a clear `Available: …` listing.
*
* @example
* ```ts
* import { analytics, createAgent, files, fromPlugin, tool } from "@databricks/appkit";
*
* const support = createAgent({
* instructions: "You help customers.",
* tools: {
* ...fromPlugin(analytics),
* ...fromPlugin(files, { only: ["uploads.read"] }),
* get_weather: tool({ ... }),
* },
* });
* ```
*
* @param factory A plugin factory produced by `toPlugin`. Must expose a
* `pluginName` field.
* @param opts Optional toolkit scoping — `prefix`, `only`, `except`, `rename`.
* Same shape as the `.toolkit()` method.
*/
export function fromPlugin<F extends NamedPluginFactory>(
factory: F,
opts?: ToolkitOptions,
): FromPluginSpread {
if (
!factory ||
typeof factory.pluginName !== "string" ||
!factory.pluginName
) {
throw new Error(
"fromPlugin(): factory is missing pluginName. Pass a factory created by toPlugin().",
);
}
const pluginName = factory.pluginName;
const marker: FromPluginMarker = {
[FROM_PLUGIN_MARKER]: true,
pluginName,
opts,
};
return { [Symbol(`fromPlugin:${pluginName}`)]: marker };
}

/**
* Type guard for {@link FromPluginMarker}.
*/
export function isFromPluginMarker(value: unknown): value is FromPluginMarker {
return (
typeof value === "object" &&
value !== null &&
(value as Record<symbol, unknown>)[FROM_PLUGIN_MARKER] === true
);
}
64 changes: 64 additions & 0 deletions packages/appkit/src/core/agent/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Agent runtime primitives. All framework-level agent types, tool helpers,
* and the standalone runner live here. The HTTP-facing `agents()` plugin in
* `plugins/agents/` consumes these but does not own them — peer plugins
* (analytics, files, genie, lakebase) can depend on this module without
* reaching across the sibling boundary.
*/
export { buildToolkitEntries } from "./build-toolkit";
export { consumeAdapterStream } from "./consume-adapter-stream";
export { createAgent } from "./create-agent";
export {
FROM_PLUGIN_MARKER,
type FromPluginMarker,
type FromPluginSpread,
fromPlugin,
isFromPluginMarker,
} from "./from-plugin";
export {
agentIdFromMarkdownPath,
type LoadContext,
type LoadResult,
loadAgentFromFile,
loadAgentsFromDir,
parseFrontmatter,
} from "./load-agents";
export { normalizeToolResult } from "./normalize-result";
export {
type RunAgentInput,
type RunAgentResult,
runAgent,
} from "./run-agent";
export { buildBaseSystemPrompt, composeSystemPrompt } from "./system-prompt";
export { dispatchToolCall } from "./tool-dispatch";
export { resolveToolkitFromProvider } from "./toolkit-resolver";
export {
defineTool,
executeFromRegistry,
type FunctionTool,
functionToolToDefinition,
type HostedTool,
isFunctionTool,
isHostedTool,
mcpServer,
resolveHostedTools,
type ToolConfig,
type ToolEntry,
type ToolRegistry,
tool,
toolsFromRegistry,
} from "./tools";
export {
type AgentDefinition,
type AgentsPluginConfig,
type AgentTool,
type AgentTools,
type AutoInheritToolsConfig,
type BaseSystemPromptOption,
isToolkitEntry,
type PromptContext,
type RegisteredAgent,
type ResolvedToolEntry,
type ToolkitEntry,
type ToolkitOptions,
} from "./types";
Loading