Skip to content

Commit 3ce0d23

Browse files
teallarsonclaude
andauthored
fix(algolia): push initialIndexSettings to live indices on sync (#1182)
The crawler's `initialIndexSettings` block is only applied when the crawler *creates* an index. After the July change to relax `removeWordsIfNoResults` for compound agent queries, the setting never reached the existing production index, and long/keyword-heavy queries kept returning zero results (23–27% no-result rate in recent weekly reports; e.g. "connect mcp client gateway streamable http configuration" returns nothing even though the MCP Gateways page covers every term except "configuration"). `scripts/sync-crawler-config.ts` now also pushes `initialIndexSettings` to each named index via the Search API's PUT /1/indexes/{name}/settings when `ALGOLIA_ADMIN_API_KEY` is available. Without the key the crawler config still syncs and a reindex still runs; the settings push is skipped with a warning so the workflow keeps working before the new secret is added. Claude-Session: https://claude.ai/code/session_01Wef2YCphN88CRNuqCoefUU Co-authored-by: Claude <noreply@anthropic.com>
1 parent c8decdf commit 3ce0d23

4 files changed

Lines changed: 69 additions & 0 deletions

File tree

‎.github/workflows/sync-crawler-config.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ name: Sync Algolia crawler config
1212
# - Variable ALGOLIA_CRAWLER_ID
1313
# - Secret ALGOLIA_CRAWLER_USER_ID
1414
# - Secret ALGOLIA_CRAWLER_API_KEY
15+
# - Secret ALGOLIA_ADMIN_API_KEY (optional — needed to push
16+
# initialIndexSettings to existing indices, since the crawler
17+
# only applies them on index creation)
1518

1619
on:
1720
push:
@@ -42,6 +45,7 @@ jobs:
4245
ALGOLIA_CRAWLER_ID: ${{ vars.ALGOLIA_CRAWLER_ID }}
4346
ALGOLIA_CRAWLER_USER_ID: ${{ secrets.ALGOLIA_CRAWLER_USER_ID }}
4447
ALGOLIA_CRAWLER_API_KEY: ${{ secrets.ALGOLIA_CRAWLER_API_KEY }}
48+
ALGOLIA_ADMIN_API_KEY: ${{ secrets.ALGOLIA_ADMIN_API_KEY }}
4549
# On push, skip the reindex here — algolia-reindex.yml fires after the
4650
# Vercel production deploy so pages are live before the crawl starts.
4751
# On workflow_dispatch there is no pending deploy, so reindex immediately.

‎algolia/README.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,20 @@ dashboard and in CI secrets. The workflows need:
5050
| `ALGOLIA_CRAWLER_ID` | Variable | Crawler dashboard URL |
5151
| `ALGOLIA_CRAWLER_USER_ID` | Secret | Crawler → API credentials |
5252
| `ALGOLIA_CRAWLER_API_KEY` | Secret | Crawler → API credentials |
53+
| `ALGOLIA_ADMIN_API_KEY` | Secret | Algolia dashboard → API Keys → Admin API Key |
54+
55+
### Why `ALGOLIA_ADMIN_API_KEY` is needed
56+
57+
The crawler's `initialIndexSettings` block is only applied when the crawler
58+
*creates* an index. Once the production index exists, later edits to that
59+
block (for example, tuning `removeWordsIfNoResults` to relax matching for
60+
long agent-style queries) never reach the live index through the crawler
61+
API alone, and the no-result rate stays elevated for those queries.
62+
63+
`scripts/sync-crawler-config.ts` therefore also pushes `initialIndexSettings`
64+
to each live index via the Search API's `PUT /1/indexes/{name}/settings`
65+
using this key. Without the key the config still syncs and a reindex still
66+
runs, but the index-settings step is skipped with a warning.
5367

5468
The public search credentials used by the frontend widget
5569
(`app/_components/algolia-search.tsx`) are separate `NEXT_PUBLIC_ALGOLIA_*`

‎algolia/crawler-config.js‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ export const crawlerConfig = {
6363
},
6464
},
6565
],
66+
// The crawler applies `initialIndexSettings` only when it *creates* an
67+
// index, so edits below never reach an existing production index by
68+
// themselves. `scripts/sync-crawler-config.ts` also pushes these via the
69+
// Search API when ALGOLIA_ADMIN_API_KEY is set; see algolia/README.md.
6670
initialIndexSettings: {
6771
docs_arcade_dev_bjb8pbsq9t_docsearch: {
6872
distinct: true,

‎scripts/sync-crawler-config.ts‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,20 @@
1212
* here (the config file doesn't store it either). Updating config doesn't crawl
1313
* on its own, so we POST /reindex afterwards to apply the new config.
1414
*
15+
* `initialIndexSettings` in the crawler config only applies when the crawler
16+
* *creates* the index — it is not re-applied to an existing index on subsequent
17+
* crawls. To keep the live production index in sync with the versioned settings,
18+
* we also push them via the Search API's PUT /1/indexes/{name}/settings when
19+
* ALGOLIA_ADMIN_API_KEY is available. Without that key, we skip with a warning
20+
* and the crawler config still updates normally.
21+
*
1522
* Requires these env vars (provided as CI secrets/variables):
1623
* ALGOLIA_CRAWLER_ID
1724
* ALGOLIA_CRAWLER_USER_ID
1825
* ALGOLIA_CRAWLER_API_KEY
26+
*
27+
* Optional:
28+
* ALGOLIA_ADMIN_API_KEY (needed to apply index settings to existing indices)
1929
*/
2030

2131
import { Buffer } from "node:buffer";
@@ -24,6 +34,7 @@ import { crawlerConfig } from "../algolia/crawler-config.js";
2434
const CRAWLER_ID = process.env.ALGOLIA_CRAWLER_ID;
2535
const USER_ID = process.env.ALGOLIA_CRAWLER_USER_ID;
2636
const API_KEY = process.env.ALGOLIA_CRAWLER_API_KEY;
37+
const ADMIN_API_KEY = process.env.ALGOLIA_ADMIN_API_KEY;
2738

2839
if (!(CRAWLER_ID && USER_ID && API_KEY)) {
2940
console.error(
@@ -64,6 +75,42 @@ if (!configResponse.ok) {
6475
}
6576
console.log("Crawler config updated.");
6677

78+
// Push initialIndexSettings to each live index via the Search API. The crawler
79+
// only applies these when the index is first created, so a settings change
80+
// (e.g. removeWordsIfNoResults) never reaches an existing production index
81+
// otherwise, and no-result rates stay high for compound agent queries.
82+
if (ADMIN_API_KEY) {
83+
const settingsByIndex = crawlerConfig.initialIndexSettings ?? {};
84+
for (const [indexName, settings] of Object.entries(settingsByIndex)) {
85+
const response = await fetch(
86+
`https://${crawlerConfig.appId}-dsn.algolia.net/1/indexes/${encodeURIComponent(indexName)}/settings`,
87+
{
88+
method: "PUT",
89+
headers: {
90+
"X-Algolia-Application-Id": crawlerConfig.appId,
91+
"X-Algolia-API-Key": ADMIN_API_KEY,
92+
"Content-Type": "application/json",
93+
},
94+
body: JSON.stringify(settings),
95+
}
96+
);
97+
if (!response.ok) {
98+
console.error(
99+
`Index settings update failed for ${indexName} (${response.status}): ${await response.text()}`
100+
);
101+
process.exit(1);
102+
}
103+
console.log(`Index settings pushed to ${indexName}.`);
104+
}
105+
} else {
106+
console.warn(
107+
"ALGOLIA_ADMIN_API_KEY not set — skipping Search API settings push. " +
108+
"The crawler's initialIndexSettings only apply on index creation, so " +
109+
"changes to those fields will not reach the existing production index " +
110+
"until this key is provided. See algolia/README.md."
111+
);
112+
}
113+
67114
if (process.env.SKIP_REINDEX === "true") {
68115
console.log("Skipping reindex — will be triggered after deployment.");
69116
process.exit(0);

0 commit comments

Comments
 (0)