From a38c74db030d53d6505b033da79abadb2c8ed917 Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 1 Jul 2026 23:45:27 -0700 Subject: [PATCH 1/8] fix(algolia): fix serialization-time param mutation, add geo/facet search, task status tool - move all tools.config coercion/remapping out of tool() into a proper params() function so dynamic block references aren't destroyed before variable resolution - wire facets and getRankingInfo into the search tool so those documented outputs are actually reachable - add geo-search (aroundLatLng/aroundRadius/insideBoundingBox/insidePolygon) to search and browse_records, matching delete_by_filter - fix aroundRadius param type (string, not number, since it accepts "all") - sync batch_operations description with the real action set (delete, clear) - consolidate list_indices pagination into the shared page/hitsPerPage fields instead of duplicate listPage/listHitsPerPage - add algolia_get_task_status tool so workflows can poll a taskID instead of guessing when a write is applied - trim indexName/objectID/destination before building request URLs - add ranking-tuning and index-snapshot skills to AlgoliaBlockMeta fix(dropcontact): swap icon to the official wordmark's teal swirl mark, bgColor to match chore(grafana): bgColor to white to match brand tile convention --- apps/docs/components/icons.tsx | 14 +- .../content/docs/en/integrations/algolia.mdx | 34 ++++- .../docs/en/integrations/dropcontact.mdx | 2 +- .../content/docs/en/integrations/grafana.mdx | 2 +- apps/sim/blocks/blocks/algolia.ts | 123 ++++++++++++------ apps/sim/blocks/blocks/dropcontact.ts | 2 +- apps/sim/blocks/blocks/grafana.ts | 2 +- apps/sim/components/icons.tsx | 14 +- apps/sim/lib/integrations/integrations.json | 12 +- apps/sim/tools/algolia/add_record.ts | 4 +- apps/sim/tools/algolia/batch_operations.ts | 4 +- apps/sim/tools/algolia/browse_records.ts | 43 +++++- apps/sim/tools/algolia/clear_records.ts | 2 +- apps/sim/tools/algolia/copy_move_index.ts | 4 +- apps/sim/tools/algolia/delete_by_filter.ts | 4 +- apps/sim/tools/algolia/delete_index.ts | 2 +- apps/sim/tools/algolia/delete_record.ts | 2 +- apps/sim/tools/algolia/get_record.ts | 2 +- apps/sim/tools/algolia/get_settings.ts | 2 +- apps/sim/tools/algolia/get_task_status.ts | 75 +++++++++++ apps/sim/tools/algolia/index.ts | 2 + .../tools/algolia/partial_update_record.ts | 2 +- apps/sim/tools/algolia/search.ts | 58 +++++++++ apps/sim/tools/algolia/types.ts | 23 ++++ apps/sim/tools/algolia/update_settings.ts | 2 +- apps/sim/tools/registry.ts | 2 + 26 files changed, 356 insertions(+), 82 deletions(-) create mode 100644 apps/sim/tools/algolia/get_task_status.ts diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index 58d2124d7b3..259fd03dfeb 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -7985,18 +7985,16 @@ export function LeadMagicIcon(props: SVGProps) { ) } -/** Dropcontact brand icon: teal disc with the white open-"d" contact mark. */ +/** Dropcontact brand icon: the teal swirl mark from the official wordmark. */ export function DropcontactIcon(props: SVGProps) { return ( - - + - ) } diff --git a/apps/docs/content/docs/en/integrations/algolia.mdx b/apps/docs/content/docs/en/integrations/algolia.mdx index 29c6725e6e7..17e262acb84 100644 --- a/apps/docs/content/docs/en/integrations/algolia.mdx +++ b/apps/docs/content/docs/en/integrations/algolia.mdx @@ -50,6 +50,12 @@ Search an Algolia index | `page` | number | No | Page number to retrieve \(default: 0\) | | `filters` | string | No | Filter string \(e.g., "category:electronics AND price < 100"\) | | `attributesToRetrieve` | string | No | Comma-separated list of attributes to retrieve | +| `facets` | string | No | Comma-separated list of facet attribute names to retrieve counts for \(use "*" for all\) | +| `getRankingInfo` | boolean | No | Whether to include detailed ranking information in each hit | +| `aroundLatLng` | string | No | Coordinates for geo-search \(e.g., "40.71,-74.01"\) | +| `aroundRadius` | string | No | Maximum radius in meters for geo-search, or "all" for unlimited | +| `insideBoundingBox` | json | No | Bounding box coordinates as \[\[lat1, lng1, lat2, lng2\]\] for geo-search | +| `insidePolygon` | json | No | Polygon coordinates as \[\[lat1, lng1, lat2, lng2, lat3, lng3, ...\]\] for geo-search | #### Output @@ -200,6 +206,10 @@ Browse and iterate over all records in an Algolia index using cursor pagination | `attributesToRetrieve` | string | No | Comma-separated list of attributes to retrieve | | `hitsPerPage` | number | No | Number of hits per page \(default: 1000, max: 1000\) | | `cursor` | string | No | Cursor from a previous browse response for pagination | +| `aroundLatLng` | string | No | Coordinates for geo-search \(e.g., "40.71,-74.01"\) | +| `aroundRadius` | string | No | Maximum radius in meters for geo-search, or "all" for unlimited | +| `insideBoundingBox` | json | No | Bounding box coordinates as \[\[lat1, lng1, lat2, lng2\]\] for geo-search | +| `insidePolygon` | json | No | Polygon coordinates as \[\[lat1, lng1, lat2, lng2, lat3, lng3, ...\]\] for geo-search | #### Output @@ -225,7 +235,7 @@ Perform batch add, update, partial update, or delete operations on records in an | `applicationId` | string | Yes | Algolia Application ID | | `apiKey` | string | Yes | Algolia Admin API Key | | `indexName` | string | Yes | Name of the Algolia index | -| `requests` | json | Yes | Array of batch operations. Each item has "action" \(addObject, updateObject, partialUpdateObject, partialUpdateObjectNoCreate, deleteObject\) and "body" \(the record data, must include objectID for update/delete\) | +| `requests` | json | Yes | Array of batch operations. Each item has "action" \(addObject, updateObject, partialUpdateObject, partialUpdateObjectNoCreate, deleteObject, delete, clear\) and "body" \(the record data, must include objectID for update/delete; omit body for delete/clear\) | #### Output @@ -390,7 +400,7 @@ Delete all records matching a filter from an Algolia index | `numericFilters` | json | No | Array of numeric filters \(e.g., \["price > 100"\]\) | | `tagFilters` | json | No | Array of tag filters using the _tags attribute \(e.g., \["published"\]\) | | `aroundLatLng` | string | No | Coordinates for geo-search filter \(e.g., "40.71,-74.01"\) | -| `aroundRadius` | number | No | Maximum radius in meters for geo-search, or "all" for unlimited | +| `aroundRadius` | string | No | Maximum radius in meters for geo-search, or "all" for unlimited | | `insideBoundingBox` | json | No | Bounding box coordinates as \[\[lat1, lng1, lat2, lng2\]\] for geo-search filter | | `insidePolygon` | json | No | Polygon coordinates as \[\[lat1, lng1, lat2, lng2, lat3, lng3, ...\]\] for geo-search filter | @@ -401,4 +411,24 @@ Delete all records matching a filter from an Algolia index | `taskID` | number | Algolia task ID for tracking the delete-by-filter operation | | `updatedAt` | string | Timestamp when the operation was performed | +### `algolia_get_task_status` + +Check whether an Algolia indexing task has finished publishing + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `applicationId` | string | Yes | Algolia Application ID | +| `apiKey` | string | Yes | Algolia API Key | +| `indexName` | string | Yes | Name of the Algolia index the task ran against | +| `taskID` | number | Yes | The taskID returned by a previous write operation | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `status` | string | Task status: "published" once the operation has been applied, "notPublished" while still pending | +| `pendingTask` | boolean | Whether the task is still pending | + diff --git a/apps/docs/content/docs/en/integrations/dropcontact.mdx b/apps/docs/content/docs/en/integrations/dropcontact.mdx index 1f5cf1c8f29..b4ec2126cb2 100644 --- a/apps/docs/content/docs/en/integrations/dropcontact.mdx +++ b/apps/docs/content/docs/en/integrations/dropcontact.mdx @@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" {/* MANUAL-CONTENT-START:intro */} diff --git a/apps/docs/content/docs/en/integrations/grafana.mdx b/apps/docs/content/docs/en/integrations/grafana.mdx index 103d69dc265..5bb28062b23 100644 --- a/apps/docs/content/docs/en/integrations/grafana.mdx +++ b/apps/docs/content/docs/en/integrations/grafana.mdx @@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" {/* MANUAL-CONTENT-START:intro */} diff --git a/apps/sim/blocks/blocks/algolia.ts b/apps/sim/blocks/blocks/algolia.ts index be4edae15f3..4940fc43158 100644 --- a/apps/sim/blocks/blocks/algolia.ts +++ b/apps/sim/blocks/blocks/algolia.ts @@ -37,6 +37,7 @@ export const AlgoliaBlock: BlockConfig = { { label: 'Copy/Move Index', id: 'copy_move_index' }, { label: 'Clear Records', id: 'clear_records' }, { label: 'Delete By Filter', id: 'delete_by_filter' }, + { label: 'Get Task Status', id: 'get_task_status' }, ], value: () => 'search', }, @@ -63,7 +64,7 @@ export const AlgoliaBlock: BlockConfig = { title: 'Hits Per Page', type: 'short-input', placeholder: '20', - condition: { field: 'operation', value: ['search', 'browse_records'] }, + condition: { field: 'operation', value: ['search', 'browse_records', 'list_indices'] }, mode: 'advanced', }, { @@ -71,7 +72,7 @@ export const AlgoliaBlock: BlockConfig = { title: 'Page', type: 'short-input', placeholder: '0', - condition: { field: 'operation', value: 'search' }, + condition: { field: 'operation', value: ['search', 'list_indices'] }, mode: 'advanced', }, { @@ -108,6 +109,26 @@ Return ONLY the filter string, no quotes or explanation.`, condition: { field: 'operation', value: ['search', 'get_record', 'browse_records'] }, mode: 'advanced', }, + { + id: 'facets', + title: 'Facets', + type: 'short-input', + placeholder: 'category,brand (or * for all)', + condition: { field: 'operation', value: 'search' }, + mode: 'advanced', + }, + { + id: 'getRankingInfo', + title: 'Include Ranking Info', + type: 'dropdown', + options: [ + { label: 'No', id: 'false' }, + { label: 'Yes', id: 'true' }, + ], + value: () => 'false', + condition: { field: 'operation', value: 'search' }, + mode: 'advanced', + }, // Browse cursor { id: 'cursor', @@ -389,7 +410,7 @@ Return ONLY the filter string, no quotes or explanation.`, title: 'Around Lat/Lng', type: 'short-input', placeholder: '40.71,-74.01', - condition: { field: 'operation', value: 'delete_by_filter' }, + condition: { field: 'operation', value: ['delete_by_filter', 'search', 'browse_records'] }, mode: 'advanced', }, { @@ -397,7 +418,7 @@ Return ONLY the filter string, no quotes or explanation.`, title: 'Around Radius (m)', type: 'short-input', placeholder: '1000 or "all"', - condition: { field: 'operation', value: 'delete_by_filter' }, + condition: { field: 'operation', value: ['delete_by_filter', 'search', 'browse_records'] }, mode: 'advanced', }, { @@ -405,7 +426,7 @@ Return ONLY the filter string, no quotes or explanation.`, title: 'Inside Bounding Box', type: 'short-input', placeholder: '[[47.3165,0.757,47.3424,0.8012]]', - condition: { field: 'operation', value: 'delete_by_filter' }, + condition: { field: 'operation', value: ['delete_by_filter', 'search', 'browse_records'] }, mode: 'advanced', }, { @@ -413,7 +434,7 @@ Return ONLY the filter string, no quotes or explanation.`, title: 'Inside Polygon', type: 'short-input', placeholder: '[[47.3165,0.757,47.3424,0.8012,47.33,0.78]]', - condition: { field: 'operation', value: 'delete_by_filter' }, + condition: { field: 'operation', value: ['delete_by_filter', 'search', 'browse_records'] }, mode: 'advanced', }, // Get records (batch) field @@ -447,22 +468,14 @@ Return ONLY the JSON array.`, generationType: 'json-object', }, }, - // List indices pagination + // Get task status field { - id: 'listPage', - title: 'Page', - type: 'short-input', - placeholder: '0', - condition: { field: 'operation', value: 'list_indices' }, - mode: 'advanced', - }, - { - id: 'listHitsPerPage', - title: 'Indices Per Page', + id: 'taskID', + title: 'Task ID', type: 'short-input', - placeholder: '100', - condition: { field: 'operation', value: 'list_indices' }, - mode: 'advanced', + placeholder: '12345', + condition: { field: 'operation', value: 'get_task_status' }, + required: { field: 'operation', value: 'get_task_status' }, }, // Object ID - for add (optional), get, partial update, delete { @@ -515,32 +528,42 @@ Return ONLY the JSON array.`, 'algolia_copy_move_index', 'algolia_clear_records', 'algolia_delete_by_filter', + 'algolia_get_task_status', ], config: { - tool: (params: Record) => { - const op = params.operation as string - if (op === 'partial_update_record') { - params.createIfNotExists = params.createIfNotExists !== 'false' + tool: (params: Record) => `algolia_${params.operation}`, + params: (params: Record) => { + const { operation, ...rest } = params + const result: Record = {} + + for (const [key, value] of Object.entries(rest)) { + if (value === undefined || value === null || value === '') continue + result[key] = value } - if (op === 'update_settings' && params.forwardToReplicas === 'true') { - params.forwardToReplicas = true - } else if (op === 'update_settings') { - params.forwardToReplicas = false + + if (operation === 'partial_update_record') { + result.createIfNotExists = result.createIfNotExists !== 'false' } - if (op === 'copy_move_index') { - params.operation = params.copyMoveOperation + if (operation === 'update_settings') { + result.forwardToReplicas = result.forwardToReplicas === 'true' } - if (op === 'delete_by_filter') { - params.filters = params.deleteFilters + if (operation === 'search' && result.getRankingInfo !== undefined) { + result.getRankingInfo = result.getRankingInfo === 'true' } - if (op === 'get_records') { - params.requests = params.getRecordsRequests + if (operation === 'copy_move_index') { + result.operation = result.copyMoveOperation + result.copyMoveOperation = undefined } - if (op === 'list_indices') { - if (params.listPage !== undefined) params.page = params.listPage - if (params.listHitsPerPage !== undefined) params.hitsPerPage = params.listHitsPerPage + if (operation === 'delete_by_filter') { + result.filters = result.deleteFilters + result.deleteFilters = undefined } - return `algolia_${op}` + if (operation === 'get_records') { + result.requests = result.getRecordsRequests + result.getRecordsRequests = undefined + } + + return result }, }, }, @@ -553,6 +576,8 @@ Return ONLY the JSON array.`, page: { type: 'string', description: 'Page number' }, filters: { type: 'string', description: 'Algolia filter string' }, attributesToRetrieve: { type: 'string', description: 'Attributes to retrieve' }, + facets: { type: 'string', description: 'Comma-separated facet attribute names to count' }, + getRankingInfo: { type: 'string', description: 'Include detailed ranking info in each hit' }, cursor: { type: 'string', description: 'Browse cursor for pagination' }, record: { type: 'json', description: 'Record data to add' }, attributes: { type: 'json', description: 'Attributes to partially update' }, @@ -579,8 +604,7 @@ Return ONLY the JSON array.`, type: 'json', description: 'Array of objects with objectID to retrieve multiple records', }, - listPage: { type: 'string', description: 'Page number for list indices pagination' }, - listHitsPerPage: { type: 'string', description: 'Indices per page for list indices' }, + taskID: { type: 'string', description: 'Task ID returned by a previous write operation' }, applicationId: { type: 'string', description: 'Algolia Application ID' }, apiKey: { type: 'string', description: 'Algolia API Key' }, }, @@ -644,6 +668,11 @@ Return ONLY the JSON array.`, type: 'number', description: 'Maximum number of hits accessible via pagination (default 1000)', }, + status: { + type: 'string', + description: 'Task status: "published" once applied, "notPublished" while still pending', + }, + pendingTask: { type: 'boolean', description: 'Whether the task is still pending' }, }, } @@ -739,5 +768,19 @@ export const AlgoliaBlockMeta = { content: '# Audit Search Relevance\n\nCheck that important queries return good results from an Algolia index.\n\n## Steps\n1. Run each query in the provided test set against the index.\n2. Record the top results, total hit count, and whether the expected record appears.\n3. Flag queries that return zero hits, too many hits, or miss the expected record.\n\n## Output\nA table of queries with result counts and pass/fail, plus suggestions for synonyms or ranking tweaks where relevance is weak.', }, + { + name: 'tune-index-ranking', + description: + 'Read an Algolia index configuration, propose ranking and searchable-attribute changes, and apply the update.', + content: + '# Tune Index Ranking\n\nAdjust how an Algolia index ranks results without touching the underlying data.\n\n## Steps\n1. Fetch the current index settings (searchable attributes, custom ranking, ranking criteria).\n2. Compare them against the desired outcome (e.g., surface newer or more popular items first).\n3. Propose specific changes to customRanking, searchableAttributes order, or attributesForFaceting.\n4. Apply the approved settings update to the index.\n\n## Output\nA before/after summary of the settings changed and why, plus confirmation the update succeeded.', + }, + { + name: 'snapshot-index-before-change', + description: + 'Copy an Algolia index to a timestamped backup before applying a risky settings or data change.', + content: + '# Snapshot Index Before Change\n\nProtect against a bad settings or batch update by copying the index first.\n\n## Steps\n1. Copy the source index to a new destination index named with a date or version suffix.\n2. Confirm the copy completed by checking the resulting task status.\n3. Apply the intended change (settings update, batch operation, or delete-by-filter) to the original index.\n4. If the change causes problems, the snapshot index can be copied back or used for comparison.\n\n## Output\nThe name of the backup index created and confirmation the source change was applied afterward.', + }, ], } as const satisfies BlockMeta diff --git a/apps/sim/blocks/blocks/dropcontact.ts b/apps/sim/blocks/blocks/dropcontact.ts index be4ca04a2f2..875504d0be9 100644 --- a/apps/sim/blocks/blocks/dropcontact.ts +++ b/apps/sim/blocks/blocks/dropcontact.ts @@ -10,7 +10,7 @@ export const DropcontactBlock: BlockConfig = { 'Use Dropcontact to verify and enrich B2B contacts. Submit a contact with their name, company, website, or LinkedIn URL and receive a verified professional email, phone number, company firmographics, and LinkedIn profile. Enrichment is async: Dropcontact processes the request, then Sim polls until the result is ready. Credits are only charged when a verified email is returned.', docsLink: 'https://docs.sim.ai/tools/dropcontact', category: 'tools', - bgColor: '#0066FF', + bgColor: '#0ABA9F', icon: DropcontactIcon, authMode: AuthMode.ApiKey, integrationType: IntegrationType.Sales, diff --git a/apps/sim/blocks/blocks/grafana.ts b/apps/sim/blocks/blocks/grafana.ts index 9cb12c810ce..d1c70517d66 100644 --- a/apps/sim/blocks/blocks/grafana.ts +++ b/apps/sim/blocks/blocks/grafana.ts @@ -13,7 +13,7 @@ export const GrafanaBlock: BlockConfig = { docsLink: 'https://docs.sim.ai/integrations/grafana', category: 'tools', integrationType: IntegrationType.Observability, - bgColor: '#F46800', + bgColor: '#FFFFFF', icon: GrafanaIcon, subBlocks: [ { diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index 58d2124d7b3..259fd03dfeb 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -7985,18 +7985,16 @@ export function LeadMagicIcon(props: SVGProps) { ) } -/** Dropcontact brand icon: teal disc with the white open-"d" contact mark. */ +/** Dropcontact brand icon: the teal swirl mark from the official wordmark. */ export function DropcontactIcon(props: SVGProps) { return ( - - + - ) } diff --git a/apps/sim/lib/integrations/integrations.json b/apps/sim/lib/integrations/integrations.json index e362db3a581..03f07029836 100644 --- a/apps/sim/lib/integrations/integrations.json +++ b/apps/sim/lib/integrations/integrations.json @@ -1,5 +1,5 @@ { - "updatedAt": "2026-07-01", + "updatedAt": "2026-07-02", "integrations": [ { "type": "onepassword", @@ -541,9 +541,13 @@ { "name": "Delete By Filter", "description": "Delete all records matching a filter from an Algolia index" + }, + { + "name": "Get Task Status", + "description": "Check whether an Algolia indexing task has finished publishing" } ], - "operationCount": 15, + "operationCount": 16, "triggers": [], "triggerCount": 0, "authType": "api-key", @@ -4418,7 +4422,7 @@ "name": "Dropcontact", "description": "Enrich B2B contacts with verified email, phone, and company data", "longDescription": "Use Dropcontact to verify and enrich B2B contacts. Submit a contact with their name, company, website, or LinkedIn URL and receive a verified professional email, phone number, company firmographics, and LinkedIn profile. Enrichment is async: Dropcontact processes the request, then Sim polls until the result is ready. Credits are only charged when a verified email is returned.", - "bgColor": "#0066FF", + "bgColor": "#0ABA9F", "iconName": "DropcontactIcon", "docsUrl": "https://docs.sim.ai/tools/dropcontact", "operations": [ @@ -7312,7 +7316,7 @@ "name": "Grafana", "description": "Interact with Grafana dashboards, alerts, and annotations", "longDescription": "Integrate Grafana into workflows. Manage dashboards, alerts, annotations, data sources, folders, and monitor health status.", - "bgColor": "#F46800", + "bgColor": "#FFFFFF", "iconName": "GrafanaIcon", "docsUrl": "https://docs.sim.ai/integrations/grafana", "operations": [ diff --git a/apps/sim/tools/algolia/add_record.ts b/apps/sim/tools/algolia/add_record.ts index a1ccb3b30c1..a6f5623ac44 100644 --- a/apps/sim/tools/algolia/add_record.ts +++ b/apps/sim/tools/algolia/add_record.ts @@ -42,9 +42,9 @@ export const addRecordTool: ToolConfig { - const base = `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}` + const base = `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}` if (params.objectID) { - return `${base}/${encodeURIComponent(params.objectID)}` + return `${base}/${encodeURIComponent(params.objectID.trim())}` } return base }, diff --git a/apps/sim/tools/algolia/batch_operations.ts b/apps/sim/tools/algolia/batch_operations.ts index d65c69c0feb..4beb4f0d072 100644 --- a/apps/sim/tools/algolia/batch_operations.ts +++ b/apps/sim/tools/algolia/batch_operations.ts @@ -38,13 +38,13 @@ export const batchOperationsTool: ToolConfig< required: true, visibility: 'user-or-llm', description: - 'Array of batch operations. Each item has "action" (addObject, updateObject, partialUpdateObject, partialUpdateObjectNoCreate, deleteObject) and "body" (the record data, must include objectID for update/delete)', + 'Array of batch operations. Each item has "action" (addObject, updateObject, partialUpdateObject, partialUpdateObjectNoCreate, deleteObject, delete, clear) and "body" (the record data, must include objectID for update/delete; omit body for delete/clear)', }, }, request: { url: (params) => - `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/batch`, + `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/batch`, method: 'POST', headers: (params) => ({ 'x-algolia-application-id': params.applicationId, diff --git a/apps/sim/tools/algolia/browse_records.ts b/apps/sim/tools/algolia/browse_records.ts index 7b6dc3064f6..c466879fae0 100644 --- a/apps/sim/tools/algolia/browse_records.ts +++ b/apps/sim/tools/algolia/browse_records.ts @@ -62,11 +62,36 @@ export const browseRecordsTool: ToolConfig< visibility: 'user-or-llm', description: 'Cursor from a previous browse response for pagination', }, + aroundLatLng: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Coordinates for geo-search (e.g., "40.71,-74.01")', + }, + aroundRadius: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Maximum radius in meters for geo-search, or "all" for unlimited', + }, + insideBoundingBox: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: 'Bounding box coordinates as [[lat1, lng1, lat2, lng2]] for geo-search', + }, + insidePolygon: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'Polygon coordinates as [[lat1, lng1, lat2, lng2, lat3, lng3, ...]] for geo-search', + }, }, request: { url: (params) => - `https://${params.applicationId}-dsn.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/browse`, + `https://${params.applicationId}-dsn.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/browse`, method: 'POST', headers: (params) => ({ 'x-algolia-application-id': params.applicationId, @@ -86,6 +111,22 @@ export const browseRecordsTool: ToolConfig< .map((a: string) => a.trim()) } if (params.hitsPerPage !== undefined) body.hitsPerPage = Number(params.hitsPerPage) + if (params.aroundLatLng) body.aroundLatLng = params.aroundLatLng + if (params.aroundRadius !== undefined) { + body.aroundRadius = params.aroundRadius === 'all' ? 'all' : Number(params.aroundRadius) + } + if (params.insideBoundingBox) { + body.insideBoundingBox = + typeof params.insideBoundingBox === 'string' + ? JSON.parse(params.insideBoundingBox) + : params.insideBoundingBox + } + if (params.insidePolygon) { + body.insidePolygon = + typeof params.insidePolygon === 'string' + ? JSON.parse(params.insidePolygon) + : params.insidePolygon + } return body }, }, diff --git a/apps/sim/tools/algolia/clear_records.ts b/apps/sim/tools/algolia/clear_records.ts index 1c789ea8fdc..b647e3912f9 100644 --- a/apps/sim/tools/algolia/clear_records.ts +++ b/apps/sim/tools/algolia/clear_records.ts @@ -32,7 +32,7 @@ export const clearRecordsTool: ToolConfig - `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/clear`, + `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/clear`, method: 'POST', headers: (params) => ({ 'x-algolia-application-id': params.applicationId, diff --git a/apps/sim/tools/algolia/copy_move_index.ts b/apps/sim/tools/algolia/copy_move_index.ts index 7174d1f9912..970d18d6414 100644 --- a/apps/sim/tools/algolia/copy_move_index.ts +++ b/apps/sim/tools/algolia/copy_move_index.ts @@ -55,7 +55,7 @@ export const copyMoveIndexTool: ToolConfig< request: { url: (params) => - `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/operation`, + `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/operation`, method: 'POST', headers: (params) => ({ 'x-algolia-application-id': params.applicationId, @@ -65,7 +65,7 @@ export const copyMoveIndexTool: ToolConfig< body: (params) => { const body: Record = { operation: params.operation, - destination: params.destination, + destination: params.destination.trim(), } if (params.scope) { const scope = typeof params.scope === 'string' ? JSON.parse(params.scope) : params.scope diff --git a/apps/sim/tools/algolia/delete_by_filter.ts b/apps/sim/tools/algolia/delete_by_filter.ts index ca030f07f5c..b79cc0f2d80 100644 --- a/apps/sim/tools/algolia/delete_by_filter.ts +++ b/apps/sim/tools/algolia/delete_by_filter.ts @@ -63,7 +63,7 @@ export const deleteByFilterTool: ToolConfig< description: 'Coordinates for geo-search filter (e.g., "40.71,-74.01")', }, aroundRadius: { - type: 'number', + type: 'string', required: false, visibility: 'user-or-llm', description: 'Maximum radius in meters for geo-search, or "all" for unlimited', @@ -85,7 +85,7 @@ export const deleteByFilterTool: ToolConfig< request: { url: (params) => - `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/deleteByQuery`, + `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/deleteByQuery`, method: 'POST', headers: (params) => ({ 'x-algolia-application-id': params.applicationId, diff --git a/apps/sim/tools/algolia/delete_index.ts b/apps/sim/tools/algolia/delete_index.ts index 7e206aafcbf..130f56ee5a9 100644 --- a/apps/sim/tools/algolia/delete_index.ts +++ b/apps/sim/tools/algolia/delete_index.ts @@ -31,7 +31,7 @@ export const deleteIndexTool: ToolConfig - `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}`, + `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}`, headers: (params) => ({ 'x-algolia-application-id': params.applicationId, 'x-algolia-api-key': params.apiKey, diff --git a/apps/sim/tools/algolia/delete_record.ts b/apps/sim/tools/algolia/delete_record.ts index db63ee70593..5332d322a67 100644 --- a/apps/sim/tools/algolia/delete_record.ts +++ b/apps/sim/tools/algolia/delete_record.ts @@ -38,7 +38,7 @@ export const deleteRecordTool: ToolConfig - `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/${encodeURIComponent(params.objectID)}`, + `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/${encodeURIComponent(params.objectID.trim())}`, headers: (params) => ({ 'x-algolia-application-id': params.applicationId, 'x-algolia-api-key': params.apiKey, diff --git a/apps/sim/tools/algolia/get_record.ts b/apps/sim/tools/algolia/get_record.ts index 88992c0feb8..61aa7482765 100644 --- a/apps/sim/tools/algolia/get_record.ts +++ b/apps/sim/tools/algolia/get_record.ts @@ -43,7 +43,7 @@ export const getRecordTool: ToolConfig { - const base = `https://${params.applicationId}-dsn.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/${encodeURIComponent(params.objectID)}` + const base = `https://${params.applicationId}-dsn.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/${encodeURIComponent(params.objectID.trim())}` if (params.attributesToRetrieve) { return `${base}?attributesToRetrieve=${encodeURIComponent(params.attributesToRetrieve)}` } diff --git a/apps/sim/tools/algolia/get_settings.ts b/apps/sim/tools/algolia/get_settings.ts index 16bc90ddfd0..db3b7aeebd8 100644 --- a/apps/sim/tools/algolia/get_settings.ts +++ b/apps/sim/tools/algolia/get_settings.ts @@ -31,7 +31,7 @@ export const getSettingsTool: ToolConfig - `https://${params.applicationId}-dsn.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/settings`, + `https://${params.applicationId}-dsn.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/settings`, headers: (params) => ({ 'x-algolia-application-id': params.applicationId, 'x-algolia-api-key': params.apiKey, diff --git a/apps/sim/tools/algolia/get_task_status.ts b/apps/sim/tools/algolia/get_task_status.ts new file mode 100644 index 00000000000..5f957745335 --- /dev/null +++ b/apps/sim/tools/algolia/get_task_status.ts @@ -0,0 +1,75 @@ +import type { + AlgoliaGetTaskStatusParams, + AlgoliaGetTaskStatusResponse, +} from '@/tools/algolia/types' +import type { ToolConfig } from '@/tools/types' + +export const getTaskStatusTool: ToolConfig< + AlgoliaGetTaskStatusParams, + AlgoliaGetTaskStatusResponse +> = { + id: 'algolia_get_task_status', + name: 'Algolia Get Task Status', + description: 'Check whether an Algolia indexing task has finished publishing', + version: '1.0', + + params: { + applicationId: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Algolia Application ID', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Algolia API Key', + }, + indexName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Name of the Algolia index the task ran against', + }, + taskID: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'The taskID returned by a previous write operation', + }, + }, + + request: { + method: 'GET', + url: (params) => + `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/task/${encodeURIComponent(String(params.taskID).trim())}`, + headers: (params) => ({ + 'x-algolia-application-id': params.applicationId, + 'x-algolia-api-key': params.apiKey, + }), + }, + + transformResponse: async (response) => { + const data = await response.json() + return { + success: true, + output: { + status: data.status ?? '', + pendingTask: data.pendingTask ?? false, + }, + } + }, + + outputs: { + status: { + type: 'string', + description: + 'Task status: "published" once the operation has been applied, "notPublished" while still pending', + }, + pendingTask: { + type: 'boolean', + description: 'Whether the task is still pending', + }, + }, +} diff --git a/apps/sim/tools/algolia/index.ts b/apps/sim/tools/algolia/index.ts index b5fdc4bd70f..a86ac448f73 100644 --- a/apps/sim/tools/algolia/index.ts +++ b/apps/sim/tools/algolia/index.ts @@ -9,6 +9,7 @@ import { deleteRecordTool } from '@/tools/algolia/delete_record' import { getRecordTool } from '@/tools/algolia/get_record' import { getRecordsTool } from '@/tools/algolia/get_records' import { getSettingsTool } from '@/tools/algolia/get_settings' +import { getTaskStatusTool } from '@/tools/algolia/get_task_status' import { listIndicesTool } from '@/tools/algolia/list_indices' import { partialUpdateRecordTool } from '@/tools/algolia/partial_update_record' import { searchTool } from '@/tools/algolia/search' @@ -24,6 +25,7 @@ export const algoliaBrowseRecordsTool = browseRecordsTool export const algoliaBatchOperationsTool = batchOperationsTool export const algoliaListIndicesTool = listIndicesTool export const algoliaGetSettingsTool = getSettingsTool +export const algoliaGetTaskStatusTool = getTaskStatusTool export const algoliaUpdateSettingsTool = updateSettingsTool export const algoliaDeleteIndexTool = deleteIndexTool export const algoliaCopyMoveIndexTool = copyMoveIndexTool diff --git a/apps/sim/tools/algolia/partial_update_record.ts b/apps/sim/tools/algolia/partial_update_record.ts index ce6430ecbd8..80f6214c07c 100644 --- a/apps/sim/tools/algolia/partial_update_record.ts +++ b/apps/sim/tools/algolia/partial_update_record.ts @@ -55,7 +55,7 @@ export const partialUpdateRecordTool: ToolConfig< request: { url: (params) => { - const base = `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/${encodeURIComponent(params.objectID)}/partial` + const base = `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/${encodeURIComponent(params.objectID.trim())}/partial` if (params.createIfNotExists === false) { return `${base}?createIfNotExists=false` } diff --git a/apps/sim/tools/algolia/search.ts b/apps/sim/tools/algolia/search.ts index fb46fd7dc41..44f6a0965a2 100644 --- a/apps/sim/tools/algolia/search.ts +++ b/apps/sim/tools/algolia/search.ts @@ -56,6 +56,44 @@ export const searchTool: ToolConfig visibility: 'user-or-llm', description: 'Comma-separated list of attributes to retrieve', }, + facets: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of facet attribute names to retrieve counts for (use "*" for all)', + }, + getRankingInfo: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether to include detailed ranking information in each hit', + }, + aroundLatLng: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Coordinates for geo-search (e.g., "40.71,-74.01")', + }, + aroundRadius: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Maximum radius in meters for geo-search, or "all" for unlimited', + }, + insideBoundingBox: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: 'Bounding box coordinates as [[lat1, lng1, lat2, lng2]] for geo-search', + }, + insidePolygon: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'Polygon coordinates as [[lat1, lng1, lat2, lng2, lat3, lng3, ...]] for geo-search', + }, }, request: { @@ -79,6 +117,26 @@ export const searchTool: ToolConfig .split(',') .map((a: string) => a.trim()) } + if (params.facets) { + request.facets = params.facets.split(',').map((f: string) => f.trim()) + } + if (params.getRankingInfo) request.getRankingInfo = true + if (params.aroundLatLng) request.aroundLatLng = params.aroundLatLng + if (params.aroundRadius !== undefined) { + request.aroundRadius = params.aroundRadius === 'all' ? 'all' : Number(params.aroundRadius) + } + if (params.insideBoundingBox) { + request.insideBoundingBox = + typeof params.insideBoundingBox === 'string' + ? JSON.parse(params.insideBoundingBox) + : params.insideBoundingBox + } + if (params.insidePolygon) { + request.insidePolygon = + typeof params.insidePolygon === 'string' + ? JSON.parse(params.insidePolygon) + : params.insidePolygon + } return { requests: [request] } }, }, diff --git a/apps/sim/tools/algolia/types.ts b/apps/sim/tools/algolia/types.ts index c297871d6d0..5c606ead21b 100644 --- a/apps/sim/tools/algolia/types.ts +++ b/apps/sim/tools/algolia/types.ts @@ -13,6 +13,12 @@ export interface AlgoliaSearchParams extends AlgoliaBaseParams { page?: number | string filters?: string attributesToRetrieve?: string + facets?: string + getRankingInfo?: boolean | string + aroundLatLng?: string + aroundRadius?: number | string + insideBoundingBox?: string | number[][] + insidePolygon?: string | number[][] } export interface AlgoliaSearchResponse extends ToolResponse { @@ -116,6 +122,10 @@ export interface AlgoliaBrowseRecordsParams extends AlgoliaBaseParams { attributesToRetrieve?: string hitsPerPage?: number | string cursor?: string + aroundLatLng?: string + aroundRadius?: number | string + insideBoundingBox?: string | number[][] + insidePolygon?: string | number[][] } export interface AlgoliaBrowseRecordsResponse extends ToolResponse { @@ -266,3 +276,16 @@ export interface AlgoliaDeleteByFilterResponse extends ToolResponse { updatedAt: string | null } } + +// Get Task Status +export interface AlgoliaGetTaskStatusParams extends AlgoliaBaseParams { + indexName: string + taskID: number | string +} + +export interface AlgoliaGetTaskStatusResponse extends ToolResponse { + output: { + status: string + pendingTask: boolean + } +} diff --git a/apps/sim/tools/algolia/update_settings.ts b/apps/sim/tools/algolia/update_settings.ts index e8ff7f873aa..e3c4dd367fa 100644 --- a/apps/sim/tools/algolia/update_settings.ts +++ b/apps/sim/tools/algolia/update_settings.ts @@ -49,7 +49,7 @@ export const updateSettingsTool: ToolConfig< request: { url: (params) => { - const base = `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName)}/settings` + const base = `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/settings` if (params.forwardToReplicas) { return `${base}?forwardToReplicas=true` } diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index 2bb910c4eef..59a20be25d5 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -101,6 +101,7 @@ import { algoliaGetRecordsTool, algoliaGetRecordTool, algoliaGetSettingsTool, + algoliaGetTaskStatusTool, algoliaListIndicesTool, algoliaPartialUpdateRecordTool, algoliaSearchTool, @@ -6643,6 +6644,7 @@ export const tools: Record = { algolia_copy_move_index: algoliaCopyMoveIndexTool, algolia_clear_records: algoliaClearRecordsTool, algolia_delete_by_filter: algoliaDeleteByFilterTool, + algolia_get_task_status: algoliaGetTaskStatusTool, airtable_create_records: airtableCreateRecordsTool, airtable_delete_records: airtableDeleteRecordsTool, airtable_get_base_schema: airtableGetBaseSchemaTool, From ec7bc76aa519573fe8fd51938ecf2fb041c435fc Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 1 Jul 2026 23:49:08 -0700 Subject: [PATCH 2/8] fix(algolia): register subblock-id migration for listPage/listHitsPerPage CI's subblock-id stability check correctly flagged that consolidating list_indices pagination into the shared page/hitsPerPage fields would silently drop values from already-deployed workflows. Add the rename mapping so existing saved state migrates instead of being lost. --- apps/sim/lib/workflows/migrations/subblock-migrations.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/sim/lib/workflows/migrations/subblock-migrations.ts b/apps/sim/lib/workflows/migrations/subblock-migrations.ts index 3deedca5212..d56d51ff055 100644 --- a/apps/sim/lib/workflows/migrations/subblock-migrations.ts +++ b/apps/sim/lib/workflows/migrations/subblock-migrations.ts @@ -26,6 +26,10 @@ export const SUBBLOCK_ID_MIGRATIONS: Record> = { knowledge: { knowledgeBaseId: 'knowledgeBaseSelector', }, + algolia: { + listPage: 'page', + listHitsPerPage: 'hitsPerPage', + }, kalshi: { settlementStatus: '_removed_settlementStatus', }, From d1021292ecb8ac1d4be4c94ea9af7bd505921e8a Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 1 Jul 2026 23:53:36 -0700 Subject: [PATCH 3/8] fix(algolia): remove fabricated pendingTask field from get_task_status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Algolia's Get Task Status response (additionalProperties: false) only returns `status` (published | notPublished) — pendingTask belongs to the List Indices response, not this endpoint. Drop it from the tool's output, response type, and block outputs rather than inventing data. --- apps/sim/blocks/blocks/algolia.ts | 1 - apps/sim/tools/algolia/get_task_status.ts | 5 ----- apps/sim/tools/algolia/types.ts | 1 - 3 files changed, 7 deletions(-) diff --git a/apps/sim/blocks/blocks/algolia.ts b/apps/sim/blocks/blocks/algolia.ts index 4940fc43158..0644e4ba077 100644 --- a/apps/sim/blocks/blocks/algolia.ts +++ b/apps/sim/blocks/blocks/algolia.ts @@ -672,7 +672,6 @@ Return ONLY the JSON array.`, type: 'string', description: 'Task status: "published" once applied, "notPublished" while still pending', }, - pendingTask: { type: 'boolean', description: 'Whether the task is still pending' }, }, } diff --git a/apps/sim/tools/algolia/get_task_status.ts b/apps/sim/tools/algolia/get_task_status.ts index 5f957745335..9c19c41a5ba 100644 --- a/apps/sim/tools/algolia/get_task_status.ts +++ b/apps/sim/tools/algolia/get_task_status.ts @@ -56,7 +56,6 @@ export const getTaskStatusTool: ToolConfig< success: true, output: { status: data.status ?? '', - pendingTask: data.pendingTask ?? false, }, } }, @@ -67,9 +66,5 @@ export const getTaskStatusTool: ToolConfig< description: 'Task status: "published" once the operation has been applied, "notPublished" while still pending', }, - pendingTask: { - type: 'boolean', - description: 'Whether the task is still pending', - }, }, } diff --git a/apps/sim/tools/algolia/types.ts b/apps/sim/tools/algolia/types.ts index 5c606ead21b..3e30293a52a 100644 --- a/apps/sim/tools/algolia/types.ts +++ b/apps/sim/tools/algolia/types.ts @@ -286,6 +286,5 @@ export interface AlgoliaGetTaskStatusParams extends AlgoliaBaseParams { export interface AlgoliaGetTaskStatusResponse extends ToolResponse { output: { status: string - pendingTask: boolean } } From 6fde39f3ced32ea5182b99abcee6a33ab5dfcf5d Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 1 Jul 2026 23:55:50 -0700 Subject: [PATCH 4/8] fix(algolia): coerce getRankingInfo/createIfNotExists/forwardToReplicas from real booleans, not just strings A wired boolean (e.g. true) failed the `=== 'true'` string-only checks and silently flipped to the wrong value. Add a toBool helper that accepts both the dropdown's string values and a genuine boolean passed in via a dynamic reference. fix(dropcontact): render icon with currentColor instead of hardcoded fill The new teal swirl mark's fill (#0ABA9F) matched the block's bgColor exactly, making the icon invisible on its own tile. Use currentColor and set iconColor so the shared tile-contrast logic (getTileIconColorClass) renders it white-on-teal like the rest of the brand icon system. --- apps/sim/blocks/blocks/algolia.ts | 12 +++++++++--- apps/sim/blocks/blocks/dropcontact.ts | 1 + apps/sim/components/icons.tsx | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/sim/blocks/blocks/algolia.ts b/apps/sim/blocks/blocks/algolia.ts index 0644e4ba077..7b62fa540b5 100644 --- a/apps/sim/blocks/blocks/algolia.ts +++ b/apps/sim/blocks/blocks/algolia.ts @@ -541,14 +541,20 @@ Return ONLY the JSON array.`, result[key] = value } + const toBool = (value: unknown, defaultValue: boolean) => { + if (typeof value === 'boolean') return value + if (typeof value === 'string') return value === 'true' + return defaultValue + } + if (operation === 'partial_update_record') { - result.createIfNotExists = result.createIfNotExists !== 'false' + result.createIfNotExists = toBool(result.createIfNotExists, true) } if (operation === 'update_settings') { - result.forwardToReplicas = result.forwardToReplicas === 'true' + result.forwardToReplicas = toBool(result.forwardToReplicas, false) } if (operation === 'search' && result.getRankingInfo !== undefined) { - result.getRankingInfo = result.getRankingInfo === 'true' + result.getRankingInfo = toBool(result.getRankingInfo, false) } if (operation === 'copy_move_index') { result.operation = result.copyMoveOperation diff --git a/apps/sim/blocks/blocks/dropcontact.ts b/apps/sim/blocks/blocks/dropcontact.ts index 875504d0be9..d335da37266 100644 --- a/apps/sim/blocks/blocks/dropcontact.ts +++ b/apps/sim/blocks/blocks/dropcontact.ts @@ -11,6 +11,7 @@ export const DropcontactBlock: BlockConfig = { docsLink: 'https://docs.sim.ai/tools/dropcontact', category: 'tools', bgColor: '#0ABA9F', + iconColor: '#0ABA9F', icon: DropcontactIcon, authMode: AuthMode.ApiKey, integrationType: IntegrationType.Sales, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index 259fd03dfeb..2bc753071f2 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -7993,7 +7993,7 @@ export function DropcontactIcon(props: SVGProps) { fillRule='evenodd' clipRule='evenodd' d='M29.57 16.22a10.84 10.84 0 0 0-4.698-1.064c-6.01 0-10.88 4.872-10.88 10.88s4.872 10.88 10.88 10.88c4.09 0 7.655-2.258 9.513-5.596l-2.623-1.457a7.88 7.88 0 0 1-6.89 4.053c-4.353 0-7.88-3.528-7.88-7.88s3.528-7.88 7.88-7.88a7.85 7.85 0 0 1 3.403.77l1.295-2.707zm5.21-14.235v25.762h-3.11V.9C29.546.313 27.3 0 25 0 11.193 0 0 11.193 0 25s11.193 25 25 25 25-11.193 25-25c0-10.337-6.274-19.21-15.222-23.016z' - fill='#0ABA9F' + fill='currentColor' /> ) From 1a8b0c353296fc67cdd20be2e215b92e15fb9658 Mon Sep 17 00:00:00 2001 From: waleed Date: Thu, 2 Jul 2026 00:11:21 -0700 Subject: [PATCH 5/8] fix(algolia): trim indexName in request bodies, not just URL paths Greptile caught that search.ts's body-level indexName (sent inside the multi-query POST body, not URL-encoded) wasn't trimmed like every other tool's URL-path indexName. Fixed there and in get_records.ts's per-request indexName default/override, which had the same gap. --- apps/sim/tools/algolia/get_records.ts | 3 ++- apps/sim/tools/algolia/search.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/sim/tools/algolia/get_records.ts b/apps/sim/tools/algolia/get_records.ts index 15199f0a8e7..4c1b2f355fe 100644 --- a/apps/sim/tools/algolia/get_records.ts +++ b/apps/sim/tools/algolia/get_records.ts @@ -48,7 +48,8 @@ export const getRecordsTool: ToolConfig[]).map((req) => ({ ...req, - indexName: req.indexName ?? params.indexName, + indexName: + typeof req.indexName === 'string' ? req.indexName.trim() : params.indexName.trim(), })) return { requests } }, diff --git a/apps/sim/tools/algolia/search.ts b/apps/sim/tools/algolia/search.ts index 44f6a0965a2..f02901eeaaa 100644 --- a/apps/sim/tools/algolia/search.ts +++ b/apps/sim/tools/algolia/search.ts @@ -106,7 +106,7 @@ export const searchTool: ToolConfig }), body: (params) => { const request: Record = { - indexName: params.indexName, + indexName: params.indexName.trim(), query: params.query, } if (params.hitsPerPage !== undefined) request.hitsPerPage = Number(params.hitsPerPage) From 90e97a442f21ae76beeb0f4e45a8e8ae449811a8 Mon Sep 17 00:00:00 2001 From: waleed Date: Thu, 2 Jul 2026 08:38:56 -0700 Subject: [PATCH 6/8] fix(algolia): route list_indices and get_task_status GETs to the -dsn read host Verified against Algolia's official JS client source (getDefaultHosts + transporter isRead = useReadTransporter || method === 'GET'): every GET request routes to the read (-dsn) host, matching the other 14 tools in this integration (get_record, get_settings, etc). Both tools were incorrectly hitting the write host. --- apps/sim/tools/algolia/get_task_status.ts | 2 +- apps/sim/tools/algolia/list_indices.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/sim/tools/algolia/get_task_status.ts b/apps/sim/tools/algolia/get_task_status.ts index 9c19c41a5ba..c8ea30d0809 100644 --- a/apps/sim/tools/algolia/get_task_status.ts +++ b/apps/sim/tools/algolia/get_task_status.ts @@ -43,7 +43,7 @@ export const getTaskStatusTool: ToolConfig< request: { method: 'GET', url: (params) => - `https://${params.applicationId}.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/task/${encodeURIComponent(String(params.taskID).trim())}`, + `https://${params.applicationId}-dsn.algolia.net/1/indexes/${encodeURIComponent(params.indexName.trim())}/task/${encodeURIComponent(String(params.taskID).trim())}`, headers: (params) => ({ 'x-algolia-application-id': params.applicationId, 'x-algolia-api-key': params.apiKey, diff --git a/apps/sim/tools/algolia/list_indices.ts b/apps/sim/tools/algolia/list_indices.ts index 5e6f3d30e75..b938be24405 100644 --- a/apps/sim/tools/algolia/list_indices.ts +++ b/apps/sim/tools/algolia/list_indices.ts @@ -37,7 +37,7 @@ export const listIndicesTool: ToolConfig { - const base = `https://${params.applicationId}.algolia.net/1/indexes` + const base = `https://${params.applicationId}-dsn.algolia.net/1/indexes` const queryParams: string[] = [] if (params.page !== undefined) queryParams.push(`page=${params.page}`) if (params.hitsPerPage !== undefined) queryParams.push(`hitsPerPage=${params.hitsPerPage}`) From 08c5f7f4f5e63956610b80874dacbc771096171f Mon Sep 17 00:00:00 2001 From: waleed Date: Thu, 2 Jul 2026 09:02:31 -0700 Subject: [PATCH 7/8] chore(algolia): regenerate docs to drop stale pendingTask entry The get_task_status pendingTask output was removed from code in d1021292ec (fabricated field, not in Algolia's real API response) but docs weren't regenerated at the time, leaving a stale entry. Also syncs the Dropcontact icon's currentColor fill into the docs mirror. --- apps/docs/components/icons.tsx | 2 +- apps/docs/content/docs/en/integrations/algolia.mdx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index 259fd03dfeb..2bc753071f2 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -7993,7 +7993,7 @@ export function DropcontactIcon(props: SVGProps) { fillRule='evenodd' clipRule='evenodd' d='M29.57 16.22a10.84 10.84 0 0 0-4.698-1.064c-6.01 0-10.88 4.872-10.88 10.88s4.872 10.88 10.88 10.88c4.09 0 7.655-2.258 9.513-5.596l-2.623-1.457a7.88 7.88 0 0 1-6.89 4.053c-4.353 0-7.88-3.528-7.88-7.88s3.528-7.88 7.88-7.88a7.85 7.85 0 0 1 3.403.77l1.295-2.707zm5.21-14.235v25.762h-3.11V.9C29.546.313 27.3 0 25 0 11.193 0 0 11.193 0 25s11.193 25 25 25 25-11.193 25-25c0-10.337-6.274-19.21-15.222-23.016z' - fill='#0ABA9F' + fill='currentColor' /> ) diff --git a/apps/docs/content/docs/en/integrations/algolia.mdx b/apps/docs/content/docs/en/integrations/algolia.mdx index 17e262acb84..9d506105db4 100644 --- a/apps/docs/content/docs/en/integrations/algolia.mdx +++ b/apps/docs/content/docs/en/integrations/algolia.mdx @@ -429,6 +429,5 @@ Check whether an Algolia indexing task has finished publishing | Parameter | Type | Description | | --------- | ---- | ----------- | | `status` | string | Task status: "published" once the operation has been applied, "notPublished" while still pending | -| `pendingTask` | boolean | Whether the task is still pending | From 96ad66a2c82ce6efe7c64a9a8911c714c75b4e1b Mon Sep 17 00:00:00 2001 From: waleed Date: Thu, 2 Jul 2026 09:45:16 -0700 Subject: [PATCH 8/8] fix(algolia): correct batch_operations body requirement wording MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verified against Algolia's actual batchWriteParams schema (specs/common/schemas/Batch.yml): body is a required property on every batch request item, including index-level delete/clear actions — it isn't omittable. The tool's param description previously said to omit it; corrected to say use an empty object instead. --- apps/sim/tools/algolia/batch_operations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sim/tools/algolia/batch_operations.ts b/apps/sim/tools/algolia/batch_operations.ts index 4beb4f0d072..7016dc26717 100644 --- a/apps/sim/tools/algolia/batch_operations.ts +++ b/apps/sim/tools/algolia/batch_operations.ts @@ -38,7 +38,7 @@ export const batchOperationsTool: ToolConfig< required: true, visibility: 'user-or-llm', description: - 'Array of batch operations. Each item has "action" (addObject, updateObject, partialUpdateObject, partialUpdateObjectNoCreate, deleteObject, delete, clear) and "body" (the record data, must include objectID for update/delete; omit body for delete/clear)', + 'Array of batch operations. Each item has "action" (addObject, updateObject, partialUpdateObject, partialUpdateObjectNoCreate, deleteObject, delete, clear) and "body" (the record data; must include objectID for update/delete; use an empty object {} for the index-level delete/clear actions)', }, },