Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
bbbbbc9
feat(agent builder): poc chat creates skills
SiddharthMantri Apr 27, 2026
d21496c
Add canvas view
zacharyparikh May 11, 2026
bd2cbab
Merge remote-tracking branch 'upstream/main' into ab/chat-customizati…
zacharyparikh May 11, 2026
fb52c2c
Only allow creation of latest draft version
zacharyparikh May 12, 2026
7d48991
add attachment header icon and badges
zacharyparikh May 12, 2026
cc40777
Add header subtitle
zacharyparikh May 12, 2026
7cd57cb
redesign skill draft attachment body
zacharyparikh May 12, 2026
6a8b7c5
adjust action buttons designs
zacharyparikh May 12, 2026
33f68e3
Show edit in managment button
zacharyparikh May 12, 2026
793d386
Add native href props to attachment action buttons
zacharyparikh May 12, 2026
e14fa65
Merge remote-tracking branch 'upstream/main' into ab/chat-customizati…
zacharyparikh May 12, 2026
6a4ec89
Adjust badge spacing
zacharyparikh May 12, 2026
5bd3ef9
Correct badge color
zacharyparikh May 12, 2026
fc5c670
show canvas view attachment header for outdated drafts
zacharyparikh May 13, 2026
fc55f5d
adjust hasFiles guard
zacharyparikh May 13, 2026
0f4ab84
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine May 13, 2026
36d540b
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine May 13, 2026
f87bda9
fix types
zacharyparikh May 13, 2026
5962a5c
Merge branch 'main' into ab/chat-customization-skill-poc
elasticmachine May 14, 2026
3f5c8da
Replace badge with proper close button
ryankeairns May 14, 2026
417ffb7
Improve responsive styles for attachment header
ryankeairns May 14, 2026
c01ab21
Change preview badge styles
ryankeairns May 14, 2026
eda1777
Tidy up title styles
ryankeairns May 14, 2026
64ba83a
Improve responsive header styles
ryankeairns May 15, 2026
82158e9
[Reference] AB skill design proposals
SiddharthMantri May 15, 2026
103b8a9
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine May 15, 2026
9b08131
Do not show attachment header if there are no buttons
zacharyparikh May 15, 2026
d5324c1
Merge branch 'main' into ab/chat-customization-skill-poc
zacharyparikh May 18, 2026
d1aa9eb
Update constants and types
zacharyparikh May 18, 2026
34f8f30
Infer SkillDraftAttachmentData type from zod schema
zacharyparikh May 18, 2026
b82beca
Merge remote-tracking branch 'upstream/main' into ab/chat-customizati…
zacharyparikh May 19, 2026
1a23814
FIx iconType prop type
zacharyparikh May 19, 2026
d6d3d94
Remove draft naming from skill attachment type
zacharyparikh May 19, 2026
5b06bb1
i18n fix - remove unused currently previewing message
zacharyparikh May 19, 2026
a9fb9a0
Import skill path and type from public module
zacharyparikh May 19, 2026
f318c83
update agentBuilderPlatform bundle limit
zacharyparikh May 20, 2026
3d656c3
Remove skill instructions truncation
zacharyparikh May 20, 2026
d758d1a
add list tool inline tool for skill authoring
SiddharthMantri May 21, 2026
f82d416
remove premature optimization for max tools
SiddharthMantri May 21, 2026
904341e
feat(agent builder) tool creation
SiddharthMantri May 27, 2026
76d0bdf
Merge branch 'main' into ab/chat-tool-creation
SiddharthMantri May 27, 2026
e23d875
fix merge issues
SiddharthMantri Jun 1, 2026
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
6 changes: 6 additions & 0 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
pageLoadAssetSize:
actions: 20500
advancedSettings: 6196
<<<<<<< HEAD
agentBuilder: 52831
agentBuilderPlatform: 15544
agentBuilderWorkflows: 25000
=======
agentBuilder: 58540
agentBuilderDashboards: 7786
agentBuilderPlatform: 15544
agentBuilderWorkflows: 24405
>>>>>>> main
agentContextLayer: 1883
aiAssistantManagementSelection: 11569
aiops: 15227
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export interface GetActionButtonsParams<TAttachment extends UnknownAttachment =
* Use to mark an attachment as currently previewed outside canvas.
*/
setPreviewBadgeState?: (previewBadgeState: AttachmentPreviewState) => void;
/** The version number being rendered. Undefined when version metadata is unavailable. */
version?: number;
/** Total number of versions for this attachment in the conversation. Undefined when version metadata is unavailable. */
versionCount?: number;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ export const AGENT_BUILDER_BUILTIN_SKILLS = [
`${internalNamespaces.search}.rag-chatbot`,
`${internalNamespaces.search}.use-case-library`,
'skill-authoring',
'tool-authoring',
] as const;

