@llmindset/hf-mcp 0.2.36 → 0.2.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/jobs/api-client.d.ts.map +1 -1
- package/dist/jobs/api-client.js.map +1 -1
- package/dist/jobs/commands/run.d.ts.map +1 -1
- package/dist/jobs/commands/run.js +2 -13
- package/dist/jobs/commands/run.js.map +1 -1
- package/dist/jobs/commands/scheduled.d.ts.map +1 -1
- package/dist/jobs/commands/scheduled.js +2 -12
- package/dist/jobs/commands/scheduled.js.map +1 -1
- package/dist/jobs/commands/uv-utils.d.ts +3 -1
- package/dist/jobs/commands/uv-utils.d.ts.map +1 -1
- package/dist/jobs/commands/uv-utils.js +19 -3
- package/dist/jobs/commands/uv-utils.js.map +1 -1
- package/dist/jobs/{tool.d.ts → jobs-tool.d.ts} +2 -3
- package/dist/jobs/jobs-tool.d.ts.map +1 -0
- package/dist/jobs/{tool.js → jobs-tool.js} +103 -44
- package/dist/jobs/jobs-tool.js.map +1 -0
- package/dist/jobs/schema-help.d.ts +22 -0
- package/dist/jobs/schema-help.d.ts.map +1 -0
- package/dist/jobs/schema-help.js +155 -0
- package/dist/jobs/schema-help.js.map +1 -0
- package/dist/jobs/types.d.ts +0 -6
- package/dist/jobs/types.d.ts.map +1 -1
- package/dist/jobs/types.js +13 -14
- package/dist/jobs/types.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/jobs/api-client.ts +0 -2
- package/src/jobs/commands/run.ts +2 -15
- package/src/jobs/commands/scheduled.ts +2 -11
- package/src/jobs/commands/uv-utils.ts +25 -4
- package/src/jobs/{tool.ts → jobs-tool.ts} +112 -44
- package/src/jobs/schema-help.ts +230 -0
- package/src/jobs/types.ts +14 -14
- package/dist/jobs/tool.d.ts.map +0 -1
- package/dist/jobs/tool.js.map +0 -1
|
@@ -14,7 +14,9 @@ import {
|
|
|
14
14
|
scheduledSuspendCommand,
|
|
15
15
|
scheduledResumeCommand,
|
|
16
16
|
} from './commands/scheduled.js';
|
|
17
|
+
import { formatCommandHelp } from './schema-help.js';
|
|
17
18
|
import type { ToolResult } from '../types/tool-result.js';
|
|
19
|
+
import { CPU_FLAVORS, GPU_FLAVORS, SPECIALIZED_FLAVORS } from './types.js';
|
|
18
20
|
import type {
|
|
19
21
|
RunArgs,
|
|
20
22
|
UvArgs,
|
|
@@ -65,6 +67,37 @@ const COMMAND_SCHEMAS = {
|
|
|
65
67
|
'scheduled resume': scheduledJobArgsSchema,
|
|
66
68
|
} as const;
|
|
67
69
|
|
|
70
|
+
const HELP_FLAG = 'help';
|
|
71
|
+
|
|
72
|
+
const CPU_FLAVOR_LIST = CPU_FLAVORS.join(', ');
|
|
73
|
+
const GPU_FLAVOR_LIST = GPU_FLAVORS.join(', ');
|
|
74
|
+
const SPECIALIZED_FLAVOR_LIST = SPECIALIZED_FLAVORS.join(', ');
|
|
75
|
+
const HARDWARE_FLAVORS_SECTION = [
|
|
76
|
+
`**CPU:** ${CPU_FLAVOR_LIST}`,
|
|
77
|
+
GPU_FLAVORS.length ? `**GPU:** ${GPU_FLAVOR_LIST}` : undefined,
|
|
78
|
+
SPECIALIZED_FLAVORS.length ? `**Specialized:** ${SPECIALIZED_FLAVOR_LIST}` : undefined,
|
|
79
|
+
]
|
|
80
|
+
.filter((line): line is string => Boolean(line))
|
|
81
|
+
.join('\n');
|
|
82
|
+
|
|
83
|
+
function isHelpRequested(args: Record<string, unknown> | undefined): boolean {
|
|
84
|
+
if (!args) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const helpValue = args[HELP_FLAG];
|
|
89
|
+
return helpValue === true || helpValue === 'true';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function removeHelpFlag(args: Record<string, unknown> | undefined): Record<string, unknown> {
|
|
93
|
+
if (!args || !(HELP_FLAG in args)) {
|
|
94
|
+
return args ?? {};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const { [HELP_FLAG]: _ignored, ...rest } = args;
|
|
98
|
+
return rest;
|
|
99
|
+
}
|
|
100
|
+
|
|
68
101
|
/**
|
|
69
102
|
* Validate command arguments against a Zod schema
|
|
70
103
|
* Returns a ToolResult with detailed error message if validation fails
|
|
@@ -104,13 +137,7 @@ function validateArgs(
|
|
|
104
137
|
errorMessage += `Invalid parameters:\n${invalidFields.join('\n')}\n\n`;
|
|
105
138
|
}
|
|
106
139
|
|
|
107
|
-
|
|
108
|
-
const providedKeys = args && typeof args === 'object' ? Object.keys(args) : [];
|
|
109
|
-
if (providedKeys.length > 0) {
|
|
110
|
-
errorMessage += `You provided: ${JSON.stringify(args, null, 2)}`;
|
|
111
|
-
} else {
|
|
112
|
-
errorMessage += `You provided: {} (no parameters)`;
|
|
113
|
-
}
|
|
140
|
+
errorMessage += `Call hf_jobs("${commandName}", {"help": true}) to see valid arguments.`;
|
|
114
141
|
|
|
115
142
|
return {
|
|
116
143
|
success: false,
|
|
@@ -153,21 +180,15 @@ Manage compute jobs on Hugging Face infrastructure.
|
|
|
153
180
|
|
|
154
181
|
### Run a simple job
|
|
155
182
|
\`\`\`
|
|
156
|
-
# Command as array (recommended, especially for complex commands)
|
|
157
183
|
hf_jobs("run", {
|
|
158
184
|
"image": "python:3.12",
|
|
159
185
|
"command": ["python", "-c", "print('Hello from HF Jobs!')"],
|
|
160
186
|
"flavor": "cpu-basic"
|
|
161
187
|
})
|
|
188
|
+
\`\`\`
|
|
162
189
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
"image": "python:3.12",
|
|
166
|
-
"command": "python -c \\"print('Hello world!')\\"",
|
|
167
|
-
"flavor": "cpu-basic"
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
# Use a Hugging Face Space as the image
|
|
190
|
+
### Use a Hugging Face Space as the image
|
|
191
|
+
\`\`\`
|
|
171
192
|
hf_jobs("run", {
|
|
172
193
|
"image": "hf.co/spaces/username/spacename",
|
|
173
194
|
"command": ["python", "app.py"],
|
|
@@ -177,7 +198,6 @@ hf_jobs("run", {
|
|
|
177
198
|
|
|
178
199
|
### Run multiline Python scripts
|
|
179
200
|
\`\`\`
|
|
180
|
-
# Use array format with newlines in the -c argument
|
|
181
201
|
hf_jobs("run", {
|
|
182
202
|
"image": "python:3.12",
|
|
183
203
|
"command": ["python", "-c", "import sys\\nprint('Line 1')\\nprint('Line 2')"],
|
|
@@ -185,11 +205,29 @@ hf_jobs("run", {
|
|
|
185
205
|
})
|
|
186
206
|
\`\`\`
|
|
187
207
|
|
|
208
|
+
### Run a Python Script from a URL with UV
|
|
209
|
+
\`\`\`
|
|
210
|
+
hf_jobs("uv", {
|
|
211
|
+
"script": "https://huggingface.co/datasets/uv-scripts/classification/blob/main/classify-dataset.py",
|
|
212
|
+
"with_deps": ["pandas"],
|
|
213
|
+
"script_args": ["--input", "data.csv"],
|
|
214
|
+
"flavor": "cpu-basic"
|
|
215
|
+
})
|
|
216
|
+
\`\`\`
|
|
217
|
+
|
|
218
|
+
### Run an inline Python script with UV
|
|
219
|
+
\`\`\`
|
|
220
|
+
hf_jobs("uv", {
|
|
221
|
+
"script": "import math\\nprint('area:', math.pi * 4**2)"
|
|
222
|
+
})
|
|
223
|
+
\`\`\`
|
|
224
|
+
|
|
225
|
+
|
|
188
226
|
### Run bash/shell commands
|
|
189
227
|
\`\`\`
|
|
190
228
|
hf_jobs("run", {
|
|
191
229
|
"image": "ubuntu:22.04",
|
|
192
|
-
"command": ["
|
|
230
|
+
"command": ["/bin/sh", "-lc", "apt-get update && apt-get install -y curl"],
|
|
193
231
|
"flavor": "cpu-basic"
|
|
194
232
|
})
|
|
195
233
|
\`\`\`
|
|
@@ -222,36 +260,48 @@ hf_jobs("scheduled run", {
|
|
|
222
260
|
})
|
|
223
261
|
\`\`\`
|
|
224
262
|
|
|
263
|
+
### Schedule a UV script
|
|
264
|
+
\`\`\`
|
|
265
|
+
hf_jobs("scheduled uv", {
|
|
266
|
+
"schedule": "0 9 * * 1-5",
|
|
267
|
+
"script": "https://huggingface.co/datasets/uv-scripts/classification/blob/main/classify-dataset.py",
|
|
268
|
+
"with_deps": ["pandas"],
|
|
269
|
+
"script_args": ["--input", "data.csv"]
|
|
270
|
+
})
|
|
271
|
+
\`\`\`
|
|
272
|
+
|
|
225
273
|
## Hardware Flavors
|
|
226
274
|
|
|
227
|
-
|
|
228
|
-
**GPU:** t4-small, t4-medium, l4x1, a10g-small, a10g-large, a100-large, h100
|
|
229
|
-
**Specialized:** inf2x6 (AWS Inferentia)
|
|
275
|
+
${HARDWARE_FLAVORS_SECTION}
|
|
230
276
|
|
|
231
277
|
## Command Format Guidelines
|
|
232
278
|
|
|
233
|
-
**Array format (
|
|
234
|
-
-
|
|
235
|
-
-
|
|
236
|
-
- Works with any language: Python, bash, npm, etc.
|
|
279
|
+
**Array format (default):**
|
|
280
|
+
- Recommended for every command—JSON keeps arguments intact (URLs with \`&\`, spaces, etc.)
|
|
281
|
+
- Use \`["/bin/sh", "-lc", "..."]\` when you need shell operators like \`&&\`, \`|\`, or redirections
|
|
282
|
+
- Works with any language: Python, bash, node, npm, uv, etc.
|
|
237
283
|
|
|
238
|
-
**String format:**
|
|
239
|
-
-
|
|
240
|
-
-
|
|
241
|
-
-
|
|
242
|
-
- \`$HF_TOKEN\` stays literal in the command. To forward your authenticated token, add \`secrets: { "HF_TOKEN": "$HF_TOKEN" }\`.
|
|
284
|
+
**String format (simple cases only):**
|
|
285
|
+
- Still accepted for backwards compatibility, parsed with POSIX shell semantics
|
|
286
|
+
- Rejects shell operators and can mis-handle characters such as \`&\`; switch to arrays when things turn complex
|
|
287
|
+
- \`$HF_TOKEN\` stays literal—forward it via \`secrets: { "HF_TOKEN": "$HF_TOKEN" }\`
|
|
243
288
|
|
|
244
289
|
**Multiline inline scripts:**
|
|
245
|
-
-
|
|
246
|
-
-
|
|
290
|
+
- Include newline characters directly in the argument (e.g., \`"first line\\nsecond line"\`)
|
|
291
|
+
- UV inline scripts are automatically base64-decoded inside the container; just send the raw script text
|
|
292
|
+
|
|
293
|
+
### Show command-specific help
|
|
294
|
+
\`\`\`
|
|
295
|
+
hf_jobs("<command>", {"help": true})
|
|
296
|
+
\`\`\`
|
|
247
297
|
|
|
248
298
|
## Tips
|
|
249
299
|
|
|
250
|
-
-
|
|
251
|
-
-
|
|
252
|
-
|
|
300
|
+
- The uv-scripts organisation contains examples for common tasks. dataset_search {'author':'uv-scripts'}
|
|
301
|
+
- Jobs default to detached mode, returning after 10 seconds..
|
|
302
|
+
- Prefer array commands to avoid shell parsing surprises
|
|
303
|
+
- To access private Hub assets, include \`secrets: { "HF_TOKEN": "$HF_TOKEN" }\` (or \`${'${HF_TOKEN}'}\`) to inject your auth token.
|
|
253
304
|
- Logs are time-limited (10s max) - check job page for full logs
|
|
254
|
-
- For shell pipes/operators, use: \`["bash", "-c", "cmd1 | cmd2"]\`
|
|
255
305
|
`;
|
|
256
306
|
|
|
257
307
|
/**
|
|
@@ -260,9 +310,10 @@ hf_jobs("scheduled run", {
|
|
|
260
310
|
export const HF_JOBS_TOOL_CONFIG = {
|
|
261
311
|
name: 'hf_jobs',
|
|
262
312
|
description:
|
|
263
|
-
'Manage HuggingFace compute jobs. Run
|
|
264
|
-
'execute Python scripts with UV
|
|
265
|
-
'
|
|
313
|
+
'Manage HuggingFace compute jobs. Run commands in Docker containers, ' +
|
|
314
|
+
'execute Python scripts with UV, schedule and monitor jobs, status and logs. ' +
|
|
315
|
+
'Call hf_jobs with no command for full usage instructions and examples. ' +
|
|
316
|
+
'Supports CPU and GPU hardware.',
|
|
266
317
|
schema: z.object({
|
|
267
318
|
command: z
|
|
268
319
|
.string()
|
|
@@ -275,8 +326,7 @@ export const HF_JOBS_TOOL_CONFIG = {
|
|
|
275
326
|
args: z.record(z.any()).optional().describe('Command-specific arguments as a JSON object'),
|
|
276
327
|
}),
|
|
277
328
|
annotations: {
|
|
278
|
-
title: '
|
|
279
|
-
destructiveHint: false,
|
|
329
|
+
title: 'Hugging Face Jobs', // omit destructive hint.
|
|
280
330
|
readOnlyHint: false,
|
|
281
331
|
openWorldHint: true,
|
|
282
332
|
},
|
|
@@ -320,10 +370,29 @@ export class HfJobsTool {
|
|
|
320
370
|
}
|
|
321
371
|
|
|
322
372
|
const command = params.command.toLowerCase();
|
|
323
|
-
const
|
|
373
|
+
const rawArgs = params.args || {};
|
|
374
|
+
const schema = COMMAND_SCHEMAS[command as keyof typeof COMMAND_SCHEMAS];
|
|
375
|
+
const helpRequested = isHelpRequested(rawArgs);
|
|
376
|
+
|
|
377
|
+
if (helpRequested) {
|
|
378
|
+
if (!schema) {
|
|
379
|
+
return {
|
|
380
|
+
formatted: `No help available for '${params.command}'.`,
|
|
381
|
+
totalResults: 0,
|
|
382
|
+
resultsShared: 0,
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return {
|
|
387
|
+
formatted: formatCommandHelp(command, schema),
|
|
388
|
+
totalResults: 1,
|
|
389
|
+
resultsShared: 1,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const args = removeHelpFlag(rawArgs);
|
|
324
394
|
|
|
325
395
|
// Validate command arguments if schema exists
|
|
326
|
-
const schema = COMMAND_SCHEMAS[command as keyof typeof COMMAND_SCHEMAS];
|
|
327
396
|
if (schema) {
|
|
328
397
|
const validation = validateArgs(schema, args, command);
|
|
329
398
|
if (!validation.success) {
|
|
@@ -390,7 +459,6 @@ export class HfJobsTool {
|
|
|
390
459
|
default:
|
|
391
460
|
return {
|
|
392
461
|
formatted: `Unknown command: "${params.command}"
|
|
393
|
-
|
|
394
462
|
Available commands:
|
|
395
463
|
- run, uv, ps, logs, inspect, cancel
|
|
396
464
|
- scheduled run, scheduled uv, scheduled ps, scheduled inspect, scheduled delete, scheduled suspend, scheduled resume
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Type utilities and help generation for Zod schemas
|
|
5
|
+
* Provides introspection and documentation generation for command arguments
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
type AnyZodType = z.ZodType<unknown, z.ZodTypeDef, unknown>;
|
|
9
|
+
|
|
10
|
+
export interface FieldDetails {
|
|
11
|
+
key: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
typeLabel: string;
|
|
14
|
+
isOptional: boolean;
|
|
15
|
+
isNullable: boolean;
|
|
16
|
+
defaultValue?: unknown;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Unwrap optional/default/nullable wrappers to find the core type definition.
|
|
21
|
+
*/
|
|
22
|
+
export function unwrapType(zodType: AnyZodType): {
|
|
23
|
+
baseType: AnyZodType;
|
|
24
|
+
isOptional: boolean;
|
|
25
|
+
isNullable: boolean;
|
|
26
|
+
defaultValue?: unknown;
|
|
27
|
+
} {
|
|
28
|
+
let current = zodType;
|
|
29
|
+
let isOptional = false;
|
|
30
|
+
let isNullable = false;
|
|
31
|
+
let defaultValue: unknown;
|
|
32
|
+
|
|
33
|
+
while (true) {
|
|
34
|
+
if (current instanceof z.ZodOptional) {
|
|
35
|
+
isOptional = true;
|
|
36
|
+
current = current._def.innerType as AnyZodType;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (current instanceof z.ZodDefault) {
|
|
41
|
+
isOptional = true;
|
|
42
|
+
defaultValue = current._def.defaultValue();
|
|
43
|
+
current = current._def.innerType as AnyZodType;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (current instanceof z.ZodNullable) {
|
|
48
|
+
isNullable = true;
|
|
49
|
+
current = current._def.innerType as AnyZodType;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (current instanceof z.ZodEffects) {
|
|
54
|
+
current = current._def.schema as AnyZodType;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { baseType: current, isOptional, isNullable, defaultValue };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function isZodType(value: unknown): value is AnyZodType {
|
|
65
|
+
return value instanceof z.ZodType;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
69
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Generate a human-readable type label from a Zod type definition
|
|
74
|
+
*/
|
|
75
|
+
export function labelForType(zodType: AnyZodType): string {
|
|
76
|
+
if (zodType instanceof z.ZodString) {
|
|
77
|
+
return 'string';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (zodType instanceof z.ZodNumber) {
|
|
81
|
+
return 'number';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (zodType instanceof z.ZodBoolean) {
|
|
85
|
+
return 'boolean';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (zodType instanceof z.ZodEnum) {
|
|
89
|
+
return `enum(${(zodType.options as readonly string[]).join(', ')})`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (zodType instanceof z.ZodLiteral) {
|
|
93
|
+
return `literal(${JSON.stringify(zodType.value)})`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (zodType instanceof z.ZodArray) {
|
|
97
|
+
return `array<${labelForType(zodType._def.type as AnyZodType)}>`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (zodType instanceof z.ZodRecord) {
|
|
101
|
+
return `record<string, ${labelForType(zodType._def.valueType as AnyZodType)}>`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (zodType instanceof z.ZodUnion) {
|
|
105
|
+
const options = zodType._def.options as readonly AnyZodType[];
|
|
106
|
+
const labels = options.map((opt) => labelForType(opt));
|
|
107
|
+
return labels.join(' | ');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (zodType instanceof z.ZodObject) {
|
|
111
|
+
return 'object';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Fallback for any unexpected types
|
|
115
|
+
return zodType.constructor.name.replace(/^Zod/, '').toLowerCase();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Extract field details from a Zod object schema
|
|
120
|
+
* Useful for custom help formatting or validation messages
|
|
121
|
+
*/
|
|
122
|
+
export function extractFieldDetails(schema: AnyZodType): FieldDetails[] {
|
|
123
|
+
if (!(schema instanceof z.ZodObject)) {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const shape = schema.shape as Record<string, unknown>;
|
|
128
|
+
const keys = Object.keys(shape);
|
|
129
|
+
const details: FieldDetails[] = [];
|
|
130
|
+
|
|
131
|
+
for (const key of keys) {
|
|
132
|
+
const candidate = shape[key];
|
|
133
|
+
if (!isZodType(candidate)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const fieldSchema: AnyZodType = candidate;
|
|
137
|
+
const { baseType, isOptional, isNullable, defaultValue } = unwrapType(fieldSchema);
|
|
138
|
+
details.push({
|
|
139
|
+
key: String(key),
|
|
140
|
+
description: fieldSchema.description ?? baseType.description,
|
|
141
|
+
typeLabel: labelForType(baseType),
|
|
142
|
+
isOptional,
|
|
143
|
+
isNullable,
|
|
144
|
+
defaultValue,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return details;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Format a default value for display in help text
|
|
153
|
+
*/
|
|
154
|
+
export function formatDefaultValue(value: unknown): string | undefined {
|
|
155
|
+
if (value === undefined) {
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (typeof value === 'string') {
|
|
160
|
+
return `"${value}"`;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {
|
|
164
|
+
return String(value);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (typeof value === 'symbol') {
|
|
168
|
+
return value.description ? `Symbol(${value.description})` : 'Symbol()';
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (value === null) {
|
|
172
|
+
return 'null';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (Array.isArray(value)) {
|
|
176
|
+
try {
|
|
177
|
+
return JSON.stringify(value);
|
|
178
|
+
} catch {
|
|
179
|
+
return '[unserializable]';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (isPlainObject(value)) {
|
|
184
|
+
try {
|
|
185
|
+
return JSON.stringify(value);
|
|
186
|
+
} catch {
|
|
187
|
+
return '[unserializable]';
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return '[unsupported]';
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Generate command-specific help text from a Zod schema
|
|
196
|
+
* Main entry point for help generation
|
|
197
|
+
*/
|
|
198
|
+
export function formatCommandHelp(commandName: string, schema: z.ZodTypeAny): string {
|
|
199
|
+
if (!schema) {
|
|
200
|
+
return `No help available for '${commandName}'.`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const fields = extractFieldDetails(schema as AnyZodType);
|
|
204
|
+
|
|
205
|
+
if (fields.length === 0) {
|
|
206
|
+
return `No help available for '${commandName}'.`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const header = `# Command help: ${commandName}\n\nArguments:\n`;
|
|
210
|
+
const lines = fields.map((field) => {
|
|
211
|
+
const parts: string[] = [];
|
|
212
|
+
parts.push(field.isOptional ? 'optional' : 'required');
|
|
213
|
+
parts.push(field.typeLabel);
|
|
214
|
+
if (field.isNullable) {
|
|
215
|
+
parts.push('nullable');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const defaultValue = formatDefaultValue(field.defaultValue);
|
|
219
|
+
if (defaultValue !== undefined) {
|
|
220
|
+
parts.push(`default: ${defaultValue}`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const meta = parts.join(', ');
|
|
224
|
+
const description = field.description ?? 'No description provided.';
|
|
225
|
+
|
|
226
|
+
return `- \`${field.key}\` (${meta}): ${description}`;
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
return header + lines.join('\n');
|
|
230
|
+
}
|
package/src/jobs/types.ts
CHANGED
|
@@ -147,17 +147,16 @@ export const runArgsSchema = commonArgsSchema.extend({
|
|
|
147
147
|
.default('cpu-basic')
|
|
148
148
|
.describe(`Hardware flavor. Options: ${ALL_FLAVORS.join(', ')}`),
|
|
149
149
|
env: z.record(z.string()).optional().describe('Environment variables as key-value pairs'),
|
|
150
|
-
secrets: z
|
|
151
|
-
|
|
152
|
-
.string()
|
|
150
|
+
secrets: z
|
|
151
|
+
.record(z.string())
|
|
153
152
|
.optional()
|
|
154
|
-
.describe('
|
|
155
|
-
|
|
153
|
+
.describe('Secrets as key-value pairs. Use HF_TOKEN=$HF_TOKEN to include your token'),
|
|
154
|
+
timeout: z.string().optional().describe('Max duration (e.g., "5m", "2h", "30s"). Default: 30m').default('30m'),
|
|
156
155
|
detach: z
|
|
157
156
|
.boolean()
|
|
158
157
|
.optional()
|
|
159
158
|
.default(true)
|
|
160
|
-
.describe('Run in background and return
|
|
159
|
+
.describe('Run in background and return after 10 seconds (default: true)'),
|
|
161
160
|
});
|
|
162
161
|
|
|
163
162
|
// UV command args
|
|
@@ -165,21 +164,24 @@ export const uvArgsSchema = commonArgsSchema.extend({
|
|
|
165
164
|
script: z
|
|
166
165
|
.string()
|
|
167
166
|
.describe('Python script: local file path, URL, or inline code. UV will handle dependencies automatically.'),
|
|
168
|
-
repo: z.string().optional().describe('Persistent repository name for script storage'),
|
|
167
|
+
// repo: z.string().optional().describe('Persistent repository name for script storage'), // consider reinstating if we decide to cache scripts
|
|
169
168
|
with_deps: z.array(z.string()).optional().describe('Additional package dependencies'),
|
|
170
169
|
script_args: z.array(z.string()).optional().describe('Arguments to pass to the script'),
|
|
171
170
|
python: z.string().optional().describe('Python interpreter version (e.g., "3.12")'),
|
|
172
171
|
flavor: z.enum(ALL_FLAVORS).optional().default('cpu-basic').describe('Hardware flavor'),
|
|
173
|
-
env: z.record(z.string()).optional().describe('Environment variables'),
|
|
174
|
-
secrets: z
|
|
172
|
+
env: z.record(z.string()).optional().describe('Environment variables as key-value pairs'),
|
|
173
|
+
secrets: z
|
|
174
|
+
.record(z.string())
|
|
175
|
+
.optional()
|
|
176
|
+
.describe('Secrets as key-value pairs. Use HF_TOKEN=$HF_TOKEN to include your token'),
|
|
175
177
|
timeout: z.string().optional().default('30m').describe('Max duration'),
|
|
176
|
-
detach: z.boolean().optional().default(true).describe('Run in background'),
|
|
178
|
+
detach: z.boolean().optional().default(true).describe('Run in background and return after 10 seconds'),
|
|
177
179
|
});
|
|
178
180
|
|
|
179
181
|
// PS command args
|
|
180
182
|
export const psArgsSchema = commonArgsSchema.extend({
|
|
181
183
|
all: z.boolean().optional().default(false).describe('Show all jobs (default: only running)'),
|
|
182
|
-
status: z.string().optional().describe('Filter by status (
|
|
184
|
+
status: z.string().optional().describe('Filter by status ("RUNNING", "COMPLETED", "CANCELED", "ERROR", "DELETED")'),
|
|
183
185
|
});
|
|
184
186
|
|
|
185
187
|
// Logs command args
|
|
@@ -200,9 +202,7 @@ export const cancelArgsSchema = commonArgsSchema.extend({
|
|
|
200
202
|
|
|
201
203
|
// Scheduled run args
|
|
202
204
|
export const scheduledRunArgsSchema = runArgsSchema.extend({
|
|
203
|
-
schedule: z
|
|
204
|
-
.string()
|
|
205
|
-
.describe('Schedule: cron expression or shorthand (@hourly, @daily, @weekly, @monthly, @yearly)'),
|
|
205
|
+
schedule: z.string().describe('Schedule: cron expression or shorthand (@hourly, @daily, @weekly, @monthly, @yearly)'),
|
|
206
206
|
suspend: z.boolean().optional().default(false).describe('Create in suspended state'),
|
|
207
207
|
});
|
|
208
208
|
|
package/dist/jobs/tool.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/jobs/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAe1D,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAmOhD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;CAuBtB,CAAC;AAKX,qBAAa,UAAU;IACtB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,eAAe,CAAU;gBAErB,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM;IASrE,OAAO,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;CAqIhG"}
|
package/dist/jobs/tool.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/jobs/tool.ts"],"names":[],"mappings":"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"}
|