UNPKG

mlld

Version:

mlld: llm scripting language

817 lines (815 loc) 30.1 kB
import { normalizeTransformerResult } from './chunk-UZUAAX2J.mjs'; import { wrapExecResult } from './chunk-GRNEVFPC.mjs'; import { createPipelineInput } from './chunk-7YZGUDWA.mjs'; import { wrapStructured, isStructuredValue, asText } from './chunk-CQPPOI5P.mjs'; import { logger } from './chunk-PLP7R2Q4.mjs'; import { MlldCommandExecutionError } from './chunk-YVSXROKS.mjs'; import { createArrayVariable, createObjectVariable, createSimpleTextVariable, createPipelineInputVariable, createStructuredValueVariable } from './chunk-CHF7KR7X.mjs'; import { __name } from './chunk-NJQWMXLH.mjs'; // interpreter/eval/pipeline/command-execution.ts var STRUCTURED_PIPELINE_LANGUAGES = /* @__PURE__ */ new Set([ "mlld-for", "mlld-foreach", "js", "javascript", "node", "nodejs", "python" ]); function shouldAutoParsePipelineInput(language) { if (!language) return false; return STRUCTURED_PIPELINE_LANGUAGES.has(language.toLowerCase()); } __name(shouldAutoParsePipelineInput, "shouldAutoParsePipelineInput"); function parseStructuredJson(text) { if (!text) return null; const trimmed = text.trim(); if (!trimmed) return null; const firstChar = trimmed[0]; if (firstChar !== "{" && firstChar !== "[") { return null; } try { const parsed = JSON.parse(trimmed); if (parsed && typeof parsed === "object") { return parsed; } } catch { const sanitized = sanitizeJsonStringControlChars(trimmed); if (sanitized !== trimmed) { try { const reparsed = JSON.parse(sanitized); if (reparsed && typeof reparsed === "object") { return reparsed; } } catch { return null; } } } return null; } __name(parseStructuredJson, "parseStructuredJson"); function sanitizeJsonStringControlChars(input) { let inString = false; let escaping = false; let changed = false; let result = ""; for (let i = 0; i < input.length; i++) { const char = input[i]; if (escaping) { result += char; escaping = false; continue; } if (char === "\\") { result += char; escaping = true; continue; } if (char === '"') { inString = !inString; result += char; continue; } if (inString) { const code = char.charCodeAt(0); if (code >= 0 && code < 32) { changed = true; switch (char) { case "\n": result += "\\n"; continue; case "\r": result += "\\r"; continue; case " ": result += "\\t"; continue; case "\f": result += "\\f"; continue; case "\b": result += "\\b"; continue; case "\v": result += "\\u000b"; continue; default: result += `\\u${code.toString(16).padStart(4, "0")}`; continue; } } } result += char; } return changed ? result : input; } __name(sanitizeJsonStringControlChars, "sanitizeJsonStringControlChars"); function attachOriginalTextHooks(target, original) { if (!target || typeof target !== "object" && typeof target !== "function") { return; } try { Object.defineProperty(target, "text", { value: original, enumerable: false, configurable: true }); } catch { } try { Object.defineProperty(target, "raw", { value: original, enumerable: false, configurable: true }); } catch { } try { Object.defineProperty(target, "data", { get: /* @__PURE__ */ __name(() => target, "get"), enumerable: false, configurable: true }); } catch { } try { Object.defineProperty(target, "toString", { value: /* @__PURE__ */ __name(() => original, "value"), enumerable: false, configurable: true }); } catch { } try { Object.defineProperty(target, "valueOf", { value: /* @__PURE__ */ __name(() => original, "value"), enumerable: false, configurable: true }); } catch { } try { Object.defineProperty(target, Symbol.toPrimitive, { value: /* @__PURE__ */ __name((hint) => { if (hint === "number") { const coerced = Number(original); return Number.isNaN(coerced) ? original : coerced; } return original; }, "value"), enumerable: false, configurable: true }); } catch { } } __name(attachOriginalTextHooks, "attachOriginalTextHooks"); function wrapPipelineStructuredValue(parsedValue, original) { if (!parsedValue || typeof parsedValue !== "object") { return parsedValue; } attachOriginalTextHooks(parsedValue, original); const stringPrototype = String.prototype; const proxy = new Proxy(parsedValue, { get(target, prop, receiver) { if (prop === "text" || prop === "raw" || prop === "data") { return Reflect.get(target, prop, receiver); } if (prop === Symbol.toPrimitive) { const primitive = Reflect.get(target, prop, receiver); if (typeof primitive === "function") { return primitive; } return (hint) => { if (hint === "number") { const numeric = Number(original); return Number.isNaN(numeric) ? original : numeric; } return original; }; } if (prop === "toString" || prop === "valueOf") { return Reflect.get(target, prop, receiver); } if (prop === "length" && !Reflect.has(target, prop) && typeof original === "string") { return original.length; } if (Reflect.has(target, prop)) { const value = Reflect.get(target, prop, receiver); if (typeof value === "function") { return value.bind(target); } return value; } if (typeof original === "string") { if (prop in stringPrototype) { const candidate = stringPrototype[prop]; if (typeof candidate === "function") { return candidate.bind(original); } return candidate; } if (prop === Symbol.iterator) { const iterator = stringPrototype[Symbol.iterator]; if (typeof iterator === "function") { return iterator.bind(original); } } } return void 0; }, has(target, prop) { if (prop === "text" || prop === "raw" || prop === "data") { return true; } if (typeof original === "string" && prop in stringPrototype) { return true; } return Reflect.has(target, prop); }, ownKeys(target) { const keys = new Set(Reflect.ownKeys(target)); keys.add("text"); keys.add("raw"); keys.add("data"); return Array.from(keys); }, getOwnPropertyDescriptor(target, prop) { if (prop === "text" || prop === "raw") { return { configurable: true, enumerable: false, value: original }; } if (prop === "data") { return { configurable: true, enumerable: false, value: target }; } return Reflect.getOwnPropertyDescriptor(target, prop); }, set(target, prop, value, receiver) { return Reflect.set(target, prop, value, receiver); } }); return proxy; } __name(wrapPipelineStructuredValue, "wrapPipelineStructuredValue"); function wrapJsonLikeString(text) { if (typeof text !== "string") { return null; } const trimmed = text.trim(); if (!trimmed) { return null; } const firstChar = trimmed[0]; if (firstChar !== "{" && firstChar !== "[") { return null; } try { const parsed = JSON.parse(trimmed); if (Array.isArray(parsed)) { return wrapStructured(parsed, "array", text); } if (parsed !== null && typeof parsed === "object") { return wrapStructured(parsed, "object", text); } } catch (error) { if (process.env.MLLD_DEBUG === "true") { try { const codes = Array.from(trimmed).map((ch) => ch.charCodeAt(0)); const details = error instanceof Error ? error.stack || error.message : String(error); console.error("[wrapJsonLikeString] Failed to parse JSON-like text:", JSON.stringify(text), codes, details); } catch { } } return null; } return null; } __name(wrapJsonLikeString, "wrapJsonLikeString"); function createTypedPipelineVariable(paramName, parsedValue, originalText) { const pipelineSource = { directive: "var", syntax: "pipeline", hasInterpolation: false, isMultiLine: false }; const metadata = { isPipelineParameter: true, pipelineOriginal: originalText, pipelineFormat: "json" }; if (Array.isArray(parsedValue)) { const bridged = wrapPipelineStructuredValue(parsedValue, originalText); metadata.pipelineType = "array"; metadata.customToString = () => originalText; return createArrayVariable(paramName, bridged, false, pipelineSource, metadata); } if (parsedValue && typeof parsedValue === "object") { const bridged = wrapPipelineStructuredValue(parsedValue, originalText); metadata.pipelineType = "object"; metadata.customToString = () => originalText; return createObjectVariable(paramName, bridged, false, pipelineSource, metadata); } const textSource = { directive: "var", syntax: "quoted", hasInterpolation: false, isMultiLine: false }; return createSimpleTextVariable(paramName, originalText, textSource, { isPipelineParameter: true }); } __name(createTypedPipelineVariable, "createTypedPipelineVariable"); function resolveExecutableLanguage(commandVar, execDef) { if (execDef?.language) return String(execDef.language); if (commandVar?.metadata?.executableDef?.language) { return String(commandVar.metadata.executableDef.language); } if (commandVar?.value?.language) { return String(commandVar.value.language); } if (commandVar?.language) { return String(commandVar.language); } return void 0; } __name(resolveExecutableLanguage, "resolveExecutableLanguage"); async function resolveCommandReference(command, env) { if (!command.identifier || command.identifier.length === 0) { return null; } const varRefNode = command.identifier[0]; if (varRefNode.type === "VariableReference") { const varRef = varRefNode; const baseVar = env.getVariable(varRef.identifier); if (!baseVar) { return null; } const variantMap = baseVar.metadata?.transformerVariants; let value; let remainingFields = Array.isArray(varRef.fields) ? [...varRef.fields] : []; if (variantMap && remainingFields.length > 0) { const firstField = remainingFields[0]; if (firstField.type === "field" || firstField.type === "stringIndex" || firstField.type === "numericField") { const variantName = String(firstField.value); const variant = variantMap[variantName]; if (!variant) { throw new Error(`Pipeline function '@${varRef.identifier}.${variantName}' is not defined`); } value = variant; remainingFields = remainingFields.slice(1); } } if (typeof value === "undefined") { if (baseVar.type === "executable") { return baseVar; } const { extractVariableValue } = await import('./variable-resolution-QKOWHUJ3.mjs'); value = await extractVariableValue(baseVar, env); } if (remainingFields.length > 0) { for (const field of remainingFields) { if ((field.type === "field" || field.type === "stringIndex" || field.type === "numericField") && typeof value === "object" && value !== null) { value = value[String(field.value)]; } else if (field.type === "arrayIndex" && Array.isArray(value)) { value = value[Number(field.value)]; } else { const fieldName = String(field.value); throw new Error(`Cannot access field '${fieldName}' on ${typeof value}`); } } } return value; } return null; } __name(resolveCommandReference, "resolveCommandReference"); async function executeCommandVariable(commandVar, args, env, stdinInput, structuredInput) { const finalizeResult = /* @__PURE__ */ __name((value, options) => { return wrapExecResult(value, options); }, "finalizeResult"); if (commandVar && commandVar.metadata?.isBuiltinTransformer && commandVar.metadata?.transformerImplementation) { try { const result = await commandVar.metadata.transformerImplementation(stdinInput || ""); const normalized = normalizeTransformerResult(commandVar?.name, result); return finalizeResult(normalized.value, normalized.options); } catch (error) { throw new MlldCommandExecutionError( `Transformer ${commandVar.name} failed: ${error.message}`, void 0, { command: commandVar.name, exitCode: 1, duration: 0, workingDirectory: process.cwd() } ); } } let execDef; if (commandVar && commandVar.type === "executable" && commandVar.value) { if (commandVar.metadata?.executableDef) { execDef = commandVar.metadata.executableDef; if (!execDef.paramNames && commandVar.paramNames) { execDef.paramNames = commandVar.paramNames; } } else { const simplifiedValue = commandVar.value; if (simplifiedValue.type === "code") { execDef = { type: "code", codeTemplate: simplifiedValue.template, language: simplifiedValue.language || "javascript", paramNames: commandVar.paramNames || [] }; } else if (simplifiedValue.type === "command") { execDef = { type: "command", commandTemplate: simplifiedValue.template, paramNames: commandVar.paramNames || [] }; } else { execDef = simplifiedValue; } } if (process.env.MLLD_DEBUG === "true") { logger.debug("Executable definition extracted:", { type: execDef?.type, hasParamNames: !!execDef?.paramNames, hasCommandTemplate: !!execDef?.commandTemplate, hasCodeTemplate: !!execDef?.codeTemplate, hasTemplateContent: !!execDef?.templateContent, hasTemplate: !!execDef?.template, language: execDef?.language, fromMetadata: !!commandVar.metadata?.executableDef }); } } else if (commandVar && (commandVar.type === "command" || commandVar.type === "code" || commandVar.type === "template") && (commandVar.commandTemplate || commandVar.codeTemplate || commandVar.templateContent)) { execDef = commandVar; } else { const varInfo = { type: commandVar?.type, hasValue: !!commandVar?.value, valueType: commandVar?.value?.type, valueKeys: commandVar?.value ? Object.keys(commandVar.value) : [], hasCommandTemplate: !!commandVar?.commandTemplate, hasCodeTemplate: !!commandVar?.codeTemplate, hasTemplateContent: !!commandVar?.templateContent, hasTemplate: !!commandVar?.template, keys: commandVar ? Object.keys(commandVar) : [], valueStructure: commandVar?.value ? { type: commandVar.value.type, hasTemplate: !!commandVar.value.template, hasCodeTemplate: !!commandVar.value.codeTemplate, hasCommandTemplate: !!commandVar.value.commandTemplate, language: commandVar.value.language, paramNames: commandVar.value.paramNames } : null }; throw new Error(`Cannot execute non-executable variable in pipeline: ${JSON.stringify(varInfo, null, 2)}`); } const execEnv = env.createChild(); const pipelineCtx = env.getPipelineContext(); const format = pipelineCtx?.format; const stageLanguage = resolveExecutableLanguage(commandVar, execDef); if (execDef.paramNames) { for (let i = 0; i < execDef.paramNames.length; i++) { const paramName = execDef.paramNames[i]; const argIndex = pipelineCtx !== void 0 && stdinInput !== void 0 ? i - 1 : i; const argValue = argIndex >= 0 && argIndex < args.length ? args[argIndex] : null; const isPipelineParam = i === 0 && pipelineCtx !== void 0 && stdinInput !== void 0; if (isPipelineParam) { const { AutoUnwrapManager } = await import('./auto-unwrap-manager-U4D6H26D.mjs'); const textValue = structuredInput ? structuredInput.text : stdinInput ?? ""; const unwrapSource = structuredInput ?? textValue; const unwrappedStdin = AutoUnwrapManager.unwrap(unwrapSource); const hasNativeStructuredInput = structuredInput && structuredInput.type && structuredInput.type !== "text"; if (hasNativeStructuredInput) { const typedVar = createTypedPipelineVariable(paramName, structuredInput.data, textValue); execEnv.setParameterVariable(paramName, typedVar); continue; } if (!format) { const shouldParse = shouldAutoParsePipelineInput(stageLanguage); if (shouldParse) { const candidate = typeof unwrappedStdin === "string" ? unwrappedStdin : textValue; const parsed = parseStructuredJson(candidate); if (parsed !== null) { const typedVar = createTypedPipelineVariable(paramName, parsed, candidate); execEnv.setParameterVariable(paramName, typedVar); continue; } } const resolvedText = typeof unwrappedStdin === "string" ? unwrappedStdin : textValue; const textSource = { directive: "var", syntax: "quoted", hasInterpolation: false, isMultiLine: false }; const textVar = createSimpleTextVariable( paramName, resolvedText, textSource, { isPipelineParameter: true } ); execEnv.setParameterVariable(paramName, textVar); continue; } else { const resolvedText = typeof unwrappedStdin === "string" ? unwrappedStdin : textValue; const wrappedInput = createPipelineInput(resolvedText, format); const pipelineSource = { directive: "var", syntax: "template", hasInterpolation: false, isMultiLine: false }; const pipelineVar = createPipelineInputVariable( paramName, wrappedInput, format, resolvedText, pipelineSource, pipelineCtx?.stage ); execEnv.setParameterVariable(paramName, pipelineVar); continue; } } else { if (isStructuredValue(argValue)) { const structuredVar = createStructuredValueVariable( paramName, argValue, { directive: "var", syntax: "reference", hasInterpolation: false, isMultiLine: false }, { isParameter: true } ); execEnv.setParameterVariable(paramName, structuredVar); continue; } let paramValue; if (argValue === null) { paramValue = ""; } else if (typeof argValue === "string" || typeof argValue === "number" || typeof argValue === "boolean") { paramValue = argValue; } else if (argValue && typeof argValue === "object") { if (!Array.isArray(argValue) && argValue.type === "Text" && argValue.content !== void 0) { paramValue = argValue.content; } else if (!Array.isArray(argValue) && argValue.content !== void 0) { paramValue = argValue.content; } else { paramValue = argValue; } } else { paramValue = String(argValue); } if (isStructuredValue(paramValue)) { const structuredVar = createStructuredValueVariable( paramName, paramValue, { directive: "var", syntax: "reference", hasInterpolation: false, isMultiLine: false }, { isParameter: true } ); execEnv.setParameterVariable(paramName, structuredVar); } else if (Array.isArray(paramValue)) { const paramVar = createArrayVariable( paramName, paramValue, true, { directive: "var", syntax: "array", hasInterpolation: false, isMultiLine: false }, { isParameter: true } ); execEnv.setParameterVariable(paramName, paramVar); } else if (paramValue !== null && typeof paramValue === "object") { const paramVar = createObjectVariable( paramName, paramValue, true, { directive: "var", syntax: "object", hasInterpolation: false, isMultiLine: false }, { isParameter: true, isPipelineContext: paramValue.stage !== void 0 } ); execEnv.setParameterVariable(paramName, paramVar); } else { const paramSource = { directive: "var", syntax: "quoted", hasInterpolation: false, isMultiLine: false }; const paramVar = createSimpleTextVariable( paramName, String(paramValue), paramSource, { isParameter: true } ); execEnv.setParameterVariable(paramName, paramVar); } } } } if (execDef.type === "command" && execDef.commandTemplate) { const { interpolate } = await import('./interpreter-SBNF6N66.mjs'); const { InterpolationContext } = await import('./interpolation-context-F4ZIN34Z.mjs'); const command = await interpolate(execDef.commandTemplate, execEnv, InterpolationContext.ShellCommand); let commandOutput = await env.executeCommand(command, { input: stdinInput }); const withClause = execDef.withClause; if (withClause) { if (withClause.needs) { const { checkDependencies, DefaultDependencyChecker } = await import('./dependencies-5TAQLO5P.mjs'); const checker = new DefaultDependencyChecker(); await checkDependencies(withClause.needs, checker, commandVar.metadata?.definedAt); } if (withClause.pipeline && withClause.pipeline.length > 0) { const { processPipeline } = await import('./unified-processor-SHTG77PF.mjs'); const processed = await processPipeline({ value: commandOutput, env, pipeline: withClause.pipeline, format: withClause.format, isRetryable: false, identifier: commandVar?.name, location: commandVar.metadata?.definedAt }); if (processed === "retry") { return "retry"; } if (processed && typeof processed === "object" && processed.value === "retry") { return processed; } commandOutput = processed; } } return finalizeResult(commandOutput); } else if (execDef.type === "code" && execDef.codeTemplate) { if (execDef.language === "mlld-when") { const whenExprNode = execDef.codeTemplate[0]; if (!whenExprNode || whenExprNode.type !== "WhenExpression") { throw new Error("mlld-when executable missing WhenExpression node"); } const { evaluateWhenExpression } = await import('./when-expression-B2BMDHFN.mjs'); const whenResult = await evaluateWhenExpression(whenExprNode, execEnv); let resultValue = whenResult.value; if (resultValue && typeof resultValue === "object" && resultValue.value === "retry") { return resultValue; } if (resultValue === "retry") { return "retry"; } const inPipeline = !!env.getPipelineContext(); const showEffect = resultValue && typeof resultValue === "object" && resultValue.__whenEffect === "show"; const structuredShowEffect = isStructuredValue(resultValue) && resultValue.data && typeof resultValue.data === "object" && resultValue.data.__whenEffect === "show"; if (inPipeline && (showEffect || structuredShowEffect)) { const pctx = env.getPipelineContext?.(); const isLastStage = pctx && typeof pctx.stage === "number" && typeof pctx.totalStages === "number" ? pctx.stage >= pctx.totalStages : false; return finalizeResult(isLastStage ? "" : stdinInput || ""); } if (resultValue && typeof resultValue === "object" && "wrapperType" in resultValue && Array.isArray(resultValue.content)) { const { interpolate: interpolate2 } = await import('./interpreter-SBNF6N66.mjs'); try { resultValue = await interpolate2(resultValue.content, execEnv); } catch (e) { resultValue = String(resultValue); } } if (showEffect) { resultValue = resultValue.text ?? ""; } else if (structuredShowEffect) { const data = resultValue.data; resultValue = data?.text ?? asText(resultValue); } return finalizeResult(resultValue ?? ""); } else if (execDef.language === "mlld-foreach") { const foreachNode = execDef.codeTemplate[0]; const { evaluateForeachCommand } = await import('./foreach-DVSY36Z4.mjs'); const results = await evaluateForeachCommand(foreachNode, execEnv); const normalized = results.map((item) => { if (isStructuredValue(item)) { return item.data ?? item.text; } if (typeof item === "string" || item instanceof String) { const strValue = item instanceof String ? item.valueOf() : item; try { return JSON.parse(strValue); } catch { return strValue; } } return item; }); const text = (() => { try { return JSON.stringify(normalized); } catch { return String(normalized); } })(); return finalizeResult(normalized, { type: "array", text }); } else if (execDef.language === "mlld-for") { const forNode = execDef.codeTemplate[0]; const { evaluateForExpression } = await import('./for-TEFC6TVV.mjs'); const arrayVar = await evaluateForExpression(forNode, execEnv); const { extractVariableValue } = await import('./variable-resolution-QKOWHUJ3.mjs'); const value = await extractVariableValue(arrayVar, execEnv); const text = (() => { try { return JSON.stringify(value); } catch { return String(value); } })(); return finalizeResult(value, { type: "array", text }); } const { interpolate } = await import('./interpreter-SBNF6N66.mjs'); const { InterpolationContext } = await import('./interpolation-context-F4ZIN34Z.mjs'); const code = await interpolate(execDef.codeTemplate, execEnv, InterpolationContext.Default); const params = {}; if (execDef.paramNames) { for (const paramName of execDef.paramNames) { const paramVar = execEnv.getVariable(paramName); if (paramVar) { if (paramVar.type === "pipeline-input") { params[paramName] = paramVar.value; } else if (paramVar.metadata?.isPipelineInput && paramVar.metadata?.pipelineInput) { params[paramName] = paramVar.metadata.pipelineInput; } else { params[paramName] = paramVar.value; } } } } const result = await env.executeCode(code, execDef.language || "javascript", params); if (result && typeof result === "object" && "text" in result && "type" in result) { const text = typeof result.text === "string" ? result.text : String(result.text ?? ""); const type = typeof result.type === "string" ? result.type : void 0; return finalizeResult(result, { type, text }); } if (typeof result === "string" && pipelineCtx !== void 0 && !format && shouldAutoParsePipelineInput(stageLanguage)) { const wrapped = wrapJsonLikeString(result); if (wrapped) { return finalizeResult(wrapped); } } return finalizeResult(result); } else if (execDef.type === "template" && execDef.template) { const { interpolate } = await import('./interpreter-SBNF6N66.mjs'); const { InterpolationContext } = await import('./interpolation-context-F4ZIN34Z.mjs'); const result = await interpolate(execDef.template, execEnv, InterpolationContext.Default); return result; } else if (execDef.type === "commandRef") { const refRaw = execDef.commandRef || ""; const refName = String(refRaw); const fromParamScope = execEnv.getVariable(refName); if (fromParamScope) { if (fromParamScope.type === "executable") { return await executeCommandVariable(fromParamScope, execDef.commandArgs ?? [], execEnv, stdinInput, structuredInput); } const t2 = fromParamScope.type; throw new Error(`Referenced symbol '${refName}' is not executable (type: ${t2}). Use a template executable (e.g., \`@${refName}\`) or refactor the definition.`); } const refVar = env.getVariable(refName); if (!refVar) { throw new Error(`Referenced executable not found: ${execDef.commandRef}`); } if (refVar.type === "executable") { return await executeCommandVariable(refVar, execDef.commandArgs ?? [], env, stdinInput, structuredInput); } const t = refVar.type; throw new Error(`Referenced symbol '${refName}' is not executable (type: ${t}). Use a template executable or a function.`); } throw new Error(`Unsupported executable type in pipeline: ${execDef.type}`); } __name(executeCommandVariable, "executeCommandVariable"); export { executeCommandVariable, resolveCommandReference }; //# sourceMappingURL=command-execution-2DKN4BY5.mjs.map //# sourceMappingURL=command-execution-2DKN4BY5.mjs.map