transloadit 4.7.3 → 4.7.6
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/README.md +897 -5
- package/dist/Transloadit.d.ts +13 -3
- package/dist/Transloadit.d.ts.map +1 -1
- package/dist/Transloadit.js +22 -2
- package/dist/Transloadit.js.map +1 -1
- package/dist/alphalib/types/assembliesGet.d.ts +5 -0
- package/dist/alphalib/types/assembliesGet.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyReplay.d.ts +5 -0
- package/dist/alphalib/types/assemblyReplay.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyReplayNotification.d.ts +5 -0
- package/dist/alphalib/types/assemblyReplayNotification.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyStatus.d.ts +25 -25
- package/dist/alphalib/types/assemblyStatus.d.ts.map +1 -1
- package/dist/alphalib/types/assemblyStatus.js +4 -1
- package/dist/alphalib/types/assemblyStatus.js.map +1 -1
- package/dist/alphalib/types/bill.d.ts +5 -0
- package/dist/alphalib/types/bill.d.ts.map +1 -1
- package/dist/alphalib/types/builtinTemplates.d.ts +83 -0
- package/dist/alphalib/types/builtinTemplates.d.ts.map +1 -0
- package/dist/alphalib/types/builtinTemplates.js +19 -0
- package/dist/alphalib/types/builtinTemplates.js.map +1 -0
- package/dist/alphalib/types/robots/ai-chat.d.ts.map +1 -1
- package/dist/alphalib/types/robots/ai-chat.js +1 -0
- package/dist/alphalib/types/robots/ai-chat.js.map +1 -1
- package/dist/alphalib/types/skillFrontmatter.d.ts +29 -0
- package/dist/alphalib/types/skillFrontmatter.d.ts.map +1 -0
- package/dist/alphalib/types/skillFrontmatter.js +19 -0
- package/dist/alphalib/types/skillFrontmatter.js.map +1 -0
- package/dist/alphalib/types/template.d.ts +36 -0
- package/dist/alphalib/types/template.d.ts.map +1 -1
- package/dist/alphalib/types/template.js +10 -0
- package/dist/alphalib/types/template.js.map +1 -1
- package/dist/alphalib/types/templateCredential.d.ts +10 -0
- package/dist/alphalib/types/templateCredential.d.ts.map +1 -1
- package/dist/bearerToken.d.ts +31 -0
- package/dist/bearerToken.d.ts.map +1 -0
- package/dist/bearerToken.js +158 -0
- package/dist/bearerToken.js.map +1 -0
- package/dist/cli/commands/assemblies.d.ts +8 -2
- package/dist/cli/commands/assemblies.d.ts.map +1 -1
- package/dist/cli/commands/assemblies.js +566 -411
- package/dist/cli/commands/assemblies.js.map +1 -1
- package/dist/cli/commands/auth.d.ts +1 -4
- package/dist/cli/commands/auth.d.ts.map +1 -1
- package/dist/cli/commands/auth.js +7 -123
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +5 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/templates.d.ts.map +1 -1
- package/dist/cli/commands/templates.js +4 -14
- package/dist/cli/commands/templates.js.map +1 -1
- package/dist/cli/fileProcessingOptions.d.ts +35 -0
- package/dist/cli/fileProcessingOptions.d.ts.map +1 -0
- package/dist/cli/fileProcessingOptions.js +182 -0
- package/dist/cli/fileProcessingOptions.js.map +1 -0
- package/dist/cli/generateIntentDocs.d.ts +2 -0
- package/dist/cli/generateIntentDocs.d.ts.map +1 -0
- package/dist/cli/generateIntentDocs.js +321 -0
- package/dist/cli/generateIntentDocs.js.map +1 -0
- package/dist/cli/intentCommandSpecs.d.ts +36 -0
- package/dist/cli/intentCommandSpecs.d.ts.map +1 -0
- package/dist/cli/intentCommandSpecs.js +181 -0
- package/dist/cli/intentCommandSpecs.js.map +1 -0
- package/dist/cli/intentCommands.d.ts +13 -0
- package/dist/cli/intentCommands.d.ts.map +1 -0
- package/dist/cli/intentCommands.js +368 -0
- package/dist/cli/intentCommands.js.map +1 -0
- package/dist/cli/intentFields.d.ts +25 -0
- package/dist/cli/intentFields.d.ts.map +1 -0
- package/dist/cli/intentFields.js +298 -0
- package/dist/cli/intentFields.js.map +1 -0
- package/dist/cli/intentInputPolicy.d.ts +10 -0
- package/dist/cli/intentInputPolicy.d.ts.map +1 -0
- package/dist/cli/intentInputPolicy.js +2 -0
- package/dist/cli/intentInputPolicy.js.map +1 -0
- package/dist/cli/intentRuntime.d.ts +114 -0
- package/dist/cli/intentRuntime.d.ts.map +1 -0
- package/dist/cli/intentRuntime.js +464 -0
- package/dist/cli/intentRuntime.js.map +1 -0
- package/dist/cli/resultFiles.d.ts +19 -0
- package/dist/cli/resultFiles.d.ts.map +1 -0
- package/dist/cli/resultFiles.js +66 -0
- package/dist/cli/resultFiles.js.map +1 -0
- package/dist/cli/resultUrls.d.ts +19 -0
- package/dist/cli/resultUrls.d.ts.map +1 -0
- package/dist/cli/resultUrls.js +36 -0
- package/dist/cli/resultUrls.js.map +1 -0
- package/dist/cli/semanticIntents/imageDescribe.d.ts +43 -0
- package/dist/cli/semanticIntents/imageDescribe.d.ts.map +1 -0
- package/dist/cli/semanticIntents/imageDescribe.js +188 -0
- package/dist/cli/semanticIntents/imageDescribe.js.map +1 -0
- package/dist/cli/semanticIntents/index.d.ts +18 -0
- package/dist/cli/semanticIntents/index.d.ts.map +1 -0
- package/dist/cli/semanticIntents/index.js +18 -0
- package/dist/cli/semanticIntents/index.js.map +1 -0
- package/dist/cli/semanticIntents/markdownPdf.d.ts +4 -0
- package/dist/cli/semanticIntents/markdownPdf.d.ts.map +1 -0
- package/dist/cli/semanticIntents/markdownPdf.js +93 -0
- package/dist/cli/semanticIntents/markdownPdf.js.map +1 -0
- package/dist/cli/semanticIntents/parsing.d.ts +11 -0
- package/dist/cli/semanticIntents/parsing.d.ts.map +1 -0
- package/dist/cli/semanticIntents/parsing.js +29 -0
- package/dist/cli/semanticIntents/parsing.js.map +1 -0
- package/dist/cli/stepsInput.d.ts +4 -0
- package/dist/cli/stepsInput.d.ts.map +1 -0
- package/dist/cli/stepsInput.js +23 -0
- package/dist/cli/stepsInput.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -4
- package/dist/cli.js.map +1 -1
- package/dist/ensureUniqueCounter.d.ts +8 -0
- package/dist/ensureUniqueCounter.d.ts.map +1 -0
- package/dist/ensureUniqueCounter.js +48 -0
- package/dist/ensureUniqueCounter.js.map +1 -0
- package/dist/inputFiles.d.ts +9 -0
- package/dist/inputFiles.d.ts.map +1 -1
- package/dist/inputFiles.js +177 -26
- package/dist/inputFiles.js.map +1 -1
- package/dist/robots.js +1 -1
- package/dist/robots.js.map +1 -1
- package/package.json +9 -7
- package/src/Transloadit.ts +35 -3
- package/src/alphalib/types/assemblyStatus.ts +4 -1
- package/src/alphalib/types/builtinTemplates.ts +24 -0
- package/src/alphalib/types/robots/ai-chat.ts +1 -0
- package/src/alphalib/types/skillFrontmatter.ts +24 -0
- package/src/alphalib/types/template.ts +14 -0
- package/src/bearerToken.ts +208 -0
- package/src/cli/commands/assemblies.ts +825 -505
- package/src/cli/commands/auth.ts +9 -151
- package/src/cli/commands/index.ts +6 -3
- package/src/cli/commands/templates.ts +6 -17
- package/src/cli/fileProcessingOptions.ts +294 -0
- package/src/cli/generateIntentDocs.ts +419 -0
- package/src/cli/intentCommandSpecs.ts +282 -0
- package/src/cli/intentCommands.ts +525 -0
- package/src/cli/intentFields.ts +403 -0
- package/src/cli/intentInputPolicy.ts +11 -0
- package/src/cli/intentRuntime.ts +734 -0
- package/src/cli/resultFiles.ts +105 -0
- package/src/cli/resultUrls.ts +72 -0
- package/src/cli/semanticIntents/imageDescribe.ts +254 -0
- package/src/cli/semanticIntents/index.ts +48 -0
- package/src/cli/semanticIntents/markdownPdf.ts +120 -0
- package/src/cli/semanticIntents/parsing.ts +56 -0
- package/src/cli/stepsInput.ts +32 -0
- package/src/cli.ts +5 -4
- package/src/ensureUniqueCounter.ts +75 -0
- package/src/inputFiles.ts +277 -26
- package/src/robots.ts +1 -1
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
import type { CommandClass } from 'clipanion'
|
|
2
|
+
import { Command } from 'clipanion'
|
|
3
|
+
import type { ZodObject, ZodRawShape, ZodTypeAny } from 'zod'
|
|
4
|
+
|
|
5
|
+
import type { RobotMetaInput } from '../alphalib/types/robots/_instructions-primitives.ts'
|
|
6
|
+
import type {
|
|
7
|
+
IntentDefinition,
|
|
8
|
+
IntentInputMode,
|
|
9
|
+
IntentOutputMode,
|
|
10
|
+
RobotIntentDefinition,
|
|
11
|
+
SemanticIntentDefinition,
|
|
12
|
+
} from './intentCommandSpecs.ts'
|
|
13
|
+
import { getIntentPaths, getIntentResultStepName, intentCatalog } from './intentCommandSpecs.ts'
|
|
14
|
+
import type { IntentFieldKind, IntentFieldSpec } from './intentFields.ts'
|
|
15
|
+
import {
|
|
16
|
+
createIntentOption,
|
|
17
|
+
inferIntentExampleValue,
|
|
18
|
+
inferIntentFieldKind,
|
|
19
|
+
unwrapIntentSchema,
|
|
20
|
+
} from './intentFields.ts'
|
|
21
|
+
import type { IntentInputPolicy } from './intentInputPolicy.ts'
|
|
22
|
+
import type {
|
|
23
|
+
IntentCommandDefinition,
|
|
24
|
+
IntentFileCommandDefinition,
|
|
25
|
+
IntentNoInputCommandDefinition,
|
|
26
|
+
IntentSingleStepExecutionDefinition,
|
|
27
|
+
} from './intentRuntime.ts'
|
|
28
|
+
import {
|
|
29
|
+
GeneratedBundledFileIntentCommand,
|
|
30
|
+
GeneratedNoInputIntentCommand,
|
|
31
|
+
GeneratedStandardFileIntentCommand,
|
|
32
|
+
GeneratedWatchableFileIntentCommand,
|
|
33
|
+
getIntentOptionDefinitions,
|
|
34
|
+
} from './intentRuntime.ts'
|
|
35
|
+
import { getSemanticIntentDescriptor } from './semanticIntents/index.ts'
|
|
36
|
+
|
|
37
|
+
interface GeneratedSchemaField extends IntentFieldSpec {
|
|
38
|
+
description?: string
|
|
39
|
+
exampleValue: string
|
|
40
|
+
optionFlags: string
|
|
41
|
+
propertyName: string
|
|
42
|
+
required: boolean
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface ResolvedIntentLocalFilesInput {
|
|
46
|
+
defaultSingleAssembly?: boolean
|
|
47
|
+
inputPolicy: IntentInputPolicy
|
|
48
|
+
kind: 'local-files'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface ResolvedIntentNoneInput {
|
|
52
|
+
kind: 'none'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type ResolvedIntentInput = ResolvedIntentLocalFilesInput | ResolvedIntentNoneInput
|
|
56
|
+
|
|
57
|
+
type IntentBaseClass =
|
|
58
|
+
| typeof GeneratedBundledFileIntentCommand
|
|
59
|
+
| typeof GeneratedNoInputIntentCommand
|
|
60
|
+
| typeof GeneratedStandardFileIntentCommand
|
|
61
|
+
| typeof GeneratedWatchableFileIntentCommand
|
|
62
|
+
|
|
63
|
+
type BuiltIntentCommandDefinition = IntentCommandDefinition & {
|
|
64
|
+
intentDefinition: IntentFileCommandDefinition | IntentNoInputCommandDefinition
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type ResolvedIntentCommandDefinition = BuiltIntentCommandDefinition & {
|
|
68
|
+
catalogDefinition: IntentDefinition
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const hiddenFieldNames = new Set([
|
|
72
|
+
'ffmpeg_stack',
|
|
73
|
+
'force_accept',
|
|
74
|
+
'ignore_errors',
|
|
75
|
+
'imagemagick_stack',
|
|
76
|
+
'output_meta',
|
|
77
|
+
'queue',
|
|
78
|
+
'result',
|
|
79
|
+
'robot',
|
|
80
|
+
'stack',
|
|
81
|
+
'use',
|
|
82
|
+
])
|
|
83
|
+
|
|
84
|
+
function toCamelCase(value: string): string {
|
|
85
|
+
return value.replace(/_([a-z])/g, (_match, letter: string) => letter.toUpperCase())
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function toKebabCase(value: string): string {
|
|
89
|
+
return value.replaceAll('_', '-')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function toPascalCase(parts: string[]): string {
|
|
93
|
+
return parts
|
|
94
|
+
.flatMap((part) => part.split('-'))
|
|
95
|
+
.map((part) => `${part[0]?.toUpperCase() ?? ''}${part.slice(1)}`)
|
|
96
|
+
.join('')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function stripTrailingPunctuation(value: string): string {
|
|
100
|
+
return value.replace(/[.:]+$/, '').trim()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function getTypicalInputFile(meta: RobotMetaInput): string {
|
|
104
|
+
switch (meta.typical_file_type) {
|
|
105
|
+
case 'audio file':
|
|
106
|
+
return 'input.mp3'
|
|
107
|
+
case 'document':
|
|
108
|
+
return 'input.pdf'
|
|
109
|
+
case 'image':
|
|
110
|
+
return 'input.png'
|
|
111
|
+
case 'video':
|
|
112
|
+
return 'input.mp4'
|
|
113
|
+
default:
|
|
114
|
+
return 'input.file'
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function getDefaultOutputPath(paths: string[], outputMode: IntentOutputMode): string {
|
|
119
|
+
if (outputMode === 'directory') {
|
|
120
|
+
return 'output/'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const [group] = paths
|
|
124
|
+
if (group === 'audio') return 'output.png'
|
|
125
|
+
if (group === 'document') return 'output.pdf'
|
|
126
|
+
if (group === 'image') return 'output.png'
|
|
127
|
+
if (group === 'text') return 'output.mp3'
|
|
128
|
+
return 'output.file'
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function inferOutputPath(
|
|
132
|
+
paths: string[],
|
|
133
|
+
outputMode: IntentOutputMode,
|
|
134
|
+
fieldSpecs: readonly GeneratedSchemaField[],
|
|
135
|
+
): string {
|
|
136
|
+
if (outputMode === 'directory') {
|
|
137
|
+
return 'output/'
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const formatExample = fieldSpecs
|
|
141
|
+
.map((fieldSpec) =>
|
|
142
|
+
fieldSpec.required && fieldSpec.name === 'format' ? fieldSpec.exampleValue : null,
|
|
143
|
+
)
|
|
144
|
+
.find((value) => value != null)
|
|
145
|
+
|
|
146
|
+
if (fieldSpecs.some((fieldSpec) => fieldSpec.name === 'format') && formatExample != null) {
|
|
147
|
+
if (fieldSpecs.some((fieldSpec) => fieldSpec.name === 'relative_pathname')) {
|
|
148
|
+
return `archive.${formatExample}`
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (formatExample != null && /^[-\w]+$/.test(formatExample)) {
|
|
153
|
+
return `output.${formatExample}`
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return getDefaultOutputPath(paths, outputMode)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function inferInputModeFromShape(shape: Record<string, ZodTypeAny>): IntentInputMode {
|
|
160
|
+
if ('prompt' in shape) {
|
|
161
|
+
return unwrapIntentSchema(shape.prompt).required ? 'none' : 'local-files'
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return 'local-files'
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function inferIntentInput(
|
|
168
|
+
definition: RobotIntentDefinition,
|
|
169
|
+
shape: Record<string, ZodTypeAny>,
|
|
170
|
+
): ResolvedIntentInput {
|
|
171
|
+
const inputMode = definition.inputMode ?? inferInputModeFromShape(shape)
|
|
172
|
+
if (inputMode === 'none') {
|
|
173
|
+
return { kind: 'none' }
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const promptIsOptional = 'prompt' in shape && !unwrapIntentSchema(shape.prompt).required
|
|
177
|
+
const inputPolicy = promptIsOptional
|
|
178
|
+
? ({
|
|
179
|
+
kind: 'optional',
|
|
180
|
+
field: 'prompt',
|
|
181
|
+
attachUseWhenInputsProvided: true,
|
|
182
|
+
} satisfies IntentInputPolicy)
|
|
183
|
+
: ({ kind: 'required' } satisfies IntentInputPolicy)
|
|
184
|
+
|
|
185
|
+
if (definition.defaultSingleAssembly) {
|
|
186
|
+
return {
|
|
187
|
+
kind: 'local-files',
|
|
188
|
+
defaultSingleAssembly: true,
|
|
189
|
+
inputPolicy,
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
kind: 'local-files',
|
|
195
|
+
inputPolicy,
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function inferFixedValues(
|
|
200
|
+
definition: RobotIntentDefinition,
|
|
201
|
+
input: ResolvedIntentInput,
|
|
202
|
+
inputMode: IntentInputMode,
|
|
203
|
+
): Record<string, unknown> {
|
|
204
|
+
if (definition.defaultSingleAssembly) {
|
|
205
|
+
return {
|
|
206
|
+
robot: definition.robot,
|
|
207
|
+
result: true,
|
|
208
|
+
use: {
|
|
209
|
+
steps: [':original'],
|
|
210
|
+
bundle_steps: true,
|
|
211
|
+
},
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (inputMode === 'none') {
|
|
216
|
+
return {
|
|
217
|
+
robot: definition.robot,
|
|
218
|
+
result: true,
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (input.kind === 'local-files' && input.inputPolicy.kind === 'required') {
|
|
223
|
+
return {
|
|
224
|
+
robot: definition.robot,
|
|
225
|
+
result: true,
|
|
226
|
+
use: ':original',
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
robot: definition.robot,
|
|
232
|
+
result: true,
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function collectSchemaFields(
|
|
237
|
+
schemaShape: Record<string, ZodTypeAny>,
|
|
238
|
+
fixedValues: Record<string, unknown>,
|
|
239
|
+
input: ResolvedIntentInput,
|
|
240
|
+
): GeneratedSchemaField[] {
|
|
241
|
+
return Object.entries(schemaShape)
|
|
242
|
+
.filter(([key]) => !hiddenFieldNames.has(key) && !Object.hasOwn(fixedValues, key))
|
|
243
|
+
.flatMap(([key, fieldSchema]) => {
|
|
244
|
+
const { required: schemaRequired, schema: unwrappedSchema } = unwrapIntentSchema(fieldSchema)
|
|
245
|
+
|
|
246
|
+
let kind: IntentFieldKind
|
|
247
|
+
try {
|
|
248
|
+
kind = inferIntentFieldKind(unwrappedSchema)
|
|
249
|
+
} catch {
|
|
250
|
+
return []
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return [
|
|
254
|
+
{
|
|
255
|
+
name: key,
|
|
256
|
+
propertyName: toCamelCase(key),
|
|
257
|
+
optionFlags: `--${toKebabCase(key)}`,
|
|
258
|
+
required: (input.kind === 'none' && key === 'prompt') || schemaRequired,
|
|
259
|
+
description: fieldSchema.description,
|
|
260
|
+
exampleValue: inferIntentExampleValue({
|
|
261
|
+
kind,
|
|
262
|
+
name: key,
|
|
263
|
+
schema: unwrappedSchema as ZodTypeAny,
|
|
264
|
+
}),
|
|
265
|
+
kind,
|
|
266
|
+
},
|
|
267
|
+
]
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function inferExamples(
|
|
272
|
+
spec: BuiltIntentCommandDefinition,
|
|
273
|
+
definition?: RobotIntentDefinition,
|
|
274
|
+
): Array<[string, string]> {
|
|
275
|
+
if (definition == null) {
|
|
276
|
+
if (spec.intentDefinition.execution.kind === 'dynamic-step') {
|
|
277
|
+
return spec.examples
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return [
|
|
281
|
+
['Run the command', `transloadit ${spec.paths.join(' ')} --input input.mp4 --out output/`],
|
|
282
|
+
]
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const parts = ['transloadit', ...spec.paths]
|
|
286
|
+
const schemaShape = (definition.schema as ZodObject<ZodRawShape>).shape as Record<
|
|
287
|
+
string,
|
|
288
|
+
ZodTypeAny
|
|
289
|
+
>
|
|
290
|
+
const inputMode = definition.inputMode ?? inferInputModeFromShape(schemaShape)
|
|
291
|
+
const fieldSpecs =
|
|
292
|
+
spec.intentDefinition.execution.kind === 'single-step'
|
|
293
|
+
? (spec.intentDefinition.execution.fields as readonly GeneratedSchemaField[])
|
|
294
|
+
: []
|
|
295
|
+
|
|
296
|
+
if (inputMode === 'local-files') {
|
|
297
|
+
parts.push('--input', getTypicalInputFile(definition.meta))
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (inputMode === 'none') {
|
|
301
|
+
const promptField = fieldSpecs.find((fieldSpec) => fieldSpec.name === 'prompt')
|
|
302
|
+
parts.push('--prompt', promptField?.exampleValue ?? JSON.stringify('A red bicycle in a studio'))
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
for (const fieldSpec of fieldSpecs) {
|
|
306
|
+
if (!fieldSpec.required) continue
|
|
307
|
+
if (fieldSpec.name === 'prompt' && inputMode === 'none') continue
|
|
308
|
+
|
|
309
|
+
parts.push(fieldSpec.optionFlags, fieldSpec.exampleValue)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const outputMode = spec.intentDefinition.outputMode ?? 'file'
|
|
313
|
+
parts.push('--out', inferOutputPath(spec.paths, outputMode, fieldSpecs))
|
|
314
|
+
|
|
315
|
+
return [['Run the command', parts.join(' ')]]
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function resolveRobotIntent(definition: RobotIntentDefinition): BuiltIntentCommandDefinition {
|
|
319
|
+
const paths = getIntentPaths(definition)
|
|
320
|
+
const className = `${toPascalCase(paths)}Command`
|
|
321
|
+
const commandLabel = paths.join(' ')
|
|
322
|
+
const schema = definition.schema as ZodObject<ZodRawShape>
|
|
323
|
+
const schemaShape = schema.shape as Record<string, ZodTypeAny>
|
|
324
|
+
const inputMode = definition.inputMode ?? inferInputModeFromShape(schemaShape)
|
|
325
|
+
const input = inferIntentInput(definition, schemaShape)
|
|
326
|
+
const fixedValues = inferFixedValues(definition, input, inputMode)
|
|
327
|
+
const fieldSpecs = collectSchemaFields(schemaShape, fixedValues, input)
|
|
328
|
+
const outputMode = definition.outputMode ?? 'file'
|
|
329
|
+
const execution: IntentSingleStepExecutionDefinition = {
|
|
330
|
+
kind: 'single-step',
|
|
331
|
+
schema,
|
|
332
|
+
fields: fieldSpecs,
|
|
333
|
+
fixedValues,
|
|
334
|
+
resultStepName:
|
|
335
|
+
getIntentResultStepName(definition) ??
|
|
336
|
+
(() => {
|
|
337
|
+
throw new Error(`Could not infer result step name for "${definition.robot}"`)
|
|
338
|
+
})(),
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const spec: BuiltIntentCommandDefinition = {
|
|
342
|
+
className,
|
|
343
|
+
description: stripTrailingPunctuation(definition.meta.title),
|
|
344
|
+
details: getIntentDetails({
|
|
345
|
+
defaultSingleAssembly: definition.defaultSingleAssembly === true,
|
|
346
|
+
inputMode,
|
|
347
|
+
outputMode,
|
|
348
|
+
robot: definition.robot,
|
|
349
|
+
}),
|
|
350
|
+
examples: [],
|
|
351
|
+
paths,
|
|
352
|
+
runnerKind:
|
|
353
|
+
input.kind === 'none' ? 'no-input' : input.defaultSingleAssembly ? 'bundled' : 'standard',
|
|
354
|
+
intentDefinition:
|
|
355
|
+
input.kind === 'none'
|
|
356
|
+
? {
|
|
357
|
+
execution,
|
|
358
|
+
outputDescription: 'Write the result to this path',
|
|
359
|
+
outputMode,
|
|
360
|
+
}
|
|
361
|
+
: {
|
|
362
|
+
commandLabel,
|
|
363
|
+
execution,
|
|
364
|
+
inputPolicy: input.inputPolicy,
|
|
365
|
+
outputDescription:
|
|
366
|
+
outputMode === 'directory'
|
|
367
|
+
? 'Write the results to this directory'
|
|
368
|
+
: 'Write the result to this path or directory',
|
|
369
|
+
outputMode,
|
|
370
|
+
},
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return {
|
|
374
|
+
...spec,
|
|
375
|
+
examples: inferExamples(spec, definition),
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function getIntentDetails({
|
|
380
|
+
defaultSingleAssembly,
|
|
381
|
+
inputMode,
|
|
382
|
+
outputMode,
|
|
383
|
+
robot,
|
|
384
|
+
}: {
|
|
385
|
+
defaultSingleAssembly: boolean
|
|
386
|
+
inputMode: IntentInputMode
|
|
387
|
+
outputMode: 'directory' | 'file'
|
|
388
|
+
robot: string
|
|
389
|
+
}): string {
|
|
390
|
+
if (inputMode === 'none') {
|
|
391
|
+
return `Runs \`${robot}\` and writes the result to \`--out\`.`
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (defaultSingleAssembly) {
|
|
395
|
+
return `Runs \`${robot}\` for the provided inputs and writes the result to \`--out\`.`
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (outputMode === 'directory') {
|
|
399
|
+
return `Runs \`${robot}\` on each input file and writes the results to \`--out\`.`
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return `Runs \`${robot}\` on each input file and writes the result to \`--out\`.`
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function resolveSemanticIntent(definition: SemanticIntentDefinition): BuiltIntentCommandDefinition {
|
|
406
|
+
const paths = getIntentPaths(definition)
|
|
407
|
+
const descriptor = getSemanticIntentDescriptor(definition.semantic)
|
|
408
|
+
|
|
409
|
+
return {
|
|
410
|
+
className: `${toPascalCase(paths)}Command`,
|
|
411
|
+
description: descriptor.presentation.description,
|
|
412
|
+
details: descriptor.presentation.details,
|
|
413
|
+
examples: [...descriptor.presentation.examples],
|
|
414
|
+
paths,
|
|
415
|
+
runnerKind: descriptor.runnerKind,
|
|
416
|
+
intentDefinition: {
|
|
417
|
+
commandLabel: paths.join(' '),
|
|
418
|
+
execution: descriptor.execution,
|
|
419
|
+
inputPolicy: descriptor.inputPolicy,
|
|
420
|
+
outputDescription: descriptor.outputDescription,
|
|
421
|
+
},
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function resolveTemplateIntent(
|
|
426
|
+
definition: IntentDefinition & { kind: 'template' },
|
|
427
|
+
): BuiltIntentCommandDefinition {
|
|
428
|
+
const outputMode = definition.outputMode ?? 'file'
|
|
429
|
+
const paths = getIntentPaths(definition)
|
|
430
|
+
const spec: BuiltIntentCommandDefinition = {
|
|
431
|
+
className: `${toPascalCase(paths)}Command`,
|
|
432
|
+
description: `Run ${stripTrailingPunctuation(definition.templateId)}`,
|
|
433
|
+
details: `Runs the \`${definition.templateId}\` template and writes the outputs to \`--out\`.`,
|
|
434
|
+
examples: [],
|
|
435
|
+
paths,
|
|
436
|
+
runnerKind: 'standard',
|
|
437
|
+
intentDefinition: {
|
|
438
|
+
commandLabel: paths.join(' '),
|
|
439
|
+
execution: {
|
|
440
|
+
kind: 'template',
|
|
441
|
+
templateId: definition.templateId,
|
|
442
|
+
},
|
|
443
|
+
inputPolicy: { kind: 'required' },
|
|
444
|
+
outputDescription:
|
|
445
|
+
outputMode === 'directory'
|
|
446
|
+
? 'Write the results to this directory'
|
|
447
|
+
: 'Write the result to this path or directory',
|
|
448
|
+
outputMode,
|
|
449
|
+
},
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
return {
|
|
453
|
+
...spec,
|
|
454
|
+
examples: inferExamples(spec),
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function resolveIntent(definition: IntentDefinition): BuiltIntentCommandDefinition {
|
|
459
|
+
if (definition.kind === 'robot') {
|
|
460
|
+
return resolveRobotIntent(definition)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (definition.kind === 'semantic') {
|
|
464
|
+
return resolveSemanticIntent(definition)
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return resolveTemplateIntent(definition)
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export function resolveIntentCommandDefinitions(): ResolvedIntentCommandDefinition[] {
|
|
471
|
+
return intentCatalog.map((definition) => ({
|
|
472
|
+
...resolveIntent(definition),
|
|
473
|
+
catalogDefinition: definition,
|
|
474
|
+
}))
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function getBaseClass(spec: BuiltIntentCommandDefinition): IntentBaseClass {
|
|
478
|
+
if (spec.runnerKind === 'no-input') {
|
|
479
|
+
return GeneratedNoInputIntentCommand
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (spec.runnerKind === 'bundled') {
|
|
483
|
+
return GeneratedBundledFileIntentCommand
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (spec.runnerKind === 'watchable') {
|
|
487
|
+
return GeneratedWatchableFileIntentCommand
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return GeneratedStandardFileIntentCommand
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
function createIntentCommandClass(spec: BuiltIntentCommandDefinition): CommandClass {
|
|
494
|
+
const BaseClass = getBaseClass(spec)
|
|
495
|
+
|
|
496
|
+
class RuntimeIntentCommand extends BaseClass {}
|
|
497
|
+
|
|
498
|
+
Object.defineProperty(RuntimeIntentCommand, 'name', {
|
|
499
|
+
value: spec.className,
|
|
500
|
+
})
|
|
501
|
+
|
|
502
|
+
Object.assign(RuntimeIntentCommand, {
|
|
503
|
+
paths: [spec.paths],
|
|
504
|
+
intentDefinition: spec.intentDefinition,
|
|
505
|
+
usage: Command.Usage({
|
|
506
|
+
category: 'Intent Commands',
|
|
507
|
+
description: spec.description,
|
|
508
|
+
details: spec.details,
|
|
509
|
+
examples: spec.examples,
|
|
510
|
+
}),
|
|
511
|
+
})
|
|
512
|
+
|
|
513
|
+
for (const field of getIntentOptionDefinitions(spec.intentDefinition)) {
|
|
514
|
+
Object.defineProperty(RuntimeIntentCommand.prototype, field.propertyName, {
|
|
515
|
+
configurable: true,
|
|
516
|
+
enumerable: true,
|
|
517
|
+
writable: true,
|
|
518
|
+
value: createIntentOption(field),
|
|
519
|
+
})
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
return RuntimeIntentCommand as unknown as CommandClass
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
export const intentCommands = resolveIntentCommandDefinitions().map(createIntentCommandClass)
|