-
Notifications
You must be signed in to change notification settings - Fork 213
feat: Surface compact input schema on search-actors results #737
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
b4e23ca
feat: Surface compact input schema on search-actors results
MQ37 f44962c
fix: Drop limit cap, drop rental over-fetch, add observability log
MQ37 a1b1bb0
chore: Render full inputSchema in text card, rename "Input fields" to…
MQ37 028d158
chore: Trim PR comments and redundant tests
MQ37 c04d43a
fix: Clamp `limit` to STORE_INPUT_SCHEMA_PAGE_LIMIT when includeInput…
MQ37 a12ffdd
feat: Trim text inputSchema to 20 fields with `... (+N more)` suffix
MQ37 6106ffb
feat: Cap search-actors limit at 10 and drop rental observability check
MQ37 a7c9d05
revert: Drop "constants in src/const.ts" CLAUDE.md rule
MQ37 cfe7260
refactor: Rename STORE_INPUT_SCHEMA_* constants
MQ37 5c79c36
fix(actor_search): Throw on incompatible limit + includeInputSchema c…
MQ37 3120d46
refactor: Rename LLM-facing "input schema" to "input fields"
MQ37 2c22b9f
test(actor_search): Replace double-cast factory with typed defaults +…
MQ37 8824929
test(actor_card): Fix misleading truncation test + add real coverage
MQ37 48706f5
refactor: Rename structured `inputSchema` -> `inputFields` and trim r…
MQ37 a2be576
test(integration): Update rental Actors test for the new `limit` cap
MQ37 df9148a
test(actor_card): Drop redundant boundary test, fold negative asserti…
MQ37 777419a
refactor(search): rename searchAndFilterActors -> searchAgentSafeActors
MQ37 b6833fe
docs(search-actors): drop stale rental-filter caveat from tool descri…
MQ37 ea5182b
refactor(schemas): encode inputFields shape on actorInfoSchema
MQ37 b9ac04f
Update src/tools/core/search_actors_common.ts
MQ37 4bf8cad
Update src/const.ts
MQ37 3f80672
refactor(actor-search): rename text-card field cap and require limit
MQ37 3ca6cba
refactor(actor-search): drop client-side limit cap throw, let API enf…
MQ37 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,87 +1,64 @@ | ||
| /** | ||
| * Shared utility for searching and filtering actors. | ||
| * Combines searchActorsByKeywords with filterRentalActors to prevent accidental omission | ||
| * of the filtering step and reduce code duplication. | ||
| * Shared utility for searching Actors via `GET /v2/store`. | ||
| * | ||
| * `GET /v2/store` returns only `[FREE, PAY_PER_EVENT]` Actors by default | ||
| * (apify-core's `AGENT_SAFE_PRICING_MODELS`) and additionally drops Actors | ||
| * that fail safety checks (KYC, full-permission low-usage, etc.) — so no | ||
| * MCP-side rental over-fetch / filter is needed. | ||
| */ | ||
|
|
||
| import { ApifyClient } from '../apify_client.js'; | ||
| import { ACTOR_PRICING_MODEL } from '../const.js'; | ||
| import type { PaymentProvider } from '../payments/types.js'; | ||
| import type { ActorStoreList } from '../types.js'; | ||
|
|
||
| /** | ||
| * Used in search Actors tool to search above the input supplied limit, | ||
| * so we can safely filter out rental Actors from the search and ensure we return some results. | ||
| */ | ||
| const ACTOR_SEARCH_ABOVE_LIMIT = 50; | ||
| type ActorPricingModel = (typeof ACTOR_PRICING_MODEL)[keyof typeof ACTOR_PRICING_MODEL]; | ||
| export type SearchActorsByKeywordsOptions = { | ||
| search: string; | ||
| apifyToken: string; | ||
| limit: number; | ||
| offset?: number; | ||
| allowsAgenticUsers?: boolean; | ||
| /** API rejects values above `MAX_LIMIT_WITH_INPUT_SCHEMA` (apify-core cap). */ | ||
| includeInputSchema?: boolean; | ||
| }; | ||
|
|
||
| export type SearchAndFilterActorsOptions = { | ||
| export type SearchAgentSafeActorsOptions = { | ||
| keywords: string; | ||
| apifyToken: string; | ||
| limit: number; | ||
| offset: number; | ||
| paymentProvider?: PaymentProvider; | ||
| userRentedActorIds?: string[]; | ||
| }; | ||
|
|
||
| export async function searchActorsByKeywords( | ||
| search: string, | ||
| apifyToken: string, | ||
| limit: number | undefined = undefined, | ||
| offset: number | undefined = undefined, | ||
| allowsAgenticUsers: boolean | undefined = undefined, | ||
| options: SearchActorsByKeywordsOptions, | ||
| ): Promise<ActorStoreList[]> { | ||
| const { search, apifyToken, limit, offset, allowsAgenticUsers, includeInputSchema } = options; | ||
| const client = new ApifyClient({ token: apifyToken }); | ||
| const storeClient = client.store(); | ||
| if (allowsAgenticUsers !== undefined) storeClient.params = { ...storeClient.params, allowsAgenticUsers }; | ||
| if (includeInputSchema !== undefined) storeClient.params = { ...storeClient.params, includeInputSchema }; | ||
|
|
||
| const results = await storeClient.list({ search, limit, offset }); | ||
| return results.items as ActorStoreList[]; | ||
| } | ||
|
|
||
| /** | ||
| * Search actors by keywords and filter rental actors. | ||
| * This combines two operations that should always happen together to ensure consistency. | ||
| * | ||
| * @param options Search and filter options | ||
| * @returns Array of filtered actors, limited to the specified limit | ||
| * Preset around `searchActorsByKeywords` for the agent-facing search tool: | ||
| * always sets `includeInputSchema=true` and forwards `allowsAgenticUsers` | ||
| * when a `paymentProvider` is in play. The public arg schema caps `limit` | ||
| * at apify-core's hard cap (`MAX_LIMIT_WITH_INPUT_SCHEMA`). | ||
| */ | ||
| export async function searchAndFilterActors( | ||
| options: SearchAndFilterActorsOptions, | ||
| export async function searchAgentSafeActors( | ||
| options: SearchAgentSafeActorsOptions, | ||
| ): Promise<ActorStoreList[]> { | ||
| const { keywords, apifyToken, limit, offset, paymentProvider, userRentedActorIds } = options; | ||
| const { keywords, apifyToken, limit, offset, paymentProvider } = options; | ||
|
|
||
| const actors = await searchActorsByKeywords( | ||
| keywords, | ||
| return searchActorsByKeywords({ | ||
| search: keywords, | ||
| apifyToken, | ||
| limit + ACTOR_SEARCH_ABOVE_LIMIT, | ||
| limit, | ||
| offset, | ||
| paymentProvider ? true : undefined, | ||
| ); | ||
|
|
||
| return filterRentalActors(actors || [], userRentedActorIds || []).slice(0, limit) as ActorStoreList[]; | ||
| } | ||
|
|
||
| /** | ||
| * Filters out actors with the 'FLAT_PRICE_PER_MONTH' pricing model (rental actors), | ||
| * unless the actor's ID is present in the user's rented actor IDs list. | ||
| * | ||
| * This is necessary because the Store list API does not support filtering by multiple pricing models at once. | ||
| * | ||
| * @param actors - Array of ActorStorePruned objects to filter. | ||
| * @param userRentedActorIds - Array of Actor IDs that the user has rented. | ||
| * @returns Array of Actors excluding those with 'FLAT_PRICE_PER_MONTH' pricing model (= rental Actors), | ||
| * except for Actors that the user has rented (whose IDs are in userRentedActorIds). | ||
| */ | ||
| export function filterRentalActors( | ||
| actors: ActorStoreList[], | ||
| userRentedActorIds: string[], | ||
| ): ActorStoreList[] { | ||
| // Store list API does not support filtering by two pricing models at once, | ||
| // so we filter the results manually after fetching them. | ||
| return actors.filter((actor) => ( | ||
| actor.currentPricingInfo.pricingModel as ActorPricingModel) !== ACTOR_PRICING_MODEL.FLAT_PRICE_PER_MONTH | ||
| || userRentedActorIds.includes(actor.id), | ||
| ); | ||
| allowsAgenticUsers: paymentProvider ? true : undefined, | ||
| includeInputSchema: true, | ||
| }); | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.