fix(agentStudio): agents dynamic mode enabled (#2959)
* fix(agentStudio): agents dynamic mode enabled * fix(askai): use string[] for dynamic agentStudio indices
This commit is contained in:
parent
3f74c33d45
commit
fe4d0c29f3
20 changed files with 146 additions and 517 deletions
6
.changeset/dynamic-indices-strings.md
Normal file
6
.changeset/dynamic-indices-strings.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
"@docsearch/react": patch
|
||||
"@docsearch/docusaurus-adapter": patch
|
||||
---
|
||||
|
||||
Align Ask AI dynamic indices with Agent Studio completions: `askAi.indices` is now `string[]` (index names only). Use `askAi.searchParameters` for per-index runtime overrides.
|
||||
|
|
@ -28,12 +28,7 @@ const minimalAskAiConfig = {
|
|||
|
||||
const askAiConfigWithIndices = {
|
||||
...minimalAskAiConfig,
|
||||
indices: [
|
||||
{
|
||||
index: 'markdown-index',
|
||||
description: 'Documentation content.',
|
||||
},
|
||||
],
|
||||
indices: ['markdown-index'],
|
||||
} satisfies NonNullable<DocSearchInput>['askAi'];
|
||||
|
||||
function testValidateThemeConfigWithUserThemeConfig(
|
||||
|
|
@ -240,20 +235,16 @@ describe('validateThemeConfig', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('accepts Agent Studio index searchParameters', () => {
|
||||
it('accepts Agent Studio searchParameters keyed by index', () => {
|
||||
const docsearch: DocSearchInput = {
|
||||
...minimalDocSearchConfig,
|
||||
askAi: {
|
||||
...askAiConfigWithIndices,
|
||||
indices: [
|
||||
{
|
||||
index: 'markdown-index',
|
||||
description: 'Documentation content.',
|
||||
searchParameters: {
|
||||
facetFilters: ['language:en', 'version:1.0'],
|
||||
},
|
||||
searchParameters: {
|
||||
'markdown-index': {
|
||||
filters: 'language:en AND version:1.0',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -310,12 +301,7 @@ describe('validateThemeConfig', () => {
|
|||
...minimalDocSearchConfig,
|
||||
askAi: minimalAskAiConfig,
|
||||
sidePanel: {
|
||||
indices: [
|
||||
{
|
||||
index: 'sidepanel-markdown-index',
|
||||
description: 'Documentation content for the side panel.',
|
||||
},
|
||||
],
|
||||
indices: ['sidepanel-markdown-index'],
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -342,7 +328,7 @@ describe('validateThemeConfig', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('rejects incomplete sidePanel Agent Studio indices', () => {
|
||||
it('rejects non-string sidePanel Agent Studio indices', () => {
|
||||
const docsearch = {
|
||||
...minimalDocSearchConfig,
|
||||
askAi: minimalAskAiConfig,
|
||||
|
|
@ -353,7 +339,7 @@ describe('validateThemeConfig', () => {
|
|||
|
||||
expectThrowMessage(
|
||||
() => testValidateThemeConfig(docsearch),
|
||||
'"docsearch.sidePanel.indices[0].description" is required'
|
||||
'"docsearch.sidePanel.indices[0]" must be a string'
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -6,16 +6,11 @@
|
|||
*/
|
||||
|
||||
import type { AskAiConfig } from '@docsearch/docusaurus-adapter';
|
||||
import type {
|
||||
AgentStudioIndices,
|
||||
DocSearchAskAi,
|
||||
DocSearchProps,
|
||||
} from '@docsearch/react';
|
||||
import type { DocSearchAskAi, DocSearchProps } from '@docsearch/react';
|
||||
import type { FacetFilters } from 'algoliasearch/lite';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useAlgoliaContextualFacetFiltersIfEnabled } from './useAlgoliaContextualFacetFilters';
|
||||
import { mergeFacetFilters } from './utils';
|
||||
|
||||
type AskAiOptions = AskAiConfig & Pick<DocSearchAskAi, 'tools'>;
|
||||
// The minimal props the hook needs from DocSearch
|
||||
|
|
@ -45,44 +40,49 @@ function getAskAiIndexName(
|
|||
askAi: AskAiConfig,
|
||||
indices: NonNullable<DocSearchProps['indices']>
|
||||
): string {
|
||||
return askAi.indices?.[0]?.index ?? getIndexName(indices[0]!);
|
||||
return askAi.indices?.[0] ?? getIndexName(indices[0]!);
|
||||
}
|
||||
|
||||
function applyContextualSearchToAgentStudioIndex(
|
||||
index: AgentStudioIndices,
|
||||
contextualSearchFilters: FacetFilters
|
||||
): AgentStudioIndices {
|
||||
return {
|
||||
...index,
|
||||
searchParameters: {
|
||||
...index.searchParameters,
|
||||
facetFilters: mergeFacetFilters(
|
||||
index.searchParameters?.facetFilters,
|
||||
contextualSearchFilters
|
||||
),
|
||||
},
|
||||
};
|
||||
function facetFiltersToFilterString(facetFilters: FacetFilters): string {
|
||||
const items = Array.isArray(facetFilters) ? facetFilters : [facetFilters];
|
||||
|
||||
return items
|
||||
.map((item) =>
|
||||
Array.isArray(item) ? `(${item.join(' OR ')})` : String(item)
|
||||
)
|
||||
.join(' AND ');
|
||||
}
|
||||
|
||||
function mergeFilters(existing: string | undefined, added: string): string {
|
||||
return existing ? `(${existing}) AND (${added})` : added;
|
||||
}
|
||||
|
||||
// We need to apply contextualSearch facetFilters to AskAI filters
|
||||
// This can't be done at config normalization time because contextual filters
|
||||
// can only be determined at runtime
|
||||
// can only be determined at runtime. Agent Studio accepts them via
|
||||
// askAi.searchParameters[index].filters, keyed by dynamic index names.
|
||||
function applyAskAiContextualSearch(
|
||||
askAi: AskAiOptions | undefined,
|
||||
contextualSearchFilters: FacetFilters | undefined
|
||||
): AskAiOptions | undefined {
|
||||
if (!askAi) {
|
||||
return undefined;
|
||||
}
|
||||
if (!contextualSearchFilters) {
|
||||
if (!askAi || !contextualSearchFilters || !askAi.indices?.length) {
|
||||
return askAi;
|
||||
}
|
||||
|
||||
const contextualFilters = facetFiltersToFilterString(contextualSearchFilters);
|
||||
const searchParameters = { ...askAi.searchParameters };
|
||||
|
||||
for (const indexName of askAi.indices) {
|
||||
const current = searchParameters[indexName] ?? {};
|
||||
searchParameters[indexName] = {
|
||||
...current,
|
||||
filters: mergeFilters(current.filters, contextualFilters),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...askAi,
|
||||
indices: askAi.indices?.map((index) =>
|
||||
applyContextualSearchToAgentStudioIndex(index, contextualSearchFilters)
|
||||
),
|
||||
searchParameters,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
declare module '@docsearch/docusaurus-adapter' {
|
||||
import type {
|
||||
AgentStudioIndices,
|
||||
AgentStudioSearchParameters,
|
||||
DocSearchAskAi,
|
||||
DocSearchProps,
|
||||
|
|
@ -50,7 +49,7 @@ declare module '@docsearch/docusaurus-adapter' {
|
|||
agentId: DocSearchAskAi['agentId'];
|
||||
suggestedQuestions?: DocSearchAskAi['suggestedQuestions'];
|
||||
searchParameters?: AgentStudioSearchParameters;
|
||||
indices?: AgentStudioIndices[];
|
||||
indices?: string[];
|
||||
memory?: DocSearchAskAi['memory'];
|
||||
promptSuggestions?: DocSearchAskAi['promptSuggestions'];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,56 +37,6 @@ const SearchParametersSchema = Joi.object({
|
|||
.optional(),
|
||||
}).unknown();
|
||||
|
||||
const SearchControlTextParamSchema = Joi.object({
|
||||
exposed: Joi.boolean().required(),
|
||||
default: Joi.string().optional(),
|
||||
}).unknown(false);
|
||||
|
||||
const SearchControlNumberParamSchema = Joi.object({
|
||||
exposed: Joi.boolean().required(),
|
||||
default: Joi.number().optional(),
|
||||
constraint: Joi.object({
|
||||
min: Joi.number().optional(),
|
||||
max: Joi.number().optional(),
|
||||
})
|
||||
.unknown(false)
|
||||
.optional(),
|
||||
}).unknown(false);
|
||||
|
||||
const SearchControlStringArrayParamSchema = Joi.object({
|
||||
exposed: Joi.boolean().required(),
|
||||
default: Joi.array().items(Joi.string()).optional(),
|
||||
constraint: Joi.object({
|
||||
values: Joi.array().items(Joi.string()).optional(),
|
||||
})
|
||||
.unknown(false)
|
||||
.optional(),
|
||||
merge: Joi.boolean().optional(),
|
||||
}).unknown(false);
|
||||
|
||||
const SearchControlFacetParamSchema = Joi.object({
|
||||
exposed: Joi.boolean().valid(false).required(),
|
||||
default: Joi.array().items(Joi.string()).optional(),
|
||||
}).unknown(false);
|
||||
|
||||
const AgentStudioSearchControlsSchema = Joi.object({
|
||||
query: SearchControlTextParamSchema.optional(),
|
||||
hits_per_page: SearchControlNumberParamSchema.optional(),
|
||||
page: SearchControlNumberParamSchema.optional(),
|
||||
attributesToRetrieve: SearchControlStringArrayParamSchema.optional(),
|
||||
responseFields: SearchControlStringArrayParamSchema.optional(),
|
||||
facets: SearchControlFacetParamSchema.optional(),
|
||||
custom: Joi.object().unknown().optional(),
|
||||
}).unknown(false);
|
||||
|
||||
const AskAiIndexSchema = Joi.object({
|
||||
index: Joi.string().required(),
|
||||
description: Joi.string().required(),
|
||||
enhancedDescription: Joi.string().optional(),
|
||||
searchParameters: SearchParametersSchema.optional(),
|
||||
searchControls: AgentStudioSearchControlsSchema.optional(),
|
||||
}).unknown(false);
|
||||
|
||||
const AskAiMemorySchema = Joi.object({
|
||||
enabled: Joi.bool().optional().default(false),
|
||||
userToken: Joi.string().optional(),
|
||||
|
|
@ -107,7 +57,7 @@ const SidePanelSchema = Joi.object({
|
|||
translations: Joi.object().optional().unknown(),
|
||||
hideButton: Joi.boolean().optional(),
|
||||
portalContainer: Joi.object().optional().unknown(),
|
||||
indices: Joi.array().items(AskAiIndexSchema).min(1).optional(),
|
||||
indices: Joi.array().items(Joi.string().min(1)).min(1).optional(),
|
||||
memory: AskAiMemorySchema.optional(),
|
||||
}).unknown(false);
|
||||
|
||||
|
|
@ -136,7 +86,7 @@ const AskAiSchema = Joi.object({
|
|||
searchParameters: Joi.object()
|
||||
.pattern(Joi.string(), SearchParametersSchema)
|
||||
.optional(),
|
||||
indices: Joi.array().items(AskAiIndexSchema).min(1).optional(),
|
||||
indices: Joi.array().items(Joi.string().min(1)).min(1).optional(),
|
||||
memory: AskAiMemorySchema.optional(),
|
||||
promptSuggestions: AskAiPromptSuggestionsSchema.optional(),
|
||||
}).unknown(false);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { DocSearch as DocSearchProvider, useDocSearch } from '@docsearch/core';
|
||||
import type { DocSearchRef, InitialAskAiMessage } from '@docsearch/core';
|
||||
import type { SearchParamsObject } from 'algoliasearch/lite';
|
||||
import React, { type JSX } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
|
|
@ -22,111 +21,6 @@ export type AgentStudioSearchParameters = Record<
|
|||
Omit<AskAiSearchParameters, 'facetFilters'>
|
||||
>;
|
||||
|
||||
interface IndexTextParam {
|
||||
exposed: boolean;
|
||||
default?: string;
|
||||
}
|
||||
|
||||
interface NumberConstraint {
|
||||
min?: number;
|
||||
max?: number;
|
||||
}
|
||||
|
||||
interface IndexNumberParam {
|
||||
exposed: boolean;
|
||||
default?: number;
|
||||
constraint?: NumberConstraint;
|
||||
}
|
||||
|
||||
interface StringArrayConstraints {
|
||||
values?: string[];
|
||||
}
|
||||
|
||||
interface IndexStringArrayParam {
|
||||
exposed: boolean;
|
||||
default?: string[];
|
||||
constraint?: StringArrayConstraints;
|
||||
merge?: boolean;
|
||||
}
|
||||
|
||||
interface IndexFacetParam {
|
||||
exposed: false;
|
||||
default?: string[];
|
||||
}
|
||||
|
||||
export interface AgentStudioSearchControls {
|
||||
/**
|
||||
* Augmented query for the MCP search tool to use.
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
query?: IndexTextParam;
|
||||
/**
|
||||
* Number of hits for the MCP to return per page.
|
||||
*
|
||||
* @default { exposed: false, default: 7 }
|
||||
*/
|
||||
hits_per_page?: IndexNumberParam;
|
||||
/**
|
||||
* The page number the MCP should pull results from.
|
||||
*
|
||||
* @default { exposed: false, default: 0 }
|
||||
*/
|
||||
page?: IndexNumberParam;
|
||||
/**
|
||||
* List of attributes that the MCP can retrieve from the index.
|
||||
*
|
||||
* @default { exposed: false, default: ['*'] }
|
||||
*/
|
||||
attributesToRetrieve?: IndexStringArrayParam;
|
||||
/**
|
||||
* List of fields that the MCP will return to the Agent.
|
||||
*
|
||||
* @default { exposed: false, default: ["hits", "nbHits", "page", "nbPages", "hitsPerPage", "facets"] }
|
||||
*/
|
||||
responseFields?: IndexStringArrayParam;
|
||||
/**
|
||||
* Defined facets the MCP will use when querying the index.
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
facets?: IndexFacetParam;
|
||||
/**
|
||||
* Any other custom properties the MCP should send when querying the index.
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
custom?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface AgentStudioIndices {
|
||||
/** The name of the index used by the search tool. */
|
||||
index: string;
|
||||
/** A brief description for the search tool. */
|
||||
description: string;
|
||||
/**
|
||||
* A description used to steer the agent on how/when to use the search tool.
|
||||
*
|
||||
* @default ''
|
||||
*/
|
||||
enhancedDescription?: string;
|
||||
/**
|
||||
* Default search parameters for the internal (non-MCP) search tool path.
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
searchParameters?: SearchParamsObject;
|
||||
/**
|
||||
* Structured search parameters for the MCP-based search tool path.
|
||||
*
|
||||
* Each parameter controls whether it is exposed to the LLM and it's default
|
||||
* value.
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
searchControls?: AgentStudioSearchControls;
|
||||
}
|
||||
|
||||
export interface Memory {
|
||||
/**
|
||||
* Determines whether or not to display the memory based tool calls.
|
||||
|
|
@ -182,8 +76,14 @@ export interface DocSearchAskAi {
|
|||
* }
|
||||
*/
|
||||
searchParameters?: AgentStudioSearchParameters;
|
||||
/** List of dynamic indices for the Agent Studio search tool to use. */
|
||||
indices?: AgentStudioIndices[];
|
||||
/**
|
||||
* Index names for the Agent Studio search tool on this request.
|
||||
*
|
||||
* Agent Studio expects names only. Put descriptions and tool defaults on the
|
||||
* agent configuration. Put per-index runtime overrides in
|
||||
* `searchParameters`.
|
||||
*/
|
||||
indices?: string[];
|
||||
/**
|
||||
* Use custom tools driven by Agent Studio.
|
||||
*
|
||||
|
|
@ -235,12 +135,7 @@ function DocSearchAIComponent(
|
|||
ref: React.ForwardedRef<DocSearchRef>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<DocSearchProvider
|
||||
{...props}
|
||||
appId={appId}
|
||||
apiKey={apiKey}
|
||||
ref={ref}
|
||||
>
|
||||
<DocSearchProvider {...props} appId={appId} apiKey={apiKey} ref={ref}>
|
||||
<DocSearchAIInner {...props} />
|
||||
</DocSearchProvider>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@ import type { JSX } from 'react';
|
|||
import React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
import type {
|
||||
AgentStudioIndices,
|
||||
AgentStudioSearchParameters,
|
||||
Memory,
|
||||
} from './DocSearchAI';
|
||||
import type { AgentStudioSearchParameters, Memory } from './DocSearchAI';
|
||||
import type {
|
||||
SidepanelButtonProps,
|
||||
SidepanelProps as SidepanelPanelProps,
|
||||
|
|
@ -77,8 +73,14 @@ export type DocSearchSidepanelProps = DocSearchCallbacks & {
|
|||
* @see https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/memory/overview
|
||||
*/
|
||||
memory?: Memory;
|
||||
/** List of dynamic indices for the Agent Studio search tool to use. */
|
||||
indices?: AgentStudioIndices[];
|
||||
/**
|
||||
* Index names for the Agent Studio search tool on this request.
|
||||
*
|
||||
* Agent Studio expects names only. Put descriptions and tool defaults on the
|
||||
* agent configuration. Put per-index runtime overrides in
|
||||
* `searchParameters`.
|
||||
*/
|
||||
indices?: string[];
|
||||
};
|
||||
|
||||
type SidepanelProps = DocSearchSidepanelProps & SidepanelSearchParameters;
|
||||
|
|
|
|||
|
|
@ -291,12 +291,7 @@ describe('useAskAi', () => {
|
|||
});
|
||||
|
||||
it('includes indices under the algolia body when provided', () => {
|
||||
const indices = [
|
||||
{
|
||||
index: 'docsearch-markdown',
|
||||
description: 'Use this to gather specific results.',
|
||||
},
|
||||
];
|
||||
const indices = ['docsearch-markdown'];
|
||||
|
||||
renderHook(() =>
|
||||
useAskAi({
|
||||
|
|
@ -317,12 +312,7 @@ describe('useAskAi', () => {
|
|||
const searchParameters = {
|
||||
'index-name': { distinct: false },
|
||||
};
|
||||
const indices = [
|
||||
{
|
||||
index: 'docsearch-markdown',
|
||||
description: 'Use this to gather specific results.',
|
||||
},
|
||||
];
|
||||
const indices = ['docsearch-markdown'];
|
||||
|
||||
renderHook(() =>
|
||||
useAskAi({
|
||||
|
|
@ -571,7 +561,7 @@ describe('useAskAi', () => {
|
|||
searchParameters: {
|
||||
'index-name': { distinct: false },
|
||||
},
|
||||
indices: [{ index: 'index-name', description: 'Test index' }],
|
||||
indices: ['index-name'],
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
@ -583,7 +573,7 @@ describe('useAskAi', () => {
|
|||
searchParameters: {
|
||||
'index-name': { distinct: false },
|
||||
},
|
||||
indices: [{ index: 'index-name', description: 'Test index' }],
|
||||
indices: ['index-name'],
|
||||
});
|
||||
|
||||
expect(result.current.startNewConversation).toBe(startNewConversation);
|
||||
|
|
|
|||
|
|
@ -20,12 +20,7 @@ import { type AIMessage, type ToolCalls } from './types/AskiAi';
|
|||
import type { OnAskAiFeedback } from './types/Feedback';
|
||||
import { EMPTY_TOOLS, sanitizeMessagesForRequest } from './utils/ai';
|
||||
|
||||
import type {
|
||||
AgentStudioIndices,
|
||||
AgentStudioSearchParameters,
|
||||
Memory,
|
||||
StoredAskAiState,
|
||||
} from '.';
|
||||
import type { AgentStudioSearchParameters, Memory, StoredAskAiState } from '.';
|
||||
|
||||
type UseChat = UseChatHelpers<AIMessage>;
|
||||
|
||||
|
|
@ -36,7 +31,7 @@ type UseAskAiParams = {
|
|||
searchParameters?: AgentStudioSearchParameters;
|
||||
tools: ToolCalls;
|
||||
memory?: Memory;
|
||||
indices?: AgentStudioIndices[];
|
||||
indices?: string[];
|
||||
};
|
||||
|
||||
type UseAskAiReturn = {
|
||||
|
|
@ -74,7 +69,7 @@ type AgentStudioTransportParams = Pick<
|
|||
> & {
|
||||
searchParameters?: AgentStudioSearchParameters;
|
||||
userToken?: string;
|
||||
indices?: AgentStudioIndices[];
|
||||
indices?: string[];
|
||||
};
|
||||
|
||||
const getAgentStudioTransport = ({
|
||||
|
|
@ -87,7 +82,7 @@ const getAgentStudioTransport = ({
|
|||
}: AgentStudioTransportParams): DefaultChatTransport<AIMessage> => {
|
||||
const algoliaParams: {
|
||||
searchParameters?: AgentStudioSearchParameters;
|
||||
indices?: AgentStudioIndices[];
|
||||
indices?: string[];
|
||||
} = {};
|
||||
|
||||
if (searchParameters) {
|
||||
|
|
|
|||
|
|
@ -3,14 +3,18 @@ title: Configure dynamic indices
|
|||
description: Select Agent Studio search indices dynamically at runtime.
|
||||
---
|
||||
|
||||
Pass `askAi.indices` when the Agent Studio search tool needs index definitions at request time. This lets your application choose indices, descriptions, fixed search parameters, and model-controlled parameters for each DocSearch instance.
|
||||
Pass `askAi.indices` when Agent Studio should search a specific set of indices for this request. This lets each DocSearch instance choose which indices the agent can use.
|
||||
|
||||
This property isn't the same as the top-level `indices` property:
|
||||
|
||||
- Top-level `indices` configures DocSearch keyword search. Entries are index names or objects with a `name` property.
|
||||
- `askAi.indices` configures Agent Studio search. Entries use an `index` property and require a `description`.
|
||||
- `askAi.indices` configures Agent Studio search. Entries are index name strings.
|
||||
|
||||
## Define an index
|
||||
Agent Studio completions accept index names only. Put index descriptions and tool defaults on the agent configuration in Agent Studio. Put per-index runtime overrides in `askAi.searchParameters`.
|
||||
|
||||
The agent's Algolia Search tool must use `mode: "dynamic"`. If the tool's static index list is empty, also enable `allowUnlistedIndices`.
|
||||
|
||||
## Select indices
|
||||
|
||||
```tsx title="Search.tsx"
|
||||
<DocSearchAI
|
||||
|
|
@ -18,123 +22,26 @@ This property isn't the same as the top-level `indices` property:
|
|||
apiKey="YOUR_SEARCH_API_KEY"
|
||||
indices={['docs']}
|
||||
askAi={{
|
||||
assistantId: 'YOUR_AGENT_ID',
|
||||
indices: [
|
||||
{
|
||||
index: 'docs_markdown',
|
||||
description: 'Published product documentation.',
|
||||
enhancedDescription:
|
||||
'Use this index for installation, configuration, and API questions.',
|
||||
searchParameters: {
|
||||
filters: 'visibility:public',
|
||||
attributesToRetrieve: ['title', 'content', 'url'],
|
||||
},
|
||||
searchControls: {
|
||||
query: { exposed: true },
|
||||
hits_per_page: {
|
||||
exposed: false,
|
||||
default: 7,
|
||||
constraint: { min: 1, max: 10 },
|
||||
},
|
||||
attributesToRetrieve: {
|
||||
exposed: false,
|
||||
default: ['title', 'content', 'url'],
|
||||
constraint: {
|
||||
values: ['title', 'content', 'url'],
|
||||
},
|
||||
},
|
||||
facets: {
|
||||
exposed: false,
|
||||
default: ['language', 'version'],
|
||||
},
|
||||
},
|
||||
agentId: 'YOUR_AGENT_ID',
|
||||
indices: ['docs_markdown', 'api_reference'],
|
||||
searchParameters: {
|
||||
docs_markdown: {
|
||||
filters: 'visibility:public',
|
||||
attributesToRetrieve: ['title', 'content', 'url'],
|
||||
},
|
||||
],
|
||||
api_reference: {
|
||||
distinct: false,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
Each index accepts these properties:
|
||||
### `indices`
|
||||
|
||||
### `index`
|
||||
> `type: string[]` | **optional**
|
||||
|
||||
> `type: string` | **required**
|
||||
|
||||
Names the Algolia index.
|
||||
|
||||
### `description`
|
||||
|
||||
> `type: string` | **required**
|
||||
|
||||
Tells the agent what the index contains.
|
||||
|
||||
### `enhancedDescription`
|
||||
|
||||
> `type: string` | **optional**
|
||||
|
||||
Gives the agent more guidance about when and how to use the index.
|
||||
|
||||
### `searchParameters`
|
||||
|
||||
> `type: SearchParamsObject` | **optional**
|
||||
|
||||
Sets defaults for the internal, non-MCP search path. It accepts Algolia search parameters.
|
||||
|
||||
### `searchControls`
|
||||
|
||||
> `type: AgentStudioSearchControls` | **optional**
|
||||
|
||||
Configures parameters for the MCP-based search path.
|
||||
|
||||
Write specific descriptions. Agent Studio uses them to select an index and plan a search. See [Algolia Search tool configuration](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/tools/algolia-search) for guidance.
|
||||
|
||||
## Configure search controls
|
||||
|
||||
A search control describes whether the model can provide a value and which default or constraints apply.
|
||||
|
||||
### `query`
|
||||
|
||||
> `type: { exposed, default? }` | **optional**
|
||||
|
||||
Sets the search query control. It has no DocSearch default when omitted.
|
||||
|
||||
### `hits_per_page`
|
||||
|
||||
> `type: { exposed, default?, constraint?: { min?, max? } }` | **optional**
|
||||
|
||||
Sets the number of results per page. When omitted, DocSearch uses `{ exposed: false, default: 7 }`.
|
||||
|
||||
### `page`
|
||||
|
||||
> `type: { exposed, default?, constraint?: { min?, max? } }` | **optional**
|
||||
|
||||
Sets the requested page. When omitted, DocSearch uses `{ exposed: false, default: 0 }`.
|
||||
|
||||
### `attributesToRetrieve`
|
||||
|
||||
> `type: { exposed, default?, constraint?: { values? }, merge? }` | **optional**
|
||||
|
||||
Sets the attributes returned for each hit. When omitted, DocSearch uses `{ exposed: false, default: ['*'] }`.
|
||||
|
||||
### `responseFields`
|
||||
|
||||
> `type: { exposed, default?, constraint?: { values? }, merge? }` | **optional**
|
||||
|
||||
Sets the fields returned in the search response. When omitted, DocSearch uses `{ exposed: false, default: ['hits', 'nbHits', 'page', 'nbPages', 'hitsPerPage', 'facets'] }`.
|
||||
|
||||
### `facets`
|
||||
|
||||
> `type: { exposed: false, default? }` | **optional**
|
||||
|
||||
Sets the facets requested with the search. It has no DocSearch default when omitted.
|
||||
|
||||
### `custom`
|
||||
|
||||
> `type: Record<string, unknown>` | **optional**
|
||||
|
||||
Sets extra tool parameters. It has no DocSearch default when omitted.
|
||||
|
||||
Use `exposed: true` only for values the model should choose from conversation context. Use fixed defaults for business rules and response limits. For the distinction between runtime and predefined parameters, see [Agent Studio tools](https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/tools/overview#configure-runtime-parameters-for-dynamic-tool-execution).
|
||||
Index names available to the Agent Studio search tool for this request. When omitted, Agent Studio uses the indices configured on the agent tool.
|
||||
|
||||
## Set request-wide search parameters
|
||||
|
||||
|
|
@ -142,7 +49,8 @@ Use `exposed: true` only for values the model should choose from conversation co
|
|||
|
||||
```js title="docsearch.js"
|
||||
askAi: {
|
||||
assistantId: 'YOUR_AGENT_ID',
|
||||
agentId: 'YOUR_AGENT_ID',
|
||||
indices: ['docs_markdown'],
|
||||
searchParameters: {
|
||||
docs_markdown: {
|
||||
filters: 'visibility:public',
|
||||
|
|
@ -153,10 +61,12 @@ askAi: {
|
|||
}
|
||||
```
|
||||
|
||||
Supported override fields are `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, `distinct`, `userToken`, `enablePersonalization`, `personalizationImpact`, and `optionalFilters`.
|
||||
|
||||
Don't use the flat search-parameter shape from earlier DocSearch AI integrations.
|
||||
|
||||
## Docusaurus validation
|
||||
|
||||
The v5 Docusaurus adapter requires at least one entry when you set `askAi.indices`. Every entry must include `index` and `description`. It rejects unknown `searchControls` properties, except values nested under `custom`.
|
||||
The v5 Docusaurus adapter requires at least one string when you set `askAi.indices`. Contextual search merges version/language filters into `askAi.searchParameters[index].filters` for each dynamic index name.
|
||||
|
||||
See the [React package reference](/docs/packages/react/api-reference) and [Docusaurus adapter guide](/docs/packages/docusaurus-adapter/getting-started) for the complete types.
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ The modal queries every index in array order. The search page queries only the f
|
|||
|
||||
Keep `contextualSearch: true` to limit results to the current locale and Docusaurus docs versions. The adapter merges these conditions into each index's `facetFilters` instead of replacing your filters.
|
||||
|
||||
Contextual search also applies to each `askAi.indices` item. Define dynamic Agent Studio indices if Ask AI must receive these facet filters.
|
||||
Contextual search also applies to Ask AI when you set `askAi.indices`. The adapter merges version and language filters into `askAi.searchParameters[index].filters` for each dynamic index name.
|
||||
|
||||
Set `contextualSearch: false` when your records don't contain Docusaurus `language` and `docusaurus_tag` attributes:
|
||||
|
||||
|
|
@ -322,30 +322,22 @@ Search parameters keyed by index name. Root `askAi.searchParameters` supports `f
|
|||
|
||||
### `indices`
|
||||
|
||||
> `type: AgentStudioIndex[]` | **optional**
|
||||
> `type: string[]` | **optional**
|
||||
|
||||
Dynamic indices available to Agent Studio search tools. See [dynamic indices][1].
|
||||
|
||||
Use `askAi.indices` to describe dynamic indices:
|
||||
Index names available to Agent Studio search tools. See [dynamic indices][1].
|
||||
|
||||
```js title="docusaurus.config.mjs"
|
||||
askAi: {
|
||||
assistantId: 'YOUR_ASSISTANT_ID',
|
||||
indices: [
|
||||
{
|
||||
index: 'docs_markdown',
|
||||
description: 'Product documentation.',
|
||||
enhancedDescription: 'Use for setup and API questions.',
|
||||
searchParameters: {
|
||||
facetFilters: ['language:en'],
|
||||
},
|
||||
agentId: 'YOUR_ASSISTANT_ID',
|
||||
indices: ['docs_markdown'],
|
||||
searchParameters: {
|
||||
docs_markdown: {
|
||||
filters: 'language:en',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
Each item requires `index` and `description`. It can also include `enhancedDescription`, `searchParameters`, and `searchControls`. Search controls can configure `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and custom properties.
|
||||
|
||||
### `memory`
|
||||
|
||||
> `type: { enabled?: boolean, userToken?: string }` | **optional**
|
||||
|
|
@ -441,7 +433,7 @@ Enable or disable the panel shortcut. The shortcut is enabled by default.
|
|||
|
||||
### `indices`
|
||||
|
||||
> `type: AgentStudioIndex[]` | **optional**
|
||||
> `type: string[]` | **optional**
|
||||
|
||||
Override Agent Studio indices for the panel. Defaults to `askAi.indices`. See [dynamic indices][1].
|
||||
|
||||
|
|
@ -607,9 +599,9 @@ The schema also reports these messages for missing or invalid required configura
|
|||
"docsearch.indices" must contain at least 1 items
|
||||
"docsearch.unknownKey" is not allowed
|
||||
"docsearch.askAi.indices" must contain at least 1 items
|
||||
"docsearch.askAi.indices[0].description" is required
|
||||
"docsearch.askAi.indices[0]" must be a string
|
||||
"docsearch.sidePanel.indices" must contain at least 1 items
|
||||
"docsearch.sidePanel.indices[0].description" is required
|
||||
"docsearch.sidePanel.indices[0]" must be a string
|
||||
```
|
||||
|
||||
Replace `unknownKey` with the rejected option name. Other invalid nested values use the same Joi path format.
|
||||
|
|
|
|||
|
|
@ -192,13 +192,8 @@ askAi: 'YOUR_ASSISTANT_ID',
|
|||
|
||||
```js title="docusaurus.config.mjs"
|
||||
askAi: {
|
||||
assistantId: 'YOUR_ASSISTANT_ID',
|
||||
indices: [
|
||||
{
|
||||
index: 'docs_markdown',
|
||||
description: 'Product documentation.',
|
||||
},
|
||||
],
|
||||
agentId: 'YOUR_ASSISTANT_ID',
|
||||
indices: ['docs_markdown'],
|
||||
},
|
||||
```
|
||||
|
||||
|
|
@ -240,7 +235,7 @@ askAi: {
|
|||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Root `askAi.searchParameters` supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`. Put `facetFilters` on a dynamic `askAi.indices` item's `searchParameters` instead.
|
||||
Root `askAi.searchParameters` supports `filters`, `attributesToRetrieve`, `restrictSearchableAttributes`, and `distinct`.
|
||||
|
||||
## 7. Move the Sidepanel to the root
|
||||
|
||||
|
|
|
|||
|
|
@ -387,35 +387,21 @@ askAi: {
|
|||
|
||||
#### `indices`
|
||||
|
||||
> `type: AgentStudioIndices[]` | **optional**
|
||||
> `type: string[]` | **optional**
|
||||
|
||||
Dynamic indices available to the Agent Studio search tool. There's no default.
|
||||
Index names for the Agent Studio search tool on this request. There's no default.
|
||||
|
||||
Each `AgentStudioIndices` item requires `index` and `description`. It can also define `enhancedDescription`, `searchParameters`, and `searchControls`.
|
||||
|
||||
`searchControls` supports `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and `custom`. The `exposed` flag controls whether the model can set a value. Constraints set allowed numeric ranges or string-array values.
|
||||
Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in `searchParameters`.
|
||||
|
||||
```js title="docsearch-options.js"
|
||||
askAi: {
|
||||
assistantId: 'YOUR_ASSISTANT_ID',
|
||||
indices: [
|
||||
{
|
||||
index: 'api_reference',
|
||||
description: 'API symbols and parameter reference',
|
||||
enhancedDescription: 'Use for questions about methods and options.',
|
||||
searchControls: {
|
||||
hits_per_page: {
|
||||
exposed: true,
|
||||
default: 7,
|
||||
constraint: { min: 1, max: 10 },
|
||||
},
|
||||
facets: {
|
||||
exposed: false,
|
||||
default: ['version'],
|
||||
},
|
||||
},
|
||||
agentId: 'YOUR_ASSISTANT_ID',
|
||||
indices: ['api_reference', 'docs_markdown'],
|
||||
searchParameters: {
|
||||
api_reference: {
|
||||
filters: 'version:latest',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -251,9 +251,9 @@ Sends search parameters keyed by index name. `AgentStudioIndexSearchParameters`
|
|||
|
||||
### `indices`
|
||||
|
||||
> `type: AgentStudioIndices[]` | **optional**
|
||||
> `type: string[]` | **optional**
|
||||
|
||||
Defines dynamic indices available to Agent Studio search tools.
|
||||
Index names available to Agent Studio search tools. Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in `searchParameters`.
|
||||
|
||||
### `tools`
|
||||
|
||||
|
|
@ -273,40 +273,6 @@ Displays memory tool activity and sends a secure user token.
|
|||
|
||||
Configures prompt suggestions in keyword search. `hitsPerPage` defaults to `3`.
|
||||
|
||||
## Dynamic indices
|
||||
|
||||
Each dynamic index accepts the following fields:
|
||||
|
||||
### `index`
|
||||
|
||||
> `type: string` | **required**
|
||||
|
||||
Index available to Agent Studio search tools.
|
||||
|
||||
### `description`
|
||||
|
||||
> `type: string` | **required**
|
||||
|
||||
Describes the index contents to Agent Studio.
|
||||
|
||||
### `enhancedDescription`
|
||||
|
||||
> `type: string` | **optional**
|
||||
|
||||
Provides more context about the index contents.
|
||||
|
||||
### `searchParameters`
|
||||
|
||||
> `type: SearchParamsObject` | **optional**
|
||||
|
||||
Sets search parameters for the dynamic index.
|
||||
|
||||
### `searchControls`
|
||||
|
||||
> `type: AgentStudioSearchControls` | **optional**
|
||||
|
||||
Configures `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and `custom` controls. Text, number, and string-array controls use an `exposed` flag and can define defaults or constraints.
|
||||
|
||||
## Custom tools
|
||||
|
||||
Each `ToolDefinition` accepts the following fields:
|
||||
|
|
|
|||
|
|
@ -310,11 +310,9 @@ Search parameters keyed by index name. Each value supports `filters`, `attribute
|
|||
|
||||
#### `indices`
|
||||
|
||||
> `type: AgentStudioIndices[]` | **optional**
|
||||
> `type: string[]` | **optional**
|
||||
|
||||
Dynamic indices for Agent Studio. Each item requires `index` and `description`. It can also define `enhancedDescription`, `searchParameters`, and `searchControls`.
|
||||
|
||||
`searchControls` supports `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and `custom`.
|
||||
Index names for the Agent Studio search tool on this request. Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in `searchParameters`.
|
||||
|
||||
#### `tools`
|
||||
|
||||
|
|
|
|||
|
|
@ -195,28 +195,17 @@ See [Get started with Agent Studio](/docs/agent-studio/getting-started) before c
|
|||
|
||||
## Add dynamic Agent Studio indices
|
||||
|
||||
Describe each index so the agent can select the right source:
|
||||
Pass the index names Agent Studio should search for this request:
|
||||
|
||||
```jsx title="DynamicIndicesSearch.jsx"
|
||||
const askAi = {
|
||||
assistantId: 'YOUR_ASSISTANT_ID',
|
||||
indices: [
|
||||
{
|
||||
index: 'product_docs',
|
||||
description: 'Product guides and conceptual documentation',
|
||||
searchControls: {
|
||||
hits_per_page: {
|
||||
exposed: true,
|
||||
default: 7,
|
||||
constraint: { min: 1, max: 10 },
|
||||
},
|
||||
},
|
||||
agentId: 'YOUR_ASSISTANT_ID',
|
||||
indices: ['product_docs', 'api_reference'],
|
||||
searchParameters: {
|
||||
product_docs: {
|
||||
filters: 'language:en',
|
||||
},
|
||||
{
|
||||
index: 'api_reference',
|
||||
description: 'API symbols, options, and return values',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
<DocSearchAI
|
||||
|
|
|
|||
|
|
@ -124,9 +124,9 @@ Configures memory-tool rendering and authentication.
|
|||
|
||||
### `indices`
|
||||
|
||||
> `type: AgentStudioIndices[]` | **optional**
|
||||
> `type: string[]` | **optional**
|
||||
|
||||
Defines dynamic indices available to Agent Studio.
|
||||
Index names available to Agent Studio. Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in `searchParameters`.
|
||||
|
||||
These fields are root props:
|
||||
|
||||
|
|
@ -141,16 +141,11 @@ const assistant = sidepanel({
|
|||
enabled: true,
|
||||
userToken: userMemoryToken,
|
||||
},
|
||||
indices: [
|
||||
{
|
||||
index: 'docs',
|
||||
description: 'Product documentation and API references.',
|
||||
},
|
||||
{
|
||||
index: 'support_articles',
|
||||
description: 'Troubleshooting and support articles.',
|
||||
},
|
||||
],
|
||||
indices: ['docs', 'support_articles'],
|
||||
searchParameters: {
|
||||
docs: { filters: 'version:v5' },
|
||||
support_articles: { filters: 'visibility:public' },
|
||||
},
|
||||
tools: {
|
||||
getReleaseChannel: {
|
||||
async onToolCall({ input, addToolOutput }) {
|
||||
|
|
@ -165,8 +160,6 @@ const assistant = sidepanel({
|
|||
});
|
||||
```
|
||||
|
||||
`AgentStudioIndices` requires `index` and `description`. It also accepts `enhancedDescription`, `searchParameters`, and `searchControls`.
|
||||
|
||||
`ToolDefinition` requires `render({ message: { input, output } })`, which returns a string. It can also define `onToolCall` and `translations.callingToolText`. If you handle a client-side tool, call `addToolOutput`.
|
||||
|
||||
Generate `memory.userToken` on your server. The package sends it as `x-algolia-secure-user-token`.
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ Don't generate or sign the token in the browser.
|
|||
|
||||
## Provide dynamic indices
|
||||
|
||||
Use `indices` to describe the indices Agent Studio can select at request time. This list is separate from the required `indexName`, which remains the Sidepanel's primary index.
|
||||
Use `indices` to select the indices Agent Studio can search at request time. This list is separate from the required `indexName`, which remains the Sidepanel's primary index.
|
||||
|
||||
```tsx title="DynamicIndices.tsx"
|
||||
<Sidepanel
|
||||
|
|
@ -145,17 +145,7 @@ Use `indices` to describe the indices Agent Studio can select at request time. T
|
|||
docs: { filters: 'version:v5' },
|
||||
support_articles: { filters: 'visibility:public' },
|
||||
}}
|
||||
indices={[
|
||||
{
|
||||
index: 'docs',
|
||||
description: 'Product documentation and API references.',
|
||||
},
|
||||
{
|
||||
index: 'support_articles',
|
||||
description: 'Troubleshooting and support articles.',
|
||||
enhancedDescription: 'Use for errors and operational incidents.',
|
||||
},
|
||||
]}
|
||||
indices={['docs', 'support_articles']}
|
||||
/>
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -116,9 +116,9 @@ Configures Agent Studio memory rendering and authentication.
|
|||
|
||||
#### `indices`
|
||||
|
||||
> `type: AgentStudioIndices[]` | **optional**
|
||||
> `type: string[]` | **optional**
|
||||
|
||||
Defines dynamic indices available to Agent Studio.
|
||||
Index names available to Agent Studio. Put descriptions and tool defaults on the agent configuration. Put per-index runtime overrides in `searchParameters`.
|
||||
|
||||
### Translation groups
|
||||
|
||||
|
|
@ -134,20 +134,6 @@ Defines dynamic indices available to Agent Studio.
|
|||
|
||||
V5 uses Agent Studio for Sidepanel conversations. It doesn't expose an `agentStudio` prop.
|
||||
|
||||
### `AgentStudioIndices`
|
||||
|
||||
```ts
|
||||
interface AgentStudioIndices {
|
||||
index: string;
|
||||
description: string;
|
||||
enhancedDescription?: string;
|
||||
searchParameters?: SearchParamsObject;
|
||||
searchControls?: AgentStudioSearchControls;
|
||||
}
|
||||
```
|
||||
|
||||
`searchControls` accepts `query`, `hits_per_page`, `page`, `attributesToRetrieve`, `responseFields`, `facets`, and `custom`. Controls specify whether Agent Studio may expose a value to the model and can include defaults and constraints.
|
||||
|
||||
### `ToolDefinition`
|
||||
|
||||
```ts
|
||||
|
|
|
|||
|
|
@ -228,7 +228,8 @@ These additions aren't breaking by themselves, but they replace common v4 custom
|
|||
- `facets` and `DocSearchFacet` for keyword filters.
|
||||
- `resultBadgeKey` for hit metadata.
|
||||
- `DocSearchAI` and `DocSearchAskAiModal` for AI-capable React views.
|
||||
- `AgentStudioIndices` and `AgentStudioSearchControls` for dynamic search tools.
|
||||
- `askAi.indices` (`string[]`) for dynamic Agent Studio search indices.
|
||||
- `askAi.searchParameters` for per-index runtime search overrides.
|
||||
- `ToolCalls` and `ToolDefinition` for custom Agent Studio tools.
|
||||
- `Memory` for user-scoped Agent Studio memory.
|
||||
- `PromptSuggestions` for keyword-query prompt suggestions.
|
||||
|
|
|
|||
Loading…
Reference in a new issue