-
Notifications
You must be signed in to change notification settings - Fork 8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Security solution] AI Assistant, replace LLM
with SimpleChatModel
+ Bedrock streaming
#182041
Merged
Merged
Changes from 2 commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
4c82b22
wip
stephmilovic 08dfd30
esql tool
stephmilovic e823543
alert tools
stephmilovic 3908f40
fix merge
stephmilovic 699abbb
rm structured
stephmilovic dc3d12c
stream wip
stephmilovic 3e37927
Merge branch 'main' into simple_chat_model
stephmilovic 385bf10
wip
stephmilovic 4830879
zomg it streamed
stephmilovic ada553e
Merge branch 'main' into simple_chat_model
stephmilovic 13cbfe8
this is awesome
stephmilovic b7c6af7
rm silly
stephmilovic af61cac
moar
stephmilovic cb83d04
merge in main
stephmilovic e0556f4
support non-streaming for ChatOpenAI
stephmilovic a3c5394
wip openai
stephmilovic 109dfa0
openai really works
stephmilovic df3732e
fix executor tests
stephmilovic b123495
more tests
stephmilovic 93fedb7
more
stephmilovic b53c2c5
more tests
stephmilovic 14779d2
cleanup
stephmilovic 082c5ba
Merge branch 'main' into simple_chat_model
stephmilovic 4cdc699
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine 88d759e
test fix
stephmilovic 6d6a3c9
i18n fix
stephmilovic 43cef41
Merge branch 'simple_chat_model' of github.com:stephmilovic/kibana in…
stephmilovic 265afe2
rm disable
stephmilovic 85f7d2d
server dir
stephmilovic 8d7d540
move langchain code to langchain package
stephmilovic 4025acd
fix types
stephmilovic 47ff787
fix merge
stephmilovic 5b0b77b
fix type
stephmilovic c463169
fix import
stephmilovic 3a8c017
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine 68b0b7b
[CI] Auto-commit changed files from 'node scripts/generate codeowners'
kibanamachine fd4e3c3
fix lint
stephmilovic 6f11ca6
Merge branch 'simple_chat_model' of github.com:stephmilovic/kibana in…
stephmilovic 726dcbd
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine afb7e49
more import fixing
stephmilovic b81bdf0
Merge branch 'simple_chat_model' of github.com:stephmilovic/kibana in…
stephmilovic 2f66531
add readme comment, fix imports better
stephmilovic 021de2b
fix!
stephmilovic f2d398d
Merge branch 'main' into simple_chat_model
stephmilovic File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
x-pack/packages/kbn-elastic-assistant-common/impl/language_models/simple_chat_model.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* | ||
* 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 { | ||
SimpleChatModel, | ||
type BaseChatModelParams, | ||
} from '@langchain/core/language_models/chat_models'; | ||
import { type BaseMessage } from '@langchain/core/messages'; | ||
import type { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server'; | ||
import { Logger } from '@kbn/logging'; | ||
import { KibanaRequest } from '@kbn/core-http-server'; | ||
import { v4 as uuidv4 } from 'uuid'; | ||
import { get } from 'lodash/fp'; | ||
import { getDefaultArguments } from './constants'; | ||
import { ExecuteConnectorRequestBody } from '../..'; | ||
|
||
export const getMessageContentAndRole = (prompt: string, role = 'user') => ({ | ||
content: prompt, | ||
role: role === 'human' ? 'user' : role, | ||
}); | ||
|
||
export interface CustomChatModelInput extends BaseChatModelParams { | ||
actions: ActionsPluginStart; | ||
connectorId: string; | ||
logger: Logger; | ||
llmType?: string; | ||
model?: string; | ||
temperature?: number; | ||
request: KibanaRequest<unknown, unknown, ExecuteConnectorRequestBody>; | ||
} | ||
|
||
export class ActionsClientSimpleChatModel extends SimpleChatModel { | ||
#actions: ActionsPluginStart; | ||
#connectorId: string; | ||
#logger: Logger; | ||
#request: KibanaRequest<unknown, unknown, ExecuteConnectorRequestBody>; | ||
#traceId: string; | ||
llmType: string; | ||
model?: string; | ||
temperature?: number; | ||
|
||
constructor({ | ||
actions, | ||
connectorId, | ||
llmType, | ||
logger, | ||
model, | ||
request, | ||
temperature, | ||
}: CustomChatModelInput) { | ||
super({}); | ||
|
||
this.#actions = actions; | ||
this.#connectorId = connectorId; | ||
this.#traceId = uuidv4(); | ||
this.#logger = logger; | ||
this.#request = request; | ||
this.llmType = llmType ?? 'openai'; | ||
this.model = model; | ||
this.temperature = temperature; | ||
} | ||
|
||
_llmType() { | ||
return this.llmType; | ||
} | ||
|
||
// Model type needs to be `base_chat_model` to work with LangChain OpenAI Tools | ||
// We may want to make this configurable (ala _llmType) if different agents end up requiring different model types | ||
// See: https://github.com/langchain-ai/langchainjs/blob/fb699647a310c620140842776f4a7432c53e02fa/langchain/src/agents/openai/index.ts#L185 | ||
_modelType() { | ||
return 'base_chat_model'; | ||
} | ||
|
||
async _call(messages: BaseMessage[], options: this['ParsedCallOptions']): Promise<string> { | ||
if (!messages.length) { | ||
throw new Error('No messages provided.'); | ||
} | ||
const formattedMessages = []; | ||
if (messages.length === 2) { | ||
messages.forEach((message, i) => { | ||
if (typeof message.content !== 'string') { | ||
throw new Error('Multimodal messages are not supported.'); | ||
} | ||
formattedMessages.push(getMessageContentAndRole(message.content, message._getType())); | ||
}); | ||
} else { | ||
if (typeof messages[0].content !== 'string') { | ||
throw new Error('Multimodal messages are not supported.'); | ||
} | ||
formattedMessages.push(getMessageContentAndRole(messages[0].content)); | ||
} | ||
this.#logger.debug( | ||
`ActionsClientSimpleChatModel#_call\ntraceId: ${ | ||
this.#traceId | ||
}\nassistantMessage:\n${JSON.stringify(formattedMessages)} ` | ||
); | ||
// create a new connector request body with the assistant message: | ||
const requestBody = { | ||
actionId: this.#connectorId, | ||
params: { | ||
// hard code to non-streaming subaction as this class only supports non-streaming | ||
subAction: 'invokeAI', | ||
subActionParams: { | ||
model: this.#request.body.model, | ||
messages: formattedMessages, | ||
...getDefaultArguments(this.llmType, this.temperature, options.stop), | ||
}, | ||
}, | ||
}; | ||
|
||
// create an actions client from the authenticated request context: | ||
const actionsClient = await this.#actions.getActionsClientWithRequest(this.#request); | ||
|
||
const actionResult = await actionsClient.execute(requestBody); | ||
|
||
if (actionResult.status === 'error') { | ||
throw new Error( | ||
`ActionsClientSimpleChatModel: action result status is error: ${actionResult?.message} - ${actionResult?.serviceMessage}` | ||
); | ||
} | ||
|
||
const content = get('data.message', actionResult); | ||
|
||
if (typeof content !== 'string') { | ||
throw new Error( | ||
`ActionsClientSimpleChatModel: content should be a string, but it had an unexpected type: ${typeof content}` | ||
); | ||
} | ||
|
||
return content; // per the contact of _call, return a string | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handleParsingErrors
can also be a function, so I put logs in here while developing. It was not hit once I added theagentArgs
. However when I was hitting it, it did help to get the agent back on track so I think I should leave it. Here is an example of a run where it was hit: https://smith.langchain.com/public/910b7739-cd9a-401b-9db0-fe8438ff53e5/rThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI - this got merged already with https://github.com/elastic/kibana/pull/182207/files#diff-d9b56949a1c36c72c58e322963a2e97d81485ee83621f804c8849d0eec654a51R133