Skip to content

Commit

Permalink
[Search Assistant] Use scopes to modify behavior contextually (#195785)
Browse files Browse the repository at this point in the history
## Summary

This actually uses the Search Assistant scope to modify the assistant's
behavior depending on the context they're in. The assistant now:
- Defaults to Observability mode
- Is a Search assistant in the Search pages
- Switches dynamically, changing available functions, prompts and
instructions based on context

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
sphilipse and kibanamachine authored Oct 11, 2024
1 parent f9417fb commit ee341d5
Show file tree
Hide file tree
Showing 69 changed files with 623 additions and 218 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ x-pack/test/alerting_api_integration/common/plugins/actions_simulators @elastic/
packages/kbn-actions-types @elastic/response-ops
src/plugins/advanced_settings @elastic/appex-sharedux @elastic/kibana-management
x-pack/packages/kbn-ai-assistant @elastic/search-kibana
x-pack/packages/kbn-ai-assistant-common @elastic/search-kibana
src/plugins/ai_assistant_management/selection @elastic/obs-knowledge-team
x-pack/packages/ml/aiops_change_point_detection @elastic/ml-ui
x-pack/packages/ml/aiops_common @elastic/ml-ui
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
"@kbn/actions-types": "link:packages/kbn-actions-types",
"@kbn/advanced-settings-plugin": "link:src/plugins/advanced_settings",
"@kbn/ai-assistant": "link:x-pack/packages/kbn-ai-assistant",
"@kbn/ai-assistant-common": "link:x-pack/packages/kbn-ai-assistant-common",
"@kbn/ai-assistant-management-plugin": "link:src/plugins/ai_assistant_management/selection",
"@kbn/aiops-change-point-detection": "link:x-pack/packages/ml/aiops_change_point_detection",
"@kbn/aiops-common": "link:x-pack/packages/ml/aiops_common",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
'xpack.observability.unsafe.thresholdRule.enabled (boolean?)',
'xpack.observability_onboarding.ui.enabled (boolean?)',
'xpack.observabilityLogsExplorer.navigation.showAppLink (boolean?|never)',
'xpack.observabilityAIAssistant.scope (observability?|search?)',
'share.new_version.enabled (boolean?)',
'aiAssistantManagementSelection.preferredAIAssistantType (default?|never?|observability?)',
/**
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"@kbn/advanced-settings-plugin/*": ["src/plugins/advanced_settings/*"],
"@kbn/ai-assistant": ["x-pack/packages/kbn-ai-assistant"],
"@kbn/ai-assistant/*": ["x-pack/packages/kbn-ai-assistant/*"],
"@kbn/ai-assistant-common": ["x-pack/packages/kbn-ai-assistant-common"],
"@kbn/ai-assistant-common/*": ["x-pack/packages/kbn-ai-assistant-common/*"],
"@kbn/ai-assistant-management-plugin": ["src/plugins/ai_assistant_management/selection"],
"@kbn/ai-assistant-management-plugin/*": ["src/plugins/ai_assistant_management/selection/*"],
"@kbn/aiops-change-point-detection": ["x-pack/packages/ml/aiops_change_point_detection"],
Expand Down
3 changes: 3 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @kbn/ai-assistant-common

Provides types and utils to render the AI Assistant in plugins.
7 changes: 7 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/
export * from './src';
19 changes: 19 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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.
*/

module.exports = {
coverageDirectory:
'<rootDir>/target/kibana-coverage/jest/x-pack/packages/kbn_ai_assistant_common_src',
coverageReporters: ['text', 'html'],
collectCoverageFrom: [
'<rootDir>/x-pack/packages/kbn-ai-assistant-common/src/**/*.{ts,tsx}',
'!<rootDir>/x-pack/packages/kbn-ai-assistant-common/src/*.test.{ts,tsx}',
],
preset: '@kbn/test',
rootDir: '../../..',
roots: ['<rootDir>/x-pack/packages/kbn-ai-assistant-common'],
};
5 changes: 5 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/kibana.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "@kbn/ai-assistant-common",
"owner": "@elastic/search-kibana",
"type": "shared-common"
}
7 changes: 7 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@kbn/ai-assistant-common",
"private": true,
"version": "1.0.0",
"license": "Elastic License 2.0",
"sideEffects": false
}
9 changes: 9 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/setup_tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

// eslint-disable-next-line import/no-extraneous-dependencies
import '@testing-library/jest-dom';
9 changes: 9 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export * from './types';
export * from './utils';
8 changes: 8 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* 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.
*/

export type AssistantScope = 'observability' | 'search' | 'all';
17 changes: 17 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/src/utils/filter_scopes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* 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 { AssistantScope } from '../types';

