Merge branch 'main' into fix/js-packages-deps
This commit is contained in:
commit
cde33cd044
4 changed files with 94 additions and 6 deletions
5
.changeset/six-tigers-fetch.md
Normal file
5
.changeset/six-tigers-fetch.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@docsearch/react": patch
|
||||
---
|
||||
|
||||
Fix Ask AI conversations breaking after stopping a stream mid-tool-call. Incomplete tool parts (`input-streaming`/`input-available`) are now pruned before resending, so the dangling `tool_use` no longer causes the provider to reject every subsequent question.
|
||||
|
|
@ -104,7 +104,6 @@ const getAgentStudioTransport = ({
|
|||
algolia: algoliaParams,
|
||||
},
|
||||
prepareSendMessagesRequest({ id, messages, body, ...rest }) {
|
||||
// Filter out `data-*` part types since Agent Studio does not currently support them on the request
|
||||
const sanitizedMessages = sanitizeMessagesForRequest(messages);
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -286,6 +286,82 @@ describe('sanitizeMessagesForRequest', () => {
|
|||
expect(result[1]).not.toBe(sanitizedMessage);
|
||||
expect(result[1].parts).toEqual([{ type: 'text', text: 'Hi' }]);
|
||||
});
|
||||
|
||||
it('removes an aborted tool call from the assistant message', () => {
|
||||
const initialQuestion: AIMessage = {
|
||||
id: 'message-1',
|
||||
role: 'user',
|
||||
parts: [{ type: 'text', text: 'Find installation instructions' }],
|
||||
};
|
||||
const assistantMessage = message('message-2', [
|
||||
{ type: 'step-start' },
|
||||
{
|
||||
type: 'tool-algolia_search_index',
|
||||
toolCallId: 'tool-1',
|
||||
state: 'input-streaming',
|
||||
input: undefined,
|
||||
},
|
||||
]);
|
||||
const followUpQuestion: AIMessage = {
|
||||
id: 'message-3',
|
||||
role: 'user',
|
||||
parts: [{ type: 'text', text: 'What are the prerequisites?' }],
|
||||
};
|
||||
|
||||
expect(
|
||||
sanitizeMessagesForRequest([
|
||||
initialQuestion,
|
||||
assistantMessage,
|
||||
followUpQuestion,
|
||||
])
|
||||
).toEqual([
|
||||
initialQuestion,
|
||||
message('message-2', [{ type: 'step-start' }]),
|
||||
followUpQuestion,
|
||||
]);
|
||||
});
|
||||
|
||||
it('keeps streamed text while removing an incomplete tool call', () => {
|
||||
const result = sanitizeMessagesForRequest([
|
||||
message('message-1', [
|
||||
{ type: 'text', text: 'Let me look that up.' },
|
||||
{
|
||||
type: 'tool-searchIndex',
|
||||
toolCallId: 'tool-1',
|
||||
state: 'input-available',
|
||||
input: { query: 'installation' },
|
||||
},
|
||||
]),
|
||||
]);
|
||||
|
||||
expect(result).toEqual([
|
||||
message('message-1', [{ type: 'text', text: 'Let me look that up.' }]),
|
||||
]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
state: 'output-available' as const,
|
||||
output: { hits: [] },
|
||||
},
|
||||
{
|
||||
state: 'output-error' as const,
|
||||
errorText: 'Search failed',
|
||||
},
|
||||
])('keeps a $state tool call', (toolPart) => {
|
||||
const messages = [
|
||||
message('message-1', [
|
||||
{
|
||||
type: 'tool-searchIndex',
|
||||
toolCallId: 'tool-1',
|
||||
input: { query: 'installation' },
|
||||
...toolPart,
|
||||
},
|
||||
]),
|
||||
];
|
||||
|
||||
expect(sanitizeMessagesForRequest(messages)).toBe(messages);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAgentPromptSuggestions', () => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { TextUIPart } from 'ai';
|
||||
import { isDataUIPart, isToolOrDynamicToolUIPart, type TextUIPart } from 'ai';
|
||||
|
||||
import type { StoredAskAiState } from '../types';
|
||||
import type {
|
||||
|
|
@ -281,10 +281,18 @@ export function sanitizeMessagesForRequest(messages: AIMessage[]): AIMessage[] {
|
|||
let sanitizedMessages: AIMessage[] | undefined;
|
||||
|
||||
messages.forEach((message, index) => {
|
||||
// Filter out `data-*` part types since Agent Studio does not currently support them on the request
|
||||
const parts = message.parts.filter(
|
||||
(part) => !part.type.startsWith('data-')
|
||||
);
|
||||
// Remove parts that Agent Studio does not support during a request, including incomplete tool calls
|
||||
const parts = message.parts.filter((part) => {
|
||||
if (isDataUIPart(part)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isToolOrDynamicToolUIPart(part) && part.state.startsWith('input-')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (parts.length === message.parts.length) {
|
||||
sanitizedMessages?.push(message);
|
||||
|
|
|
|||
Loading…
Reference in a new issue