@useatlas/plugin-sdk
Advanced tools
+21
| MIT License | ||
| Copyright (c) 2026 Matthew Sywulak | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
+15
-1
| /** | ||
| * Re-exports from the Vercel AI SDK for plugin authors. | ||
| * | ||
| * The `ai` package is a peer dependency of `@useatlas/plugin-sdk`. | ||
| * The `ai` package is an optional peer dependency of `@useatlas/plugin-sdk`. | ||
| * Install it when your plugin defines custom tools or actions. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { tool } from "@useatlas/plugin-sdk/ai"; | ||
| * import { z } from "zod"; | ||
| * | ||
| * const myTool = tool({ | ||
| * description: "Look up inventory by SKU", | ||
| * parameters: z.object({ sku: z.string() }), | ||
| * execute: async ({ sku }) => ({ stock: 42 }), | ||
| * }); | ||
| * ``` | ||
| */ | ||
| export { tool, jsonSchema } from "ai"; | ||
| export type { ToolSet, Tool } from "ai"; |
+12
-1
| /** | ||
| * Re-exports from Hono for plugin authors. | ||
| * | ||
| * The `hono` package is a peer dependency of `@useatlas/plugin-sdk`. | ||
| * The `hono` package is an optional peer dependency of `@useatlas/plugin-sdk`. | ||
| * Install it when your plugin mounts HTTP routes (interaction plugins). | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { Hono } from "@useatlas/plugin-sdk/hono"; | ||
| * import type { Context } from "@useatlas/plugin-sdk/hono"; | ||
| * | ||
| * function mountRoutes(app: Hono) { | ||
| * app.get("/api/my-plugin/health", (c: Context) => c.json({ ok: true })); | ||
| * } | ||
| * ``` | ||
| */ | ||
| export { Hono } from "hono"; | ||
| export type { Context, MiddlewareHandler } from "hono"; |
+7
-1
| /** | ||
| * @useatlas/plugin-sdk — Public API for authoring Atlas plugins. | ||
| * | ||
| * Optional peer dependency re-exports are available via sub-paths: | ||
| * - `@useatlas/plugin-sdk/ai` — `tool`, `jsonSchema`, `ToolSet`, `Tool` | ||
| * - `@useatlas/plugin-sdk/hono` — `Hono`, `Context`, `MiddlewareHandler` | ||
| */ | ||
| export type { PluginQueryResult, PluginDBConnection, QueryValidationResult, PluginDBType, ParserDialect, PluginType, PluginStatus, PluginHealthResult, PluginLogger, AtlasPluginContext, PluginHookEntry, QueryHookContext, QueryHookMutation, AfterQueryHookContext, ExploreHookContext, ExploreHookMutation, AfterExploreHookContext, RequestHookContext, ResponseHookContext, PluginHooks, PluginFieldDefinition, PluginTableDefinition, AtlasPluginBase, PluginEntity, EntityProvider, AtlasDatasourcePlugin, AtlasContextPlugin, AtlasInteractionPlugin, PluginAction, AtlasActionPlugin, PluginExecResult, PluginExploreBackend, AtlasSandboxPlugin, ActionApprovalMode, AtlasPlugin, $InferServerPlugin, } from "./types"; | ||
| export type { PluginQueryResult, PluginDBConnection, QueryValidationResult, PluginDBType, ParserDialect, PluginType, PluginStatus, PluginHealthResult, PluginLogger, AtlasPluginContext, PluginHookEntry, QueryHookContext, QueryHookMutation, AfterQueryHookContext, ExploreHookContext, ExploreHookMutation, AfterExploreHookContext, ToolCallSessionContext, ToolCallHookContext, AfterToolCallHookContext, ToolCallArgsMutation, ToolCallResultMutation, RequestHookContext, ResponseHookContext, PluginHooks, PluginFieldDefinition, PluginTableDefinition, AtlasPluginBase, PluginEntity, EntityProvider, AtlasDatasourcePlugin, AtlasContextPlugin, AtlasInteractionPlugin, PluginAction, AtlasActionPlugin, PluginExecResult, PluginExploreBackend, AtlasSandboxPlugin, ActionApprovalMode, ConfigSchemaField, AtlasPlugin, $InferServerPlugin, } from "./types"; | ||
| export { SANDBOX_DEFAULT_PRIORITY } from "./types"; | ||
| export { definePlugin, createPlugin, isDatasourcePlugin, isContextPlugin, isInteractionPlugin, isActionPlugin, isSandboxPlugin, } from "./helpers"; | ||
| export type { CreatePluginOptions } from "./helpers"; | ||
| export type { ToolSet, Tool } from "./ai"; | ||
| export type { Context, MiddlewareHandler } from "./hono"; |
@@ -16,2 +16,3 @@ /** | ||
| */ | ||
| import type { ToolSet } from "ai"; | ||
| import type { AtlasPluginContext, PluginDBConnection, PluginExploreBackend, PluginExecResult, PluginLogger, PluginQueryResult } from "./types"; | ||
@@ -92,3 +93,3 @@ export interface CapturedLog { | ||
| description: string; | ||
| tool: unknown; | ||
| tool: ToolSet[string]; | ||
| } | ||
@@ -95,0 +96,0 @@ export interface MockContextResult { |
+110
-11
@@ -35,3 +35,3 @@ /** | ||
| /** Known database types, plus an escape hatch for custom drivers. */ | ||
| export type PluginDBType = "postgres" | "mysql" | "clickhouse" | "snowflake" | "duckdb" | (string & {}); | ||
| export type PluginDBType = "postgres" | "mysql" | "clickhouse" | "snowflake" | "duckdb" | "bigquery" | (string & {}); | ||
| /** | ||
@@ -112,2 +112,8 @@ * Known node-sql-parser dialect strings, plus an escape hatch for future dialects. | ||
| connectionId?: string; | ||
| /** | ||
| * Mutable metadata bag. Hooks can attach arbitrary key-value pairs | ||
| * (e.g. `{ estimatedCostUsd, bytesScanned }`) that the caller | ||
| * merges into the tool result so the agent can reference them. | ||
| */ | ||
| metadata?: Record<string, unknown>; | ||
| } | ||
@@ -133,2 +139,38 @@ export interface AfterQueryHookContext extends QueryHookContext { | ||
| } | ||
| /** Session context available to tool call hooks. */ | ||
| export interface ToolCallSessionContext { | ||
| userId?: string; | ||
| conversationId?: string; | ||
| /** 1-based count of tool invocations in the current agent run (across all tools). */ | ||
| toolCallCount: number; | ||
| } | ||
| /** Context passed to beforeToolCall / afterToolCall hooks. */ | ||
| export interface ToolCallHookContext { | ||
| toolName: string; | ||
| args: Record<string, unknown>; | ||
| context: ToolCallSessionContext; | ||
| } | ||
| export interface AfterToolCallHookContext extends ToolCallHookContext { | ||
| /** | ||
| * The tool's return value. Typed as `unknown` because different tools | ||
| * return different shapes. Narrow based on `toolName`: | ||
| * | ||
| * ```ts | ||
| * if (ctx.toolName === "executeSQL") { | ||
| * const qr = ctx.result as { columns: string[]; rows: Record<string, unknown>[] }; | ||
| * } | ||
| * ``` | ||
| */ | ||
| result: unknown; | ||
| /** Wall-clock duration of the tool execution in milliseconds. */ | ||
| durationMs: number; | ||
| } | ||
| /** Mutation return type for beforeToolCall hooks. Return to rewrite the args. */ | ||
| export interface ToolCallArgsMutation { | ||
| args: Record<string, unknown>; | ||
| } | ||
| /** Mutation return type for afterToolCall hooks. Return to rewrite the result. */ | ||
| export interface ToolCallResultMutation { | ||
| result: unknown; | ||
| } | ||
| /** Context passed to onRequest / onResponse HTTP hooks. */ | ||
@@ -149,5 +191,6 @@ export interface RequestHookContext { | ||
| * | ||
| * `beforeQuery` and `beforeExplore` are mutable — handlers can return a | ||
| * mutation object to rewrite the SQL/command, or throw to reject the operation. | ||
| * All other hooks are observation-only (void return). | ||
| * `beforeQuery`, `beforeExplore`, `beforeToolCall`, and `afterToolCall` are | ||
| * mutable — handlers can return a mutation object to rewrite the | ||
| * SQL/command/args/result, or throw to reject the operation. All other hooks | ||
| * are observation-only (void return). | ||
| */ | ||
@@ -163,2 +206,6 @@ export interface PluginHooks { | ||
| afterExplore?: PluginHookEntry<AfterExploreHookContext>[]; | ||
| /** Fires before each tool call. Return `{ args }` to rewrite args, throw to reject. */ | ||
| beforeToolCall?: PluginHookEntry<ToolCallHookContext, ToolCallArgsMutation>[]; | ||
| /** Fires after each tool call. Return `{ result }` to rewrite the result, throw to reject. */ | ||
| afterToolCall?: PluginHookEntry<AfterToolCallHookContext, ToolCallResultMutation>[]; | ||
| /** HTTP-level: fires before routing a request. */ | ||
@@ -182,2 +229,46 @@ onRequest?: PluginHookEntry<RequestHookContext>[]; | ||
| } | ||
| /** | ||
| * Describes a single config field for admin UI form generation. | ||
| * Plugins return an array of these from `getConfigSchema()`. | ||
| */ | ||
| export interface ConfigSchemaField { | ||
| /** Field key in the config object. */ | ||
| key: string; | ||
| /** Field type for form generation. */ | ||
| type: "string" | "number" | "boolean" | "select"; | ||
| /** Human-readable label. Falls back to `key` in the UI. */ | ||
| label?: string; | ||
| /** Help text shown below the input. */ | ||
| description?: string; | ||
| /** Whether the field is required. */ | ||
| required?: boolean; | ||
| /** When true, the value is masked in the UI (e.g. API keys, secrets). */ | ||
| secret?: boolean; | ||
| /** Valid options for "select" type fields. */ | ||
| options?: string[]; | ||
| /** Default value. */ | ||
| default?: unknown; | ||
| } | ||
| /** A single cached query result entry. */ | ||
| export interface PluginCacheEntry { | ||
| columns: string[]; | ||
| rows: Record<string, unknown>[]; | ||
| cachedAt: number; | ||
| ttl: number; | ||
| } | ||
| /** Cache backend interface for query result caching. */ | ||
| export interface PluginCacheBackend { | ||
| get(key: string): PluginCacheEntry | null; | ||
| set(key: string, entry: PluginCacheEntry): void; | ||
| delete(key: string): boolean; | ||
| /** Flush all entries. */ | ||
| flush(): void; | ||
| stats(): { | ||
| hits: number; | ||
| misses: number; | ||
| entryCount: number; | ||
| maxSize: number; | ||
| ttl: number; | ||
| }; | ||
| } | ||
| export interface AtlasPluginBase<TConfig = undefined> { | ||
@@ -195,2 +286,8 @@ /** Unique plugin identifier (e.g. "salesforce-datasource", "slack-interaction"). */ | ||
| /** | ||
| * Return a serializable description of the plugin's config schema. | ||
| * Used by the admin UI to generate dynamic config forms. Optional — | ||
| * plugins without this method show config as read-only JSON. | ||
| */ | ||
| getConfigSchema?(): ConfigSchemaField[]; | ||
| /** | ||
| * Called once during server boot with the full Atlas context. | ||
@@ -218,2 +315,7 @@ * Throw to signal initialization failure. | ||
| schema?: Record<string, PluginTableDefinition>; | ||
| /** | ||
| * Optional external cache backend (e.g. Redis) for query result caching. | ||
| * When provided, replaces the default in-memory LRU cache. | ||
| */ | ||
| cacheBackend?: PluginCacheBackend; | ||
| } | ||
@@ -248,5 +350,8 @@ /** | ||
| * | ||
| * Can be synchronous or asynchronous — async validators are useful when validation | ||
| * requires an external call (e.g. schema service, permission check). | ||
| * | ||
| * Queries rewritten by hooks are re-validated through this function before execution. | ||
| */ | ||
| validate?(query: string): QueryValidationResult; | ||
| validate?(query: string): QueryValidationResult | Promise<QueryValidationResult>; | ||
| /** | ||
@@ -263,5 +368,2 @@ * node-sql-parser dialect string for SQL validation. When not provided, | ||
| * the entire SQL validation pipeline). | ||
| * | ||
| * **Note:** Wired into the core pipeline in #15. Until then, this field | ||
| * is validated at registration time but not yet consumed at query time. | ||
| */ | ||
@@ -277,5 +379,2 @@ parserDialect?: ParserDialect; | ||
| * the entire SQL validation pipeline). | ||
| * | ||
| * **Note:** Wired into the core pipeline in #15. Until then, this field | ||
| * is validated at registration time but not yet consumed at query time. | ||
| */ | ||
@@ -282,0 +381,0 @@ forbiddenPatterns?: RegExp[]; |
+12
-4
| { | ||
| "name": "@useatlas/plugin-sdk", | ||
| "version": "0.0.6", | ||
| "version": "0.0.7", | ||
| "description": "Type definitions and helpers for authoring Atlas plugins", | ||
| "type": "module", | ||
| "scripts": { | ||
| "build": "rm -rf dist && bun build src/index.ts src/types.ts src/helpers.ts src/ai.ts src/hono.ts src/testing.ts --outdir dist --target node --packages external && npx tsc -p tsconfig.build.json", | ||
| "build": "rm -rf dist && bun build src/index.ts src/types.ts src/helpers.ts src/ai.ts src/hono.ts src/testing.ts --outdir dist --target node --packages external && bun x tsc -p tsconfig.build.json", | ||
| "prepublishOnly": "bun run build", | ||
@@ -69,7 +69,15 @@ "test": "bun test src/__tests__/types.test.ts && bun test src/__tests__/infer.test.ts && bun test src/__tests__/testing.test.ts" | ||
| }, | ||
| "peerDependenciesMeta": { | ||
| "ai": { | ||
| "optional": true | ||
| }, | ||
| "hono": { | ||
| "optional": true | ||
| } | ||
| }, | ||
| "devDependencies": { | ||
| "ai": "^6.0.97", | ||
| "hono": "^4.12.3", | ||
| "ai": "^6.0.141", | ||
| "hono": "^4.12.9", | ||
| "zod": "^4.3.6" | ||
| } | ||
| } |
62049
11.18%15
7.14%1192
13.09%