Skip to content

Commit 152048e

Browse files
committed
fix: type errors
1 parent 4dbd41d commit 152048e

File tree

8 files changed

+25
-28
lines changed

8 files changed

+25
-28
lines changed

src/tools/actor.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { getActorMCPServerPath, getActorMCPServerURL } from '../mcp/actors.js';
1717
import { connectMCPClient } from '../mcp/client.js';
1818
import { getMCPServerTools } from '../mcp/proxy.js';
1919
import { actorDefinitionPrunedCache } from '../state.js';
20-
import type { ActorDefinitionStorage, ActorInfo, ApifyToken, DatasetItem, ToolEntry } from '../types.js';
20+
import type { ActorDefinitionStorage, ActorInfo, ApifyToken, DatasetItem, IActorInputSchema, ToolEntry } from '../types.js';
2121
import { ensureOutputWithinCharLimit, getActorDefinitionStorageFieldNames, getActorMcpUrlCached } from '../utils/actor.js';
2222
import { fetchActorDetails } from '../utils/actor-details.js';
2323
import { buildActorResponseContent } from '../utils/actor-response.js';
@@ -389,7 +389,7 @@ The step parameter enforces this workflow - you cannot call an Actor without fir
389389
client = await connectMCPClient(mcpServerUrl, apifyToken);
390390
const toolsResponse = await client.listTools();
391391

392-
const toolsInfo = toolsResponse.tools.map((tool) => `**${tool.name}**\n${tool.description || 'No description'}\n\n${jsonSchemaToMarkdown(tool.inputSchema)}`,
392+
const toolsInfo = toolsResponse.tools.map((tool) => `**${tool.name}**\n${tool.description || 'No description'}\n\n${jsonSchemaToMarkdown(tool.inputSchema as IActorInputSchema)}`,
393393
).join('\n\n');
394394

395395
return buildMCPResponse([`This is an MCP Server Actor with the following tools:\n\n${toolsInfo}\n\nTo call a tool, use step="call" with actor name format: "${baseActorName}:{toolName}"`]);
@@ -479,7 +479,7 @@ The step parameter enforces this workflow - you cannot call an Actor without fir
479479
if (errors && errors.length > 0) {
480480
return buildMCPResponse([
481481
`Input validation failed for Actor '${actorName}': ${errors.map((e) => e.message).join(', ')}`,
482-
jsonSchemaToMarkdown(actor.tool.inputSchema),
482+
jsonSchemaToMarkdown(actor.tool.inputSchema as IActorInputSchema),
483483
]);
484484
}
485485
}

src/tools/build.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { ACTOR_README_MAX_LENGTH, HelperTools } from '../const.js';
88
import type {
99
ActorDefinitionPruned,
1010
ActorDefinitionWithDesc,
11+
IActorInputSchema,
1112
InternalTool,
1213
ISchemaProperties,
1314
ToolEntry,
@@ -132,7 +133,7 @@ export const actorDefinitionTool: ToolEntry = {
132133
const properties = filterSchemaProperties(v.input.properties as { [key: string]: ISchemaProperties });
133134
v.input.properties = shortenProperties(properties);
134135
}
135-
return { content: [{ type: 'text', text: jsonSchemaToMarkdown(v.input) }] };
136+
return { content: [{ type: 'text', text: jsonSchemaToMarkdown((v.input || {}) as IActorInputSchema) }] };
136137
},
137138
} as InternalTool,
138139
};

src/tools/dataset.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { HelperTools } from '../const.js';
66
import type { InternalTool, ToolEntry } from '../types.js';
77
import { ajv } from '../utils/ajv.js';
88
import { parseCommaSeparatedList } from '../utils/generic.js';
9-
import { jsonSchemaToMarkdown } from '../utils/json-schema-to-markdown.js';
109
import { jsonToMarkdown } from '../utils/json-to-markdown.js';
1110
import { generateSchemaFromItems } from '../utils/schema-generation.js';
1211

