{"id":"html_code_executor","name":"HTML Executor","alias":"HtmlCodeExecutor","aliases":[],"description_short":"Execute a JavaScript function on HTML from SiteCrawler crawls.","description_long":"\n    Execute custom JavaScript extraction functions on HTML content from SiteCrawler.\n\n    This agent is optimized for batch processing - when processing multiple URLs,\n    they are sent to javascript executor together for better performance.\n\n    The JavaScript function should be in the format 'function() { ... }' and has\n    access to a `document` object for DOM traversal (querySelector, querySelectorAll, etc.).\n\n    If no crawl is specified (analysis_slug in config), the last successful crawl is used.\n    Temporary uploaded URLs on https://app.botify.com/:organization/:project/o/storage/tmp\n    are resolved from project storage and do not require a crawl.\n\n    Each input URL may carry a list of quality control expectations. When set,\n    the agent evaluates them against the extracted JSON result and reports, per\n    item, whether all expectations passed and the details of any failures.\n    ","description_tool_prompt":"\n    Execute a JavaScript function on HTML from a SiteCrawler crawl or a\n    temporary uploaded file.\n\n    The function must be written as `function() { ... }` and return\n    JSON-serializable data. A `document` object is pre-created for DOM queries.\n\n    For the full JavaScript API (Document, Element, helpers, runtime\n    differences vs a browser), call tool_documentation with\n    tool_name=\"html_code_executor\".\n\n    If no crawl is specified (analysis_slug), the last successful regular crawl\n    is used. Temporary uploaded URLs on\n    https://app.botify.com/:organization/:project/o/storage/tmp are resolved\n    from project storage and do not require a crawl.\n\n    Each input URL may carry quality control expectations evaluated against the\n    extracted JSON.\n    ","source":null,"conversation_examples":[],"tags":[],"available_in_chat":true,"available_in_deepthink":true,"available_in_mcp":true,"mcp_audience":"all","config":{"type":"object","properties":{"function":{"description":"JavaScript function to execute on the HTML. Should be in the format 'function() { ... }' and return the extracted data.","title":"JavaScript Function","type":"string"}},"required":["function"]},"item":{"type":"object","properties":{"url":{"description":"URL to execute the JavaScript function on. Temporary uploaded URLs on https://app.botify.com/:organization/:project/o/storage/tmp are allowed.","title":"URL","type":"string"},"expectations":{"default":[],"description":"Quality control expectations the extracted result must satisfy. When provided, the agent evaluates them against the extracted JSON and reports any failures.","items":{"$ref":"#/$defs/Expectation"},"title":"Expectations","type":"array"}},"required":["url"],"$defs":{"ArrayItemMatch":{"description":"A sub-object pattern that at least one array item must match.\n\nThe mapping ``fields`` is keyed by the sub-object's attribute names\n(e.g. ``{\"review_text\": \"great\", \"review_rating\": 5}``). Keys not\nlisted here are not checked.\n\nFor convenience, a bare sub-object is accepted as a shorthand for\n``fields``: ``{\"name\": \"Année\", \"value\": \"1982\"}`` is normalised to\n``{\"fields\": {\"name\": \"Année\", \"value\": \"1982\"}}``. To match an array of\n*scalars* (e.g. a list of URLs), pass the scalar directly in\n``expected_array_items`` rather than an :class:`ArrayItemMatch`.","properties":{"fields":{"additionalProperties":true,"description":"Sub-object fields to match (subset, no exhaustivity required)","title":"Fields","type":"object"},"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Free-form note describing how to locate this item in the page. Never used by the evaluator — purely informational.","title":"Instructions"}},"title":"ArrayItemMatch","type":"object"},"Expectation":{"description":"An expectation about a single field of the extracted JSON.\n\nExactly one of ``expected_value`` (for scalar fields),\n``expected_array_items`` (for array-item patterns) or\n``expected_length`` (for the length of an array field) must be set. The\n``operator`` is only meaningful for scalar and length expectations.","properties":{"field":{"description":"Name of the extracted JSON field to check. Supports dotted paths for nested objects (e.g. ``dimensions.width``).","title":"Field","type":"string"},"operator":{"default":"equals","description":"Predicate applied between the actual value and ``expected_value`` (scalar expectations) or between the array length and ``expected_length`` (length expectations). Defaults to ``equals``. Length expectations support only ``equals`` / ``gt`` / ``gte`` / ``lt`` / ``lte``.","enum":["equals","contains","matches_regex","gt","gte","lt","lte"],"title":"Operator","type":"string"},"expected_value":{"anyOf":[{},{"type":"null"}],"default":null,"description":"Expected scalar value (set when the field is a scalar)","title":"Expected Value"},"expected_array_items":{"anyOf":[{"items":{"anyOf":[{"$ref":"#/$defs/ArrayItemMatch"},{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"}]},"type":"array"},{"type":"null"}],"default":null,"description":"Patterns to match against array items (set when the field is an array). Each pattern is either a scalar — the array must contain an item equal to it (use this for arrays of strings or numbers, e.g. image URLs) — or a sub-object of fields, in which case at least one array item must match all the listed fields. For each pattern, at least one item must match.","title":"Expected Array Items"},"expected_length":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Expected number of items of an array field (set to assert on the array length). Combined with ``operator`` (equals / gt / gte / lt / lte).","title":"Expected Length"},"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Free-form note describing how to locate this field on the page. Never used by the evaluator — purely informational.","title":"Instructions"}},"required":["field"],"title":"Expectation","type":"object"}}},"response":{"$defs":{"ExpectationFailure":{"description":"A single expectation that did not hold against the extracted JSON.","properties":{"attribute":{"description":"The (possibly dotted) field that failed","title":"Attribute","type":"string"},"expected":{"anyOf":[{},{"type":"null"}],"default":null,"description":"What was expected (scalar value or array patterns)","title":"Expected"},"result":{"anyOf":[{},{"type":"null"}],"default":null,"description":"The value actually extracted (None when absent/null)","title":"Result"},"message":{"description":"Human-readable error message","title":"Message","type":"string"}},"required":["attribute","message"],"title":"ExpectationFailure","type":"object"}},"description":"Output from HTML executor agent.","properties":{"url":{"description":"The URL that was processed","title":"Url","type":"string"},"crawl":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Crawl Slug from SiteCrawler","title":"Crawl"},"url_found":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"Whether the URL was found in the crawl index","title":"Url Found"},"result":{"anyOf":[{},{"type":"null"}],"default":null,"description":"Result of executing the function on the HTML","title":"Result"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Error if function execution failed","title":"Error"},"quality_control_passed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True when every expectation holds against the extracted result, False when at least one fails, None when no expectations were provided.","title":"Quality Control Passed"},"quality_control_failures":{"default":[],"description":"One entry per failed expectation (empty when passed or when no expectations were provided).","items":{"$ref":"#/$defs/ExpectationFailure"},"title":"Quality Control Failures","type":"array"}},"required":["url"],"title":"HTMLExecutorProcessedItem","type":"object"},"has_canvas":false,"open_canvas_automatically":false}