/* * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. * @generated-id: af8d0e1dda1d */ import { searchSearchAssets } from "../../funcs/searchSearchAssets.js"; import { SearchParameters$zodSchema } from "../../models/searchparameters.js"; import { formatResult, ToolDefinition } from "../tools.js"; import { appUri } from "../apps/uri.js"; const args = { request: SearchParameters$zodSchema.describe(`The search query parameters.`), }; export const tool$searchSearchAssets: ToolDefinition = { name: "search-assets", description: `Provides a powerful query interface to filter and retrieve assets and their details Returns a list of resources matching the specified search criteria. Uses a Lucene-like query language to filter assets by descriptive attributes (\`public_id\`, \`asset_id\`, \`filename\`, \`display_name\`, \`folder\` / \`asset_folder\`, \`tags\`, \`context.\`), file details (\`resource_type\`, \`type\`, \`format\`, \`bytes\`, \`width\`, \`height\`, \`duration\`, \`pages\`, \`aspect_ratio\`, \`transparent\`, \`grayscale\`), lifecycle dates (\`uploaded_at\`, \`created_at\`, \`taken_at\`, \`updated_at\`, \`last_updated.\`), moderation and lifecycle state (\`status\`, \`moderation_status\`, \`moderation_kind\`), embedded data (\`image_metadata.*\`), structured metadata (\`metadata.\`), and analysis fields (\`face_count\`, \`colors\`, \`quality_score\`, \`illustration_score\`, \`accessibility_analysis.*\`). Supports sorting, aggregate counts, and complex boolean expressions. See the \`expression\` parameter for the full field reference. ## Expression syntax - **Match**: \`field:value\` (token match) or \`field=value\` (exact match). Examples: \`tags:shirt\`, \`tags=cotton\`. - **Comparisons**: \`>\`, \`<\`, \`>=\`, \`<=\` for numbers and dates. Example: \`bytes>10000000\`. - **Ranges**: \`field:[from TO to]\` inclusive, \`field:{from TO to}\` exclusive. Example: \`width:{200 TO 1028}\`. - **Booleans**: \`AND\`, \`OR\`, \`NOT\` (uppercase), or \`+\` (must), \`-\` (must not). \`NOT\` must appear between clauses — a bare leading \`NOT\` is a parse error; use \`-field:value\` to negate the first clause. Group with parentheses: \`(shirt OR pants) AND clothes\`. - **Wildcards**: trailing \`*\` only, for prefix match (\`public_id:shoes_*\`, \`format:jp*\`, \`tags:shirt*\`). Not supported on \`folder\`, \`asset_folder\`, \`resource_type\`, or \`type\`. Leading \`*\`, middle \`*\`, \`?\`, and bare \`*\` (\`folder:*\`, \`context.alt:*\`) are all parse errors — wildcards cannot be used as a "field is present" probe. - **Tokenized vs exact fields**: \`tags\`, \`filename\`, \`display_name\`, \`context.\`, and \`metadata.\` match on tokens split by whitespace and punctuation — \`tags:analysis\` matches the tag \`full-analysis\`. \`public_id\`, \`folder\`, \`asset_folder\`, and \`format\` match the whole value — \`public_id:dog\` will not match \`dog_pldcwy\`; use \`public_id="dog_pldcwy"\` (exact) or \`public_id:dog*\` (prefix). These exact-match fields still accept a trailing \`*\` for prefix match (except \`folder\` / \`asset_folder\`, where wildcards are ignored). - **Dates**: ISO-8601 in quotes (\`uploaded_at>"2024-01-15"\`) or relative shorthand \`Nh\`, \`Nd\`, \`Nw\`, \`Nm\`, \`Ny\` (\`uploaded_at>1d\`, \`created_at:[4w TO 1w]\`). Send raw \`<\`/\`>\`, never HTML-escaped. - **Quoting**: wrap any value containing a space, colon, or other reserved character (\`! ( ) { } [ ] ^ ~ ? \\ = & < > |\`) in double quotes, or escape each character with \`\\\`. Examples: \`tags:"service:mantels"\`, \`aspect_ratio:"16:9"\`, \`folder:"My Folder"\`. ## Common mistakes - Use \`folder:\` or \`asset_folder:\` (singular); \`folders:\`, \`asset_folder_id:\`, and other invented variants are not valid fields. Pass the exact folder name — wildcards do not apply here. - There is no "has any value" / presence probe. \`folder:*\`, \`metadata.alt:*\`, \`context.key:*\`, \`tags:*\`, and \`-tags:*\` are all parse errors. See *"Which assets have any value for \`metadata.\`?"* under **Common tasks** for workarounds. - \`NOT foo AND bar\` is a parse error. Write it as \`bar AND NOT foo\` or \`-foo AND bar\`, and keep every \`NOT\` between two clauses (\`a AND NOT b AND NOT c\` is fine; \`NOT b AND NOT c …\` is not). - \`public_id:dog\` will not match \`dog_pldcwy\`. Use \`public_id="dog_pldcwy"\` (exact) or \`public_id:dog*\` (prefix). - \`tags=service:mantels\` fails because the unquoted colon is parsed as a field separator. Use \`tags="service:mantels"\` or \`tags=service\\:mantels\`. - Do not HTML-escape operators. Send \`uploaded_at<1h\`, not \`uploaded_at<1h\`. - Do not leave an operand empty (e.g. \`tags: AND -tags:foo\`). Omit the empty clause entirely. ## Tips - Set \`max_results: 0\` to return only \`total_count\` and \`aggregations\` without any resource payload — useful for counts and aggregation-only queries. - \`total_count\` is always present in the response; prefer it over running an aggregation just to get a count. - \`aggregate\` (both simple and range variants) and the \`metadata\`, \`image_metadata\`, \`image_analysis\` values of \`with_field\` require a Tier 2 search plan. - Range aggregations require each range to include a \`key\` label (1–20 chars, \`[a-zA-Z0-9_-]+\`) and at least one of \`from\` / \`to\`. ## Common tasks - **Count matching assets** — put the filter in \`expression\` with \`max_results: 0\` and read \`total_count\` from the response. Works on every tier; no \`aggregate\` needed. - **Preview one matching asset** — set \`max_results: 1\`; add \`with_field: ["tags", "context"]\` (or \`metadata\`, Tier 2) to inspect values. Prefer this over fetching and scanning a full page. - **Distribution of values for a field** — Tier 2: \`aggregate: [format|resource_type|type]\` for enum counts, or range aggregations on \`bytes\`, \`image_pixels\`, \`video_pixels\`, or \`duration\`. Tier 1 fallback: run N small queries with \`max_results: 0\`, one per candidate value, and read \`total_count\` from each. - **"Which assets have any value for \`metadata.\`?"** — not expressible directly (\`metadata.X:*\` is a parse error; there is no presence probe). Workarounds: (a) if the field has a known value set, enumerate — \`metadata.region:(apac OR emea OR amer)\`; (b) query broadly with \`with_field: ["metadata"]\` (Tier 2) and filter client-side for entries where the field is set; (c) at ingest time, attach a sentinel tag whenever the field is set, then search by that tag. - **Newest / largest N** — keep the filter in \`expression\` and sort explicitly: \`sort_by: [{uploaded_at: "desc"}]\` with \`max_results: 10\`. - **Filter by folder** — both \`asset_folder:"parent/child"\` and \`folder:"parent/child"\` match an exact folder path; there is no wildcard or "contains". To query across multiple folders, enumerate: \`asset_folder:("campaigns/2024" OR "campaigns/2025")\`. - **Filter by metadata when you only know the label** — first call \`list-metadata-fields\` to resolve the label to an \`external_id\`, then query \`metadata.:value\`. - **Multiple independent filters in one turn** — prefer one \`expression\` with \`OR\` / parentheses over firing many parallel calls: \`metadata.region:apac OR metadata.region:emea\` in a single request is faster and more reliable than two parallel requests. ## Examples - \`tags:shirt AND uploaded_at>1d\` - \`resource_type:image AND bytes>1000000 AND (format:png OR format:jpg)\` - \`folder:products AND context.category:electronics\` - \`tags:"service:mantels" AND -tags:discontinued\` `, scopes: ["librarian"], annotations: { "title": "Search Assets", "destructiveHint": false, "idempotentHint": true, "openWorldHint": false, "readOnlyHint": true, }, _meta: { ui: { resourceUri: appUri("asset-gallery", "search-assets") }, }, args, tool: async (client, args, ctx) => { const [result] = await searchSearchAssets( client, args.request, { fetchOptions: { signal: ctx.signal } }, ).$inspect(); if (!result.ok) { return { content: [{ type: "text", text: result.error.message }], isError: true, }; } return formatResult(result.value); }, };