export type AgentBuilderBuiltinSkill = (typeof AGENT_BUILDER_BUILTIN_SKILLS)[number];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import {
type ActionTypeExecutorResult,
AgentBuilderConnectorFeatureId,
} from '@kbn/actions-plugin/common';
import { ToolType, isMcpTool, type McpToolDefinition } from '@kbn/agent-builder-common/tools';
import {
ToolType,
editableToolTypes,
isMcpTool,
type McpToolDefinition,
} from '@kbn/agent-builder-common/tools';
import type { RouteDependencies } from '../types';
import { getHandlerWrapper } from '../wrap_handler';
import type {
Expand Down Expand Up @@ -762,4 +767,47 @@ export function registerInternalToolsRoutes({
});
})
);

// Dry-run an un-persisted tool draft. Used by the chat tool-authoring
// attachment card's Test affordance. Same execution path as the persisted
// tool would take at agent runtime, scoped to the requesting user.
router.post(
{
path: `${internalApiPath}/tools/_execute_draft`,
validate: {
body: schema.object({
type: schema.oneOf(
// @ts-expect-error TS2769: editableToolTypes is a const array of literals
editableToolTypes.map((type) => schema.literal(type))
),
configuration: schema.recordOf(schema.string(), schema.any()),
tool_params: schema.recordOf(schema.string(), schema.any()),
connector_id: schema.maybe(schema.string()),
}),
},
options: { access: 'internal' },
security: AGENT_BUILDER_READ_SECURITY,
},
wrapHandler(async (ctx, request, response) => {
const {
type,
configuration,
tool_params: toolParams,
connector_id: connectorId,
} = request.body;
const { tools: toolService } = getInternalServices();

const toolResult = await toolService.executeDraft({
request,
type,
configuration,
toolParams,
connectorId,
});

return response.ok({
body: { results: toolResult.results },
});
})
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@ import type {
SavedObjectsServiceStart,
} from '@kbn/core/server';
import type { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server';
import type { Runner } from '@kbn/agent-builder-server';
import type { Runner, InternalToolDefinition } from '@kbn/agent-builder-server';
import type { WorkflowsServerPluginSetup } from '@kbn/workflows-management-plugin/server';
import { isAllowedBuiltinTool } from '@kbn/agent-builder-server/allow_lists';
import type { SpacesPluginStart } from '@kbn/spaces-plugin/server';
import { AGENT_BUILDER_EXPERIMENTAL_FEATURES_SETTING_ID } from '@kbn/management-settings-ids';
import { createBadRequestError, type ToolType } from '@kbn/agent-builder-common';
import { getCurrentSpaceId } from '../../utils/spaces';
import {
createBuiltinToolRegistry,
createBuiltinProviderFn,
type BuiltinToolRegistry,
} from './builtin';
import type { ToolsServiceSetup, ToolsServiceStart } from './types';
import type { ExecuteDraftParams, ToolsServiceSetup, ToolsServiceStart } from './types';
import { getToolTypeDefinitions } from './tool_types';
import { isEnabledDefinition } from './tool_types/definitions';
import { createPersistedProviderFn } from './persisted';
Expand Down Expand Up @@ -146,10 +147,70 @@ export class ToolsService {
});
};

const executeDraft: ToolsServiceStart['executeDraft'] = async ({
request,
type,
configuration,
toolParams,
connectorId,
}: ExecuteDraftParams) => {
const typeDef = toolTypes.find(
(def): def is Extract<typeof def, { toolType: ToolType }> & { validateForCreate: any } =>
'toolType' in def && def.toolType === type && isEnabledDefinition(def)
);
if (!typeDef || !isEnabledDefinition(typeDef)) {
throw createBadRequestError(
`Unknown or unsupported tool type for chat authoring: ${String(type)}`
);
}

const spaceId = getCurrentSpaceId({ request, spaces });
const esClient = elasticsearch.client.asScoped(request).asCurrentUser;
const validatorContext = { request, spaceId, esClient };

const validatedConfig = await typeDef.validateForCreate({
config: configuration as Record<string, any>,
context: validatorContext,
});

const dynamic = await typeDef.getDynamicProps(validatedConfig as Record<string, any>, {
request,
spaceId,
});
const toolSchema = await dynamic.getSchema();
const validation = toolSchema.safeParse(toolParams);
if (!validation.success) {
throw createBadRequestError(`Invalid parameters: ${validation.error.message}`);
}

const transientTool: InternalToolDefinition = {
id: '__draft__',
type,
description: 'Draft tool execution',
readonly: true,
tags: [],
experimental: false,
configuration: validatedConfig as Record<string, unknown>,
isAvailable: async () => ({ status: 'available' }),
getSchema: () => toolSchema,
getHandler: async () => dynamic.getHandler(),
...(dynamic.getLlmDescription ? { getLlmDescription: dynamic.getLlmDescription } : {}),
};

return getRunner().runInternalTool({
tool: transientTool,
toolParams: validation.data as Record<string, unknown>,
request,
source: 'user',
...(connectorId ? { defaultConnectorId: connectorId } : {}),
});
};

