Skip to content
Merged
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ Find Tools and execution are available on both the full surface and the search s

### Alexandria session feedback

Use the existing `firecrawl_feedback` tool with `endpoint: "alexandria"`:
The existing `firecrawl_feedback` tool accepts `endpoint: "alexandria"`:

```json
{
Expand All @@ -1212,4 +1212,4 @@ Use the existing `firecrawl_feedback` tool with `endpoint: "alexandria"`:

This uses authenticated `POST /v2/feedback`, without a job ID, job-age deadline, or credit refund. Optional `providerFeedback` and `capabilityFeedback` arrays describe coverage gaps and execution issues; the tool schema lists supported issue values. A `new_capability_request` requires `requestedFunctionality`; `missing_capability` (the provider exists but lacks the capability) does not. Existing feedback opt-out and authentication controls apply.

Agents are pointed at this loop from three places: the server instructions, the `firecrawl_scrape` and `firecrawl_find_tools` descriptions, and a `feedbackTool` object attached to every Alexandria execution and discovery result (with the tool name and a skeleton of the arguments). The hint is omitted for Firecrawl-internal calls such as `bash` and when `firecrawl_feedback` is not registered (`FIRECRAWL_NO_ENDPOINT_FEEDBACK` or keyless startup).
Eligible Alexandria execution and discovery results include a `feedbackTool` pointer with the tool name and a skeleton of the arguments. The pointer is omitted for Firecrawl-internal calls such as `bash` and when `firecrawl_feedback` is not registered (`FIRECRAWL_NO_ENDPOINT_FEEDBACK` or keyless startup).
10 changes: 1 addition & 9 deletions src/alexandria-feedback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,10 @@ export const alexandriaFeedbackFields = {
.optional(),
};

/**
* Shared by the server instructions and the Alexandria tool descriptions so an
* agent that only reads one of them still learns the feedback loop exists.
* Wording is checked by scripts/agent-metadata-policy.mjs.
*/
export const ALEXANDRIA_FEEDBACK_GUIDANCE =
'After an Alexandria task, whether a capability ran or discovery found nothing for the website, call firecrawl_feedback once per website with endpoint "alexandria": requestedWebsite (the url the user needed data from and the requestedFunctionality they needed), a rating, a rationale from observed results, and any providerFeedback or capabilityFeedback gaps. It is free, needs no job ID, has no deadline, and follows the answer rather than replacing it.';

/** Appended to Alexandria results so the pointer travels with the data the agent is reading. */
export const ALEXANDRIA_FEEDBACK_HINT = {
name: 'firecrawl_feedback',
when: 'Once per website after the task is complete, including when no provider covered the site. Free; no job ID or deadline.',
when: 'Optional after task completion; at most once per website, including uncovered sites. Free; no job ID or deadline.',
arguments: {
endpoint: 'alexandria',
rating: '<good | partial | bad>',
Expand Down
6 changes: 3 additions & 3 deletions src/alexandria.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ export const ALEXANDRIA_CATALOGUE_VERTICALS =
export const ALEXANDRIA_CATALOGUE_SENTENCE =
"Alexandria is Firecrawl's catalogue of data providers and workflows across " + ALEXANDRIA_CATALOGUE_VERTICALS + '; providers return typed, sourced records through published contracts.';
export const ALEXANDRIA_SOURCES_OPT_OUT =
'Passing sources without alexandria in it (for example ["web"] or ["news"]) excludes Alexandria provider matches; omit sources unless you specifically need web-only or news-only results, or include "alexandria" alongside them.';
'A search with sources: ["web"] omits semantic provider discovery; domainTools: true can still return website-matched tools. Web-only results use domainTools: false.';

// Claude Code truncates each tool description at 2,048 characters, so the routing
// copy that changes behaviour sits in the first lines of each description and the
// mechanics live on the parameters they describe.
export const ALEXANDRIA_SEARCH_LEAD =
'Authenticated search also returns matching Alexandria data providers in data.tools (' + ALEXANDRIA_CATALOGUE_VERTICALS + '). Prefer a provider over scraping pages when the task needs the same fields across several entities, exact figures or timestamps, provenance, or many records; use web results when they already answer the question. ' + ALEXANDRIA_SOURCES_OPT_OUT;
export const ALEXANDRIA_CONTRACT_GUIDANCE =
'Read the selected contract before executing: required inputs and requiresOneOf groups (at least one member per group), example.request/example.response when present, and response.key (do not assume records is the result key). Follow the declared pagination input and response cursor, preserving filters; catalogue next is separate from provider pagination.';
'The selected contract marks required inputs and any requiresOneOf groups (at least one member per group); it may include example.request/example.response and response.key (which may differ from records). Where pagination is declared, its fields govern paging with the same filters; catalogue next is separate from provider pagination.';

export function findToolsOptions(args: z.infer<typeof findToolsSchema>) {
const level = args.level ?? (args.query || args.capabilities?.length || args.providers?.length || args.groups?.length || args.urls?.length ? 'tools' : args.categories?.length ? 'providers' : 'categories');
Expand Down Expand Up @@ -105,4 +105,4 @@ export function withFindToolsNavigation(envelope: any) {
}

export const ALEXANDRIA_SEARCH_INSTRUCTIONS =
'Authenticated search combines web results, semantic tool summaries and domain matches. Use sources: ["alexandria"] for semantic tools only, or sources: ["web"] for web only. domainTools: false disables domain matching. Tool matches describe available structured-data capabilities, not executed data. toolDetail: "compact" (default) returns only provider, capability and description; "summary" adds metadata; "full" includes their input and output contracts. Execute a matched tool through firecrawl_scrape with an alexandria body; use firecrawl_find_tools to browse the catalogue or read a full contract.';
'Authenticated search combines web results, semantic tool summaries and domain matches. Use sources: ["alexandria"] for semantic tools only. ' + ALEXANDRIA_SOURCES_OPT_OUT + ' Tool matches describe available structured-data capabilities, not executed data. toolDetail: "compact" (default) returns only provider, capability and description; "summary" adds metadata; "full" includes their input and output contracts. firecrawl_scrape with an alexandria body executes a selected capability; firecrawl_find_tools provides catalogue browsing and full contracts.';

@cubic-dev-ai cubic-dev-ai Bot Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The firecrawl_search tool description still omits billing semantics, so full-profile users cannot tell that web, developer, and research searches are billed per request, Alexandria-only discovery is free, and scrape execution uses URL or listed capability pricing. Add that guidance here.

(Based on your team's feedback about search billing semantics.)

View Feedback

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/alexandria.ts, line 108:

<comment>The `firecrawl_search` tool description still omits billing semantics, so full-profile users cannot tell that web, developer, and research searches are billed per request, Alexandria-only discovery is free, and scrape execution uses URL or listed capability pricing. Add that guidance here.

(Based on your team's feedback about search billing semantics.) </comment>

<file context>
@@ -105,4 +105,4 @@ export function withFindToolsNavigation(envelope: any) {
 
 export const ALEXANDRIA_SEARCH_INSTRUCTIONS =
-  'Authenticated search combines web results, semantic tool summaries and domain matches. Use sources: ["alexandria"] for semantic tools only, or sources: ["web"] with domainTools: false for web only. Tool matches describe available structured-data capabilities, not executed data. toolDetail: "compact" (default) returns only provider, capability and description; "summary" adds metadata; "full" includes their input and output contracts. firecrawl_scrape with an alexandria body executes a selected capability; firecrawl_find_tools provides catalogue browsing and full contracts.';
+  'Authenticated search combines web results, semantic tool summaries and domain matches. Use sources: ["alexandria"] for semantic tools only. ' + ALEXANDRIA_SOURCES_OPT_OUT + ' Tool matches describe available structured-data capabilities, not executed data. toolDetail: "compact" (default) returns only provider, capability and description; "summary" adds metadata; "full" includes their input and output contracts. firecrawl_scrape with an alexandria body executes a selected capability; firecrawl_find_tools provides catalogue browsing and full contracts.';
</file context>
Fix with cubic

Loading
Loading