Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions packages/input_schema/src/input_schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ export { schema as inputSchema };

const { definitions } = schema;

// Because the definitions contain not only the root properties definitions, but also sub-schema definitions
// and utility definitions, we need to filter them out and validate only against the appropriate ones.
// We do this by checking the prefix of the definition title (Utils: or Sub-schema:)
// Because the definitions contain not only the root properties definitions, but also sub-schema definitions,
// utility definitions, and component definitions, we need to filter them out and validate only against the appropriate ones.
// We do this by checking the prefix of the definition title (Utils:, Component:, or Sub-schema:)

const [fieldDefinitions, subFieldDefinitions] = Object
.values<any>(definitions)
.reduce<[any[], any[]]>((acc, definition) => {
if (definition.title.startsWith('Utils:')) {
// skip utility definitions
if (definition.title.startsWith('Utils:') || definition.title.startsWith('Component:')) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have introduce new Component: prefix for reusable schemas for properties that does not really fit the Utils: classification (where errorMessage fits, but mcpProperty not so much).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe Utils: wasn't the greatest choice, but it's simply used for everything else then fields and subfields definitions => utility definitions.
I think introducing new "category" just for this and applying the exact logic as for Utils is not necessary.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not really opposed to using Utils: here. I think however, that it might be useful to have the Component: as with Utils: we would have both utility definitions and reusable sub-definitions semantically covered.

No hard opinion here tho.

// skip utility and component definitions
return acc;
}

Expand Down Expand Up @@ -271,8 +271,7 @@ function validateFieldAgainstSchemaDefinition(
}
// Otherwise we use the other definition.
const definition = matchingDefinitions.filter((item) => !item.properties.enum && !item.properties.resourceType).pop();
if (!definition) throw new Error('Input schema validation failed to find other than "enum property" definition');

if (!definition) throw new Error('Input schema validation failed to find other than "enum" or "resource" definition');
validateAgainstSchemaOrThrow(validator, fieldSchema, enhanceDefinition(definition), `schema.properties.${fieldKey}`);
}

Expand Down
30 changes: 28 additions & 2 deletions packages/input_schema/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,41 @@ export type ArrayFieldDefinition = CommonFieldDefinition<unknown[]> & {

export type CommonResourceFieldDefinition<T> = CommonFieldDefinition<T> & {
editor?: 'resourcePicker' | 'hidden';
resourceType: 'dataset' | 'keyValueStore' | 'requestQueue' | 'mcpConnector';
}

type StorageResourceFieldDefinition<T> = CommonResourceFieldDefinition<T> & {
resourceType: 'dataset' | 'keyValueStore' | 'requestQueue';
resourcePermissions?: ('READ' | 'WRITE')[];
}

export type ResourceFieldDefinition = CommonResourceFieldDefinition<string> & {
type McpServerTools = {
required?: readonly string[];
readOnly?: boolean;
destructive?: boolean;
idempotent?: boolean;
openWorld?: boolean;
}

type McpServer = {
url: string;
tools?: McpServerTools;
}

type McpConnectorResourceFieldDefinition<T> = CommonResourceFieldDefinition<T> & {
resourceType: 'mcpConnector';
mcpServers: readonly McpServer[];
}

type AnyResourceFieldDefinition<T> =
| StorageResourceFieldDefinition<T>
| McpConnectorResourceFieldDefinition<T>

export type ResourceFieldDefinition = AnyResourceFieldDefinition<string> & {
type: 'string';
}

export type ResourceArrayFieldDefinition = CommonResourceFieldDefinition<string[]> & {
export type ResourceArrayFieldDefinition = AnyResourceFieldDefinition<string[]> & {
type: 'array';
maxItems?: number;
minItems?: number;
Expand Down
446 changes: 312 additions & 134 deletions packages/json_schemas/output/actor.ide.json

Large diffs are not rendered by default.

446 changes: 312 additions & 134 deletions packages/json_schemas/output/input.ide.json

Large diffs are not rendered by default.

446 changes: 312 additions & 134 deletions packages/json_schemas/output/input.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,6 @@
format="markdown">
Titles for the `enum` keys described.
</AddDescription>
<AddDescription json-path="/definitions/resourceProperty/properties/resourcePermissions" format="markdown">
The provided documentation for Actor input schema specification does not contain a description for
`resourcePermissions` in the `resourceProperty` section. It is present in the JSON validation schema, indicating
permissions for the resource.
</AddDescription>
<AddDescription json-path="/definitions/resourceArrayProperty/properties/resourcePermissions" format="markdown">
The provided documentation for Actor input schema specification does not contain a description for
`resourcePermissions` in the `resourceArrayProperty` section. It is present in the JSON validation schema,
indicating permissions for the resource array.
</AddDescription>
<AddDescription json-path="/definitions/anyProperty/properties/type" format="markdown">
Allowed type for the input value. Cannot be mixed.
</AddDescription>
Expand Down Expand Up @@ -555,7 +545,7 @@
Visual editor used for the input field. Defaults to `resourcePicker`.
</AddDescription>
<AddDescription json-path="/definitions/resourceProperty/properties/resourceType" format="markdown">
Type of Apify Platform resource
Type of Apify resource this field references - a storage resource (`dataset`, `keyValueStore`, `requestQueue`) or an `mcpConnector`.
</AddDescription>
<AddDescription json-path="/definitions/resourceProperty/properties/default" format="markdown">
Default value that will be used when no value is provided.
Expand Down Expand Up @@ -612,7 +602,7 @@
Specifies whether the array should contain only unique values.
</AddDescription>
<AddDescription json-path="/definitions/resourceArrayProperty/properties/resourceType" format="markdown">
Type of Apify Platform resource
Type of Apify resource this field references - a storage resource (`dataset`, `keyValueStore`, `requestQueue`) or an `mcpConnector`.
</AddDescription>
<AddDescription json-path="/definitions/resourceArrayProperty/properties/sectionCaption" format="markdown">
If this property is set, then all fields following this field (this field included) will be separated into a
Expand All @@ -623,6 +613,21 @@
If the `sectionCaption` property is set, then you can use this property to provide additional description to the
section. The description will be visible right under the caption when the section is open.
</AddDescription>
<AddDescription json-path="/definitions/resourcePermissionsProperty" format="markdown">
Permissions required for the resource. Only applicable when `resourceType` is `dataset`, `keyValueStore`, or `requestQueue`.
</AddDescription>
<AddDescription json-path="/definitions/mcpServersProperty" format="markdown">
Defines which MCP servers this Actor works with. Each entry describes an acceptable server - a connector can be selected for this input only if it matches at least one entry. Required when `resourceType` is `mcpConnector`.
</AddDescription>
<AddDescription json-path="/definitions/mcpServersProperty/items" format="markdown">
An acceptable MCP server profile. A connector matches if the URL of the server it targets matches `url` and it provides the tools described in `tools`.
</AddDescription>
<AddDescription json-path="/definitions/mcpServersProperty/items/properties/url" format="markdown">
URL pattern that connector's targeted MCP server must match. Supports `*` and `?` wildcards. Use `"*"` to accept any server.
</AddDescription>
<AddDescription json-path="/definitions/mcpServersProperty/items/properties/tools" format="markdown">
Defines which tools the Actor needs and gets access to. `required` lists tool name patterns (supports `*` and `?` wildcards) - the connector must authorize at least one matching tool per pattern. Hint booleans further restrict which tools are considered. Only matching tools are exposed to the Actor.
</AddDescription>
<AddDescription json-path="/definitions/anyProperty/properties/title" format="markdown">
Title of the field in UI.
</AddDescription>
Expand Down
Loading