@@ -178,7 +177,7 @@ export const getDatasetSchema: ToolEntry = {
178177
return {
179178
content: [{
180179
type: 'text',
181-
text: jsonSchemaToMarkdown(schema),
180+
text: JSON.stringify(schema), // TODO: jsonSchemaToMarkdown don't have implemented array support
182181
}],
183182
};
184183
},

src/tools/key_value_store.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export const getKeyValueStore: ToolEntry = {
3131
const parsed = getKeyValueStoreArgs.parse(args);
3232
const client = new ApifyClient({ token: apifyToken });
3333
const store = await client.keyValueStore(parsed.storeId).get();
34-
return { content: [{ type: 'text', text: jsonToMarkdown(store) }] };
34+
return { content: [{ type: 'text', text: store ? jsonToMarkdown(store) : 'Value not found' }] };
3535
},
3636
} as InternalTool,
3737
};
@@ -105,7 +105,7 @@ export const getKeyValueStoreRecord: ToolEntry = {
105105
const parsed = getKeyValueStoreRecordArgs.parse(args);
106106
const client = new ApifyClient({ token: apifyToken });
107107
const record = await client.keyValueStore(parsed.storeId).getRecord(parsed.recordKey);
108-
return { content: [{ type: 'text', text: jsonToMarkdown(record) }] };
108+
return { content: [{ type: 'text', text: record ? jsonToMarkdown(record) : 'Value not found' }] };
109109
},
110110
} as InternalTool,
111111
};

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export interface ISchemaProperties {
1919
enumTitles?: string[]; // Array of string titles for the enum
2020
default?: unknown;
2121
prefill?: unknown;
22+
format?: string;
2223

2324
items?: ISchemaProperties;
2425
editor?: string;

src/utils/actor-response.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { CallActorGetDatasetResult } from '../tools/actor.js';
2-
import { jsonSchemaToMarkdown } from './json-schema-to-markdown.js';
2+
import { jsonToMarkdown } from './json-to-markdown.js';
33

44
/**
55
* Builds the response content for Actor tool calls.
@@ -38,16 +38,17 @@ Results summary:
3838
3939
Actor output data schema:
4040
* You can use this schema to understand the structure of the output data and, for example, retrieve specific fields based on your current task.
41-
42-
${jsonSchemaToMarkdown(displaySchema)}
41+
\`\`\`json
42+
${JSON.stringify(displaySchema, null, 2)}
43+
\`\`\`
4344
4445
Above this text block is a preview of the Actor output containing ${result.previewItems.length} item(s).${itemCount !== result.previewItems.length ? ` You have access only to a limited preview of the Actor output. Do not present this as the full output, as you have only ${result.previewItems.length} item(s) available instead of the full ${itemCount} item(s). Be aware of this and inform users about the currently loaded count and the total available output items count.` : ''}
4546
4647
If you need to retrieve additional data, use the "get-actor-output" tool with: datasetId: "${datasetId}". Be sure to limit the number of results when using the "get-actor-output" tool, since you never know how large the items may be, and they might exceed the output limits.
4748
`;
4849

4950
const itemsPreviewText = result.previewItems.length > 0
50-
? JSON.stringify(result.previewItems)
51+
? jsonToMarkdown(result.previewItems)
5152
: `No items available for preview—either the Actor did not return any items or they are too large for preview. In this case, use the "get-actor-output" tool.`;
5253

5354
// Build content array

src/utils/json-schema-to-markdown.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import type { IActorInputSchema } from '../types';
1+
import type { IActorInputSchema, ISchemaProperties } from '../types';
22

33
function visibleEmpty(value: string) {
44
return value === '' ? '<empty>' : value;
55
}
66

7-
function formatProperty(key: string, value: any, requiredFields: Set<string>, level = 2): string {
7+
function formatProperty(key: string, value: ISchemaProperties, requiredFields: Set<string>, level = 2): string {
88
const isRequired = requiredFields.has(key);
99
const requiredText = isRequired ? 'required' : 'optional';
1010

@@ -53,7 +53,7 @@ function formatProperty(key: string, value: any, requiredFields: Set<string>, le
5353
}
5454

5555
export function jsonSchemaToMarkdown(inputSchema: IActorInputSchema) {
56-
const requiredFields = new Set(inputSchema.required || []);
56+
const requiredFields = new Set(Array.isArray(inputSchema.required) ? inputSchema.required : []);
5757

5858
let markdown = '# JSON Schema';
5959
if (inputSchema.description) {
@@ -62,7 +62,7 @@ export function jsonSchemaToMarkdown(inputSchema: IActorInputSchema) {
6262
}
6363
markdown += '\n\n'; // Add blank line after title/description
6464

65-
const properties = Object.entries(inputSchema.properties);
65+
const properties = inputSchema.properties ? Object.entries(inputSchema.properties) : [];
6666
for (let i = 0; i < properties.length; i++) {
6767
const [key, value] = properties[i];
6868
markdown += formatProperty(key, value, requiredFields);

src/utils/json-to-markdown.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
type JSON = string | number | boolean | null | JSON[] | { [key: string]: JSON };
1+
type JSON = string | number | boolean | null | JSON[] | object;
22

33
function isEmpty(json: JSON): boolean {
44
return (
@@ -74,17 +74,12 @@ function simplifyJson(json: JSON): JSON {
7474

7575
function serializeJsonTopLevel(json: JSON): string {
7676
switch (typeOfJson(json)) {
77+
case 'null':
78+
return '';
7779
case 'string':
7880
case 'number':
7981
case 'boolean':
8082
return String(json);
81-
case 'null':
82-
return '';
83-
case 'object':
84-
return serializeJson(json, 0);
85-
case 'array-simple':
86-
case 'array-mixed':
87-
return serializeJson(json, 0);
8883
case 'array-object':
8984
return (json as JSON[]).map((unknownItem, index) => {
9085
const item = unknownItem as Record<string, object>;
@@ -117,8 +112,8 @@ function serializeJson(json: JSON, pad: number): string {
117112
return pad === 0 ? getIndent(pad, true) + String(json) : String(json);
118113
case 'object':
119114
return Object.entries(json as Record<string, JSON>)
120-
.filter(([key, value]) => !isEmpty(value))
121-
.map(([key, value], index) => {
115+
.filter(([_key, value]) => !isEmpty(value))
116+
.map(([key, value]) => {
122117
const indentLevel = pad;
123118
const prefix = `${getIndent(indentLevel, true)}${key}:`;
124119
if (isOneLiner(value)) {
@@ -137,7 +132,7 @@ function serializeJson(json: JSON, pad: number): string {
137132
}
138133
if (itemType === 'object') {
139134
return Object.entries(unknownItem as Record<string, JSON>)
140-
.filter(([key, value]) => !isEmpty(value))
135+
.filter(([_key, value]) => !isEmpty(value))
141136
.map(([key, value], index) => {
142137
const prefix = `${getIndent(pad, index === 0)}${key}:`;
143138
if (isOneLiner(value)) {
@@ -152,7 +147,7 @@ function serializeJson(json: JSON, pad: number): string {
152147
case 'array-object':
153148
return (json as JSON[]).filter(isNotEmpty).map((unknownItem) => {
154149
return Object.entries(unknownItem as Record<string, JSON>)
155-
.filter(([key, value]) => !isEmpty(value))
150+
.filter(([_key, value]) => !isEmpty(value))
156151
.map(([key, value], index) => {
157152
const indentLevel = pad === 1 ? 1 : pad;
158153
const withBullet = pad === 1 ? index === 0 : true;

0 commit comments

Comments
 (0)