return {
getRegistry,
getToolDefinitions: () => toolTypes,
getHealthClient,
executeDraft,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

import type { ZodObject } from '@kbn/zod/v4';
import type { KibanaRequest } from '@kbn/core-http-server';
import type { ToolType } from '@kbn/agent-builder-common';
import type { StaticToolRegistration, ToolRegistry } from '@kbn/agent-builder-server/tools';
import type { RunToolReturn } from '@kbn/agent-builder-server';
import type { AnyToolTypeDefinition } from './tool_types';
import type { ToolHealthClient } from './health';

Expand All @@ -29,4 +31,20 @@ export interface ToolsServiceStart {
* Used to track and query tool health state.
*/
getHealthClient(opts: { request: KibanaRequest }): ToolHealthClient;
/**
* Execute an inline (un-persisted) tool draft using the same runtime path
* the agent would use at call time. Powers the chat tool-authoring dry-run.
* Validates the configuration via the matching tool type's `validateForCreate`,
* then runs the handler through the scoped runner. No persistence, no
* health tracking.
*/
executeDraft(opts: ExecuteDraftParams): Promise<RunToolReturn>;
}

export interface ExecuteDraftParams {
request: KibanaRequest;
type: ToolType;
configuration: Record<string, unknown>;
toolParams: Record<string, unknown>;
connectorId?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export {
type GraphAttachmentData,
} from './graph';
export { SKILL_ATTACHMENT_TYPE, type SkillAttachment, type SkillAttachmentData } from './skill';
export { TOOL_ATTACHMENT_TYPE, type ToolAttachment, type ToolAttachmentData } from './tool';
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { ToolType, EsqlToolConfig } from '@kbn/agent-builder-common';
import type { Attachment } from '@kbn/agent-builder-common/attachments';

/**
* Attachment type id for tools authored via chat.
*
* A `tool` attachment is a versioned, by-value snapshot of a candidate tool
* payload (matching the public `POST /api/agent_builder/tools` request body).
* It is created by the tool-authoring inline tools and rendered as an inline
* card with primary "Create tool" and (canvas-side) "Test" actions. Once
* persisted, the attachment's `origin` is set to the persisted tool id via
* `updateOrigin` so the card flips to a "Created" state.
*
* MVP: only ES|QL bodies are supported. The shape stays open under
* `ToolAttachmentData` so other types can be added later without breaking
* persisted attachments.
*/
export const TOOL_ATTACHMENT_TYPE = 'tool' as const;

/**
* Data shape stored on a `tool` attachment version.
*
* Mirrors `CreateToolPayload` from
* `x-pack/platform/plugins/shared/agent_builder/common/http_api/tools.ts`
* so the card's "Create tool" button can POST `attachment.data` directly to
* `/api/agent_builder/tools`.
*/
export interface ToolAttachmentData {
id: string;
type: ToolType.esql;
description: string;
tags?: string[];
configuration: EsqlToolConfig;
}

export type ToolAttachment = Attachment<typeof TOOL_ATTACHMENT_TYPE, ToolAttachmentData>;
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@ import type { AttachmentServiceStartContract } from '@kbn/agent-builder-browser'
import type { ILocatorClient } from '@kbn/share-plugin/common/url_service';
import type { CoreStart } from '@kbn/core/public';
import { AttachmentType } from '@kbn/agent-builder-common/attachments';
import { GRAPH_ATTACHMENT_TYPE, SKILL_ATTACHMENT_TYPE } from '../../common/attachments';
import {
GRAPH_ATTACHMENT_TYPE,
SKILL_ATTACHMENT_TYPE,
TOOL_ATTACHMENT_TYPE,
} from '../../common/attachments';
import { createEsqlAttachmentDefinition } from './esql_attachment';
import { textAttachmentDefinition } from './text_attachment';
import { screenContextAttachmentDefinition } from './screen_context_attachment';
import { graphAttachmentDefinition } from './graph_attachment/graph_attachment';
import { createSkillAttachmentDefinition } from './skill_attachment/skill_attachment';
import { createToolAttachmentDefinition } from './tool_attachment/tool_attachment';

export const registerAttachmentUiDefinitions = ({
attachments,
Expand All @@ -37,4 +42,12 @@ export const registerAttachmentUiDefinitions = ({
application: core.application,
})
);
attachments.addAttachmentType(
TOOL_ATTACHMENT_TYPE,
createToolAttachmentDefinition({
http: core.http,
notifications: core.notifications,
application: core.application,
})
);
};
Loading
Loading