Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0e45c52
wip
stephmilovic Nov 11, 2025
461686c
fix tool description and schema
stephmilovic Nov 11, 2025
5996a99
rm
stephmilovic Nov 11, 2025
779e84c
fixes
stephmilovic Nov 11, 2025
771f19e
Merge branch 'main' into product_docs_ab_tool
stephmilovic Nov 12, 2025
8252602
Changes from node scripts/lint_ts_projects --fix
kibanamachine Nov 12, 2025
f2ee19c
Merge branch 'product_docs_ab_tool' of github.com:stephmilovic/kibana…
stephmilovic Nov 12, 2025
b1d415c
Merge branch 'main' into product_docs_ab_tool
stephmilovic Nov 12, 2025
15f004b
shorter description
stephmilovic Nov 12, 2025
67e00dd
product documentation registration only when available
stephmilovic Nov 12, 2025
99b53ec
update tool services tests
stephmilovic Nov 12, 2025
b356eef
promises for types
stephmilovic Nov 12, 2025
caa6709
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine Nov 12, 2025
ccf5860
Merge branch 'main' into product_docs_ab_tool
stephmilovic Nov 14, 2025
85f22ee
refactor
stephmilovic Nov 14, 2025
6be7a9f
more fixing
stephmilovic Nov 14, 2025
2856fb6
Changes from node scripts/lint_ts_projects --fix
kibanamachine Nov 14, 2025
789b159
rm async
stephmilovic Nov 14, 2025
6f4bea1
Merge branch 'product_docs_ab_tool' of github.com:stephmilovic/kibana…
stephmilovic Nov 14, 2025
5afd16c
revert plugin
stephmilovic Nov 14, 2025
24b046d
dynamic inference id
stephmilovic Nov 14, 2025
e71f2dd
Merge branch 'main' into product_docs_ab_tool
elasticmachine Nov 17, 2025
7382505
rm connector inferenceId code
stephmilovic Nov 18, 2025
414df60
Merge branch 'main' into product_docs_ab_tool
stephmilovic Nov 18, 2025
0911d2a
Merge remote-tracking branch 'upstream/main' into product_docs_ab_tool
stephmilovic Nov 25, 2025
63b605a
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine Nov 25, 2025
d9a976f
Merge remote-tracking branch 'upstream/main' into product_docs_ab_tool
stephmilovic Nov 30, 2025
bad8112
move to new plugin
stephmilovic Nov 30, 2025
c52a35e
productDocumentationTool
stephmilovic Nov 30, 2025
5eaae5c
Changes from node scripts/lint_ts_projects --fix
kibanamachine Nov 30, 2025
6409546
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine Nov 30, 2025
3282c73
Changes from node scripts/eslint_all_files --no-cache --fix
kibanamachine Nov 30, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const platformCoreTools = {
executeEsql: platformCoreTool('execute_esql'),
createVisualization: platformCoreTool('create_visualization'),
getWorkflowExecutionStatus: platformCoreTool('get_workflow_execution_status'),
productDocumentation: platformCoreTool('product_documentation'),
} as const;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"configPath": ["xpack", "agentBuilderPlatform"],
"requiredPlugins": ["onechat"],
"requiredBundles": [],
"optionalPlugins": ["workflowsManagement"],
"optionalPlugins": ["llmTasks", "workflowsManagement"],
"extraPublicDirs": []
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ dependsOn:
- '@kbn/onechat-plugin'
- '@kbn/core-lifecycle-server'
- '@kbn/esql-validation-autocomplete'
- '@kbn/inference-common'
- '@kbn/llm-tasks-plugin'
tags:
- plugin
- prod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import type { CoreSetup } from '@kbn/core-lifecycle-server';
import type { BuiltinToolDefinition } from '@kbn/onechat-server';
import { productDocumentationTool } from './product_documentation';
import type {
AgentBuilderPlatformPluginStart,
PluginSetupDependencies,
Expand Down Expand Up @@ -40,6 +41,7 @@ export const registerTools = ({
listIndicesTool(),
indexExplorerTool(),
createVisualizationTool(),
productDocumentationTool(coreSetup),
];

if (setupDeps.workflowsManagement) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* 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 { z } from '@kbn/zod';
import { platformCoreTools, ToolType } from '@kbn/onechat-common';
import { defaultInferenceEndpoints } from '@kbn/inference-common';
import type { BuiltinToolDefinition } from '@kbn/onechat-server';
import { createErrorResult } from '@kbn/onechat-server';
import { ToolResultType } from '@kbn/onechat-common/tools/tool_result';
import type { CoreSetup } from '@kbn/core/server';
import type { RetrieveDocumentationResultDoc } from '@kbn/llm-tasks-plugin/server';
import type { AgentBuilderPlatformPluginStart, PluginStartDependencies } from '../types';

const productDocumentationSchema = z.object({
query: z.string().describe('Search query to retrieve documentation about Elastic products'),
product: z
.enum(['kibana', 'elasticsearch', 'observability', 'security'])
.optional()
.describe('Product to filter by: "kibana", "elasticsearch", "observability", or "security"'),
Comment thread
stephmilovic marked this conversation as resolved.
max: z
.number()
.optional()
.default(3)
.describe('Maximum number of documents to return. Defaults to 3.'),
});

// TODO make this configurable, we need a platform level setting for the embedding model
const inferenceId = defaultInferenceEndpoints.ELSER;

export const productDocumentationTool = (
coreSetup: CoreSetup<PluginStartDependencies, AgentBuilderPlatformPluginStart>
): BuiltinToolDefinition<typeof productDocumentationSchema> => {
// Create a closure that will resolve llmTasks when the handler is called
const getLlmTasks = async () => {
const [, plugins] = await coreSetup.getStartServices();
return plugins.llmTasks;
};

const baseTool: BuiltinToolDefinition<typeof productDocumentationSchema> = {
id: platformCoreTools.productDocumentation,
type: ToolType.builtin,
description: `Search and retrieve documentation about Elastic products (Kibana, Elasticsearch, Elastic Security, Elastic Observability).`,
schema: productDocumentationSchema,
handler: async ({ query, product, max = 3 }, { modelProvider, logger, request }) => {
const llmTasks = await getLlmTasks();
if (!llmTasks) {
return {
results: [
createErrorResult({
message:
'Product documentation tool is not available. LlmTasks plugin is not available.',
}),
],
};
}

try {
// Get the default model to extract the connector
const model = await modelProvider.getDefaultModel();
const connector = model.connector;

// Retrieve documentation
const result = await llmTasks.retrieveDocumentation({
searchTerm: query,
products: product ? [product as any] : undefined,
max,
connectorId: connector.connectorId,
request,
inferenceId,
});

if (!result.success || result.documents.length === 0) {
return {
results: [
createErrorResult({
message: 'No documentation found for the given query.',
metadata: {
query,
product: product || 'all',
},
}),
],
};
}

// Return documentation results
return {
results: result.documents.map((doc: RetrieveDocumentationResultDoc) => ({
type: ToolResultType.resource,
data: {
reference: {
url: doc.url,
title: doc.title,
},
partial: doc.summarized,
content: {
title: doc.title,
url: doc.url,
content: doc.content,
summarized: doc.summarized,
},
},
})),
};
} catch (error) {
logger.error(`Error retrieving product documentation: ${error.message}`);
return {
results: [
createErrorResult({
message: `Failed to retrieve product documentation: ${error.message}`,
}),
],
};
}
},
tags: [],
availability: {
cacheMode: 'space',
handler: async () => {
try {
const [, plugins] = await coreSetup.getStartServices();
const llmTasks = plugins.llmTasks;

if (!llmTasks) {
return { status: 'unavailable' };
}

const isAvailable =
(await llmTasks.retrieveDocumentationAvailable({
inferenceId,
})) ?? false;

return {
status: isAvailable ? 'available' : 'unavailable',
};
} catch (error) {
return { status: 'unavailable' };
}
},
},
};

return baseTool;
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import type { WorkflowsServerPluginSetup } from '@kbn/workflows-management-plugin/server';
import type { OnechatPluginSetup, OnechatPluginStart } from '@kbn/onechat-plugin/server';
import type { LlmTasksPluginStart } from '@kbn/llm-tasks-plugin/server';

export interface PluginSetupDependencies {
workflowsManagement?: WorkflowsServerPluginSetup;
Expand All @@ -15,6 +16,7 @@ export interface PluginSetupDependencies {

export interface PluginStartDependencies {
onechat: OnechatPluginStart;
llmTasks?: LlmTasksPluginStart;
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,7 @@
"@kbn/onechat-plugin",
"@kbn/core-lifecycle-server",
"@kbn/esql-validation-autocomplete",
"@kbn/inference-common",
"@kbn/llm-tasks-plugin",
]
}
2 changes: 1 addition & 1 deletion x-pack/platform/plugins/shared/onechat/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,6 @@
"@kbn/shared-ux-utility",
"@kbn/usage-collection-plugin",
"@kbn/core-notifications-browser",
"@kbn/deeplinks-agent-builder"
"@kbn/deeplinks-agent-builder",
]
}