You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 1f421e1
Browse filesBrowse the repository at this point in the historyBrowse files
fix: Apply direct Actor input contracts consistently (#1585)
## Why
Closes#1574. Closes#1575. Supersedes #1580 and #1581.
WCC's API defaults robots.txt handling to false. Its direct MCP tool
also accepts page code and session cookies, preventing read-only
classification under the existing rule.
## What changed
One declarative direct-tool policy controls defaults, denied inputs, and
restriction text. The factory derives annotations from permitted inputs
while retaining ownership, permission, and side-effect checks.
For `apify--website-content-crawler`, robots.txt defaults to true and
explicit false remains valid. `pageFunction` and `initialCookies` are
absent from the offered properties, and the call engine refuses a call
that carries either before validation runs, so no run starts even when
AJV would otherwise strip an undeclared field. The served schema stays a
plain object: OpenAI rejects a function schema with `allOf`, `anyOf`,
`oneOf` or `not` at the top level, strict or not.
Generic calls, widgets, and Actor details keep the original Actor input
contract. Restricted direct-tool errors point to their own tools/list
schema. Other Actors are unchanged.
Contract change: WCC's direct input schema, description, validation, and
annotations. Applies to the hosted server through the core package; no
internal exports, shared types, result shapes, or client-specific
routing changed.
## Notes for reviewers (human-written)
## Proof it works
- New regression tests failed before implementation. Final suite: 2,661
passed, 1 skipped. Type-check, lint, format, check:agents, and build
passed.
- mcpc on the local build: WCC has read-only/non-destructive/open-world
annotations; the three other direct tools retain their annotations. Both
denied fields were refused with an error naming them, and no run
started. Other validation errors point to tools/list.
`fetch-actor-details` and a `call-actor` validation error still show the
original schema with both fields and `default: false`.
- The exact served WCC schema is accepted by OpenAI's Responses API
(HTTP 200). The earlier `allOf` version was refused with HTTP 400
("schema must have type 'object' and not have
'oneOf'/'anyOf'/'allOf'/'enum'/'const'/'not' at the top level").
- One-page [Actor
run](https://console.apify.com/actors/runs/iaftEn6QeCMUKorMX) succeeded
with the robots.txt field omitted. `apify key-value-stores get-value
qEgw9ZA6yIZ6u5WQh INPUT` confirmed `respectRobotsTxtFile: true`. A
second one-page run on the final head (`ykzc28KDS26DtXPq1`) stored
`respectRobotsTxtFile: true` in `vXvkNIfxOm7acBeWl` with neither denied
field present.
- Generic and widget regression tests use the real factory and
validator, including lookup by Actor ID, to verify original
inputs/defaults and error schemas.
AI-assisted: Codex wrote the implementation, tests, documentation, and
this description, ran verification, and used an independent review
agent. Claude Code reviewed the PR, replaced the schema-level `allOf`
denial with the call-engine check after finding the OpenAI rejection,
and reran the mcpc checks and the second run.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -315,9 +315,11 @@ Legend for the **Enabled by default** column:
315
315
All tools include metadata annotations to help MCP clients and LLMs understand tool behavior:
316
316
317
317
-**`title`**: Short display name for the tool (e.g., "Search Actors", "Call Actor", "apify/rag-web-browser")
318
-
-**`readOnlyHint`**: `true` for tools that only read data without modifying state (e.g., `get-dataset`, `fetch-actor-details`). Actor tools get it only for Apify-maintained Actors with limited permissions and no secret, writable storage, MCP connector, or code input (e.g., `apify--web-fetch`); other Actor tools are marked destructive.
318
+
-**`readOnlyHint`**: `true` for tools that only read data without modifying state (e.g., `get-dataset`, `fetch-actor-details`). Actor tools get it only for Apify-maintained Actors with limited permissions and no accepted secret, writable storage, MCP connector, or code input (e.g., `apify--web-fetch`). Direct tools can restrict the original Actor inputs: `apify--website-content-crawler` excludes and rejects `pageFunction` and `initialCookies`, so it is read-only. Other Actor tools are marked destructive.
319
319
-**`openWorldHint`**: `true` for tools that access external resources outside the Apify platform (e.g., `call-actor` executes external Actors). Tools that interact only with the Apify platform (like `search-actors` or `fetch-apify-docs`) do not have this hint.
320
320
321
+
The direct `apify--website-content-crawler` tool defaults `respectRobotsTxtFile` to `true`; an explicit `false` is preserved. These restrictions and defaults apply only to the direct tool. `call-actor`, `call-actor-widget`, and `fetch-actor-details` retain the original Actor input contract.
322
+
321
323
### Tools configuration
322
324
323
325
The `tools` configuration parameter is used to specify loaded tools – either categories or specific tools directly, and Apify Actors. For example, `tools=storage,runs` loads two categories; `tools=call-actor` loads just one tool.
return`${list}${verb} not accepted by this tool, although the Actor supports ${pronoun}${reason ? `: ${reason}` : ''}, so this tool rejects ${pronoun}.`;
48
+
}
49
+
50
+
/**
51
+
* Denied inputs are absent from the served schema, but AJV keeps undeclared fields unless the Actor's
52
+
* schema sets `additionalProperties: false`, in which case it strips them. Either way the run would
53
+
* proceed, so the call is checked before validation.
0 commit comments