1
0
Fork 0

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:
Felipe Bermudez 2026-08-05 16:37:25 -05:00 committed by GitHub
parent 3f74c33d45
commit fe4d0c29f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 146 additions and 517 deletions

View 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.

View file

@ -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'
);
});

View file

@ -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,
};
}

View file

@ -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'];
};

View file

@ -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);

View file

@ -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>
);

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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',
},
],
},
}
```

View file

@ -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:

View file

@ -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`

View file

@ -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

View file

@ -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`.

View file

@ -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']}
/>
```

View file

@ -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

View file

@ -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.