export function filterScopes<T extends { scopes?: AssistantScope[] }>(scope?: AssistantScope) {
return function (value: T): boolean {
if (!scope || !value) {
return true;
}
return value?.scopes ? value.scopes.includes(scope) || value.scopes.includes('all') : true;
};
}
8 changes: 8 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* 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.
*/

export * from './filter_scopes';
19 changes: 19 additions & 0 deletions x-pack/packages/kbn-ai-assistant-common/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"outDir": "target/types",
"types": [
"jest",
"node",
]
},
"include": [
"**/*.ts",
"**/*.tsx",
],
"exclude": [
"target/**/*"
],
"kbn_references": [
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { EuiSelectableOptionCheckedType } from '@elastic/eui/src/components
import { i18n } from '@kbn/i18n';
import { FunctionVisibility } from '@kbn/observability-ai-assistant-plugin/public';
import type { FunctionDefinition } from '@kbn/observability-ai-assistant-plugin/common';
import { useAIAssistantChatService } from '../hooks/use_ai_assistant_chat_service';
import { useFunctions } from '../hooks/use_functions';

interface FunctionListOption {
label: string;
Expand All @@ -40,8 +40,7 @@ export function FunctionListPopover({
onSelectFunction: (func: string | undefined) => void;
disabled: boolean;
}) {
const { getFunctions } = useAIAssistantChatService();
const functions = getFunctions();
const functions = useFunctions();

const [functionOptions, setFunctionOptions] = useState<
Array<EuiSelectableOption<FunctionListOption>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const starterPromptInnerClassName = css`

export function StarterPrompts({ onSelectPrompt }: { onSelectPrompt: (prompt: string) => void }) {
const service = useAIAssistantAppService();

const { connectors } = useGenAIConnectors();

if (!connectors || connectors.length === 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { css } from '@emotion/css';
import { euiThemeVars } from '@kbn/ui-theme';
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import type { AssistantScope } from '@kbn/ai-assistant-common';
import { useKibana } from '../hooks/use_kibana';
import { ConversationList, ChatBody, ChatInlineEditingContent } from '../chat';
import { useConversationKey } from '../hooks/use_conversation_key';
Expand All @@ -26,13 +27,15 @@ interface ConversationViewProps {
navigateToConversation: (nextConversationId?: string) => void;
getConversationHref?: (conversationId: string) => string;
newConversationHref?: string;
scope?: AssistantScope;
}

export const ConversationView: React.FC<ConversationViewProps> = ({
conversationId,
navigateToConversation,
getConversationHref,
newConversationHref,
scope,
}) => {
const { euiTheme } = useEuiTheme();

Expand All @@ -57,6 +60,12 @@ export const ConversationView: React.FC<ConversationViewProps> = ({
[service]
);

useEffect(() => {
if (scope) {
service.setScope(scope);
}
}, [scope, service]);

const { key: bodyKey, updateConversationIdInPlace } = useConversationKey(conversationId);

const [secondSlotContainer, setSecondSlotContainer] = useState<HTMLDivElement | null>(null);
Expand Down
1 change: 1 addition & 0 deletions x-pack/packages/kbn-ai-assistant/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
export * from './use_ai_assistant_app_service';
export * from './use_ai_assistant_chat_service';
export * from './use_knowledge_base';
export * from './use_scope';
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
} from '@testing-library/react-hooks';
import { merge } from 'lodash';
import React, { PropsWithChildren } from 'react';
import { Observable, of, Subject } from 'rxjs';
import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
import {
MessageRole,
StreamingChatResponseEventType,
Expand All @@ -31,6 +31,7 @@ import { createMockChatService } from '../utils/create_mock_chat_service';
import { createUseChat } from '@kbn/observability-ai-assistant-plugin/public/hooks/use_chat';
import type { NotificationsStart } from '@kbn/core/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { AssistantScope } from '@kbn/ai-assistant-common';

let hookResult: RenderHookResult<UseConversationProps, UseConversationResult>;

Expand All @@ -54,7 +55,9 @@ const mockService: MockedService = {
predefinedConversation$: new Observable(),
},
navigate: jest.fn().mockReturnValue(of()),
scope: 'all',
scope$: new BehaviorSubject<AssistantScope>('all') as MockedService['scope$'],
setScope: jest.fn(),
getScope: jest.fn(),
};

const mockChatService = createMockChatService();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { useAIAssistantAppService } from './use_ai_assistant_app_service';
import { useKibana } from './use_kibana';
import { useOnce } from './use_once';
import { useAbortableAsync } from './use_abortable_async';
import { useScope } from './use_scope';

function createNewConversation({
title = EMPTY_CONVERSATION_TITLE,
Expand Down Expand Up @@ -61,7 +62,7 @@ export function useConversation({
onConversationUpdate,
}: UseConversationProps): UseConversationResult {
const service = useAIAssistantAppService();
const { scope } = service;
const scope = useScope();

const {
services: {
Expand Down
15 changes: 15 additions & 0 deletions x-pack/packages/kbn-ai-assistant/src/hooks/use_functions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 { useObservable } from 'react-use/lib';
import { useAIAssistantChatService } from './use_ai_assistant_chat_service';

export const useFunctions = () => {
const service = useAIAssistantChatService();
const functions = useObservable(service.functions$);
return functions || [];
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import { useEffect, useMemo, useState } from 'react';
import { monaco } from '@kbn/monaco';
import { createInitializedObject } from '../utils/create_initialized_object';
import { useAIAssistantChatService } from './use_ai_assistant_chat_service';
import { safeJsonParse } from '../utils/safe_json_parse';
import { useFunctions } from './use_functions';

const { editor, languages, Uri } = monaco;

Expand All @@ -19,9 +19,9 @@ export const useJsonEditorModel = ({
functionName: string | undefined;
initialJson?: string | undefined;
}) => {
const chatService = useAIAssistantChatService();
const functions = useFunctions();

const functionDefinition = chatService.getFunctions().find((func) => func.name === functionName);
const functionDefinition = functions.find((func) => func.name === functionName);

const [initialJsonValue, setInitialJsonValue] = useState<string | undefined>(initialJson);

Expand Down
15 changes: 15 additions & 0 deletions x-pack/packages/kbn-ai-assistant/src/hooks/use_scope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 { useObservable } from 'react-use/lib';
import { useAIAssistantAppService } from './use_ai_assistant_app_service';

export const useScope = () => {
const service = useAIAssistantAppService();
const scope = useObservable(service.scope$);
return scope || 'all';
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

import type { DeeplyMockedKeys } from '@kbn/utility-types-jest';
import {
FunctionDefinition,
MessageRole,
ObservabilityAIAssistantChatService,
} from '@kbn/observability-ai-assistant-plugin/public';
import { BehaviorSubject } from 'rxjs';

type MockedChatService = DeeplyMockedKeys<ObservabilityAIAssistantChatService>;

Expand All @@ -18,6 +20,7 @@ export const createMockChatService = (): MockedChatService => {
chat: jest.fn(),
complete: jest.fn(),
sendAnalyticsEvent: jest.fn(),
functions$: new BehaviorSubject<FunctionDefinition[]>([]) as MockedChatService['functions$'],
getFunctions: jest.fn().mockReturnValue([]),
hasFunction: jest.fn().mockReturnValue(false),
hasRenderFunction: jest.fn().mockReturnValue(true),
Expand All @@ -29,6 +32,7 @@ export const createMockChatService = (): MockedChatService => {
content: '',
},
}),
getScope: jest.fn(),
};
return mockChatService;
};
1 change: 1 addition & 0 deletions x-pack/packages/kbn-ai-assistant/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@
"@kbn/code-editor",
"@kbn/ml-plugin",
"@kbn/share-plugin",
"@kbn/ai-assistant-common",
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
*/
import type { JSONSchema7TypeName } from 'json-schema';
import type { Observable } from 'rxjs';
import type { AssistantScope } from '@kbn/ai-assistant-common';
import { ChatCompletionChunkEvent, MessageAddEvent } from '../conversation_complete';
import { FunctionVisibility } from './function_visibility';
import { AssistantScope } from '../types';
export { FunctionVisibility };

type JSONSchemaOrPrimitive = CompatibleJSONSchema | string | number | boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
import { IconType } from '@elastic/eui';
import type { ToolSchema } from '@kbn/inference-plugin/common';
import type { AssistantScope } from '@kbn/ai-assistant-common';
import type { ObservabilityAIAssistantChatService } from '../public';
import type { FunctionResponse } from './functions/types';

Expand Down Expand Up @@ -145,6 +146,7 @@ export interface StarterPrompt {
title: string;
prompt: string;
icon: IconType;
scopes?: AssistantScope[];
}

export interface ObservabilityAIAssistantScreenContext {
Expand All @@ -157,5 +159,3 @@ export interface ObservabilityAIAssistantScreenContext {
actions?: Array<ScreenContextActionDefinition<any>>;
starterPrompts?: StarterPrompt[];
}

export type AssistantScope = 'observability' | 'search' | 'all';
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function filterFunctionDefinitions({
}: {
filter?: string;
definitions: FunctionDefinition[];
}) {
}): FunctionDefinition[] {
return filter
? definitions.filter((fn) => {
const matchesFilter =
Expand Down
Loading

0 comments on commit ee341d5

Please sign in to comment.