{"version":3,"file":"chain-outputs.d.ts","sourceRoot":"","sources":["../../../../src/runs/shared/chain-outputs.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,SAAS,EAKd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE/F,OAAO,EACN,KAAK,mBAAmB,EAIxB,MAAM,qBAAqB,CAAC;AAK7B,qBAAa,0BAA2B,SAAQ,KAAK;CAAG;AAExD,MAAM,WAAW,4BAA4B;IAC5C,gBAAgB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAmBD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,mBAAmB,GAAE,mBAAwB,GAAG,IAAI,CAEnH;AAED,wBAAgB,sCAAsC,CACrD,KAAK,EAAE,SAAS,EAAE,EAClB,mBAAmB,GAAE,mBAAwB,EAC7C,OAAO,GAAE,4BAAiC,GACxC,IAAI,CAwDN;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAWzF;AAMD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAUlG;AAED,wBAAgB,0BAA0B,CACzC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,EACrE,SAAS,EAAE,MAAM,GACf,mBAAmB,CAOrB","sourcesContent":["import {\n\ttype ChainStep,\n\tisCheckpointStep,\n\tisDynamicParallelStep,\n\tisParallelStep,\n\ttype SequentialStep,\n} from \"../../shared/settings.ts\";\nimport type { ChainOutputMap, ChainOutputMapEntry, SingleResult } from \"../../shared/types.ts\";\nimport { getSingleResultOutput } from \"../../shared/utils.ts\";\nimport {\n\ttype DynamicFanoutConfig,\n\tDynamicFanoutError,\n\thasDynamicFanoutFields,\n\tvalidateDynamicStepShape,\n} from \"./dynamic-fanout.ts\";\n\nconst OUTPUT_REF_PATTERN = /\\{outputs\\.([^}]*)\\}/g;\nconst SAFE_OUTPUT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nexport class ChainOutputValidationError extends Error {}\n\nexport interface ChainOutputValidationContext {\n\tpriorOutputNames?: Iterable<string>;\n\tstartStepIndex?: number;\n}\n\nfunction outputNamesForStep(step: ChainStep): string[] {\n\tif (isCheckpointStep(step)) return [];\n\tif (isParallelStep(step))\n\t\treturn step.parallel.map((task) => task.as).filter((name): name is string => Boolean(name));\n\tif (isDynamicParallelStep(step)) return [step.collect.as];\n\tconst name = (step as SequentialStep).as;\n\treturn name ? [name] : [];\n}\n\nfunction taskTemplatesForStep(step: ChainStep): string[] {\n\tif (isCheckpointStep(step)) return [];\n\tif (isParallelStep(step)) return step.parallel.map((task) => task.task ?? \"{previous}\");\n\tif (isDynamicParallelStep(step))\n\t\treturn [step.parallel.task ?? \"{previous}\", step.parallel.label ?? \"\"].filter(Boolean);\n\treturn [(step as SequentialStep).task ?? \"{previous}\"];\n}\n\nexport function validateChainOutputBindings(steps: ChainStep[], dynamicFanoutConfig: DynamicFanoutConfig = {}): void {\n\tvalidateChainOutputBindingsWithContext(steps, dynamicFanoutConfig);\n}\n\nexport function validateChainOutputBindingsWithContext(\n\tsteps: ChainStep[],\n\tdynamicFanoutConfig: DynamicFanoutConfig = {},\n\tcontext: ChainOutputValidationContext = {},\n): void {\n\tconst priorOutputNames = [...(context.priorOutputNames ?? [])];\n\tconst available = new Set<string>(priorOutputNames);\n\tconst seen = new Set<string>(priorOutputNames);\n\tfor (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {\n\t\tconst displayStepIndex = (context.startStepIndex ?? 0) + stepIndex + 1;\n\t\tconst step = steps[stepIndex]!;\n\t\tif (hasDynamicFanoutFields(step)) {\n\t\t\tif (!isDynamicParallelStep(step)) {\n\t\t\t\tthrow new ChainOutputValidationError(\n\t\t\t\t\t`Dynamic chain step ${displayStepIndex} requires expand, a single parallel template object, and collect; dynamic expand/collect cannot be mixed with static parallel arrays.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tvalidateDynamicStepShape(step, displayStepIndex - 1, dynamicFanoutConfig);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof DynamicFanoutError) throw new ChainOutputValidationError(error.message);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (!available.has(step.expand.from.output)) {\n\t\t\t\tthrow new ChainOutputValidationError(\n\t\t\t\t\t`Dynamic chain step ${displayStepIndex} references unknown output '${step.expand.from.output}'. Named outputs are only available after producing step/group completes.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tfor (const name of outputNamesForStep(step)) {\n\t\t\tif (!SAFE_OUTPUT_NAME_PATTERN.test(name)) {\n\t\t\t\tthrow new ChainOutputValidationError(\n\t\t\t\t\t`Invalid chain output name '${name}' at step ${displayStepIndex}. Use /^[A-Za-z_][A-Za-z0-9_]*$/.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (seen.has(name)) {\n\t\t\t\tthrow new ChainOutputValidationError(`Duplicate chain output name '${name}'. Each as name must be unique.`);\n\t\t\t}\n\t\t\tseen.add(name);\n\t\t}\n\t\tfor (const template of taskTemplatesForStep(step)) {\n\t\t\tfor (const match of template.matchAll(OUTPUT_REF_PATTERN)) {\n\t\t\t\tconst rawReference = match[0];\n\t\t\t\tconst name = match[1]!;\n\t\t\t\tif (!SAFE_OUTPUT_NAME_PATTERN.test(name)) {\n\t\t\t\t\tthrow new ChainOutputValidationError(\n\t\t\t\t\t\t`Invalid chain output reference '${rawReference}' at step ${displayStepIndex}. Use {outputs.name} with /^[A-Za-z_][A-Za-z0-9_]*$/ names.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!available.has(name)) {\n\t\t\t\t\tthrow new ChainOutputValidationError(\n\t\t\t\t\t\t`Unknown chain output reference '${rawReference}' at step ${displayStepIndex}. Named outputs are only available after producing step/group completes.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const name of outputNamesForStep(step)) {\n\t\t\tavailable.add(name);\n\t\t}\n\t}\n}\n\nexport function resolveOutputReferences(template: string, outputs: ChainOutputMap): string {\n\treturn template.replace(OUTPUT_REF_PATTERN, (rawReference, name: string) => {\n\t\tif (!SAFE_OUTPUT_NAME_PATTERN.test(name)) {\n\t\t\tthrow new ChainOutputValidationError(\n\t\t\t\t`Invalid chain output reference '${rawReference}'. Use {outputs.name} with /^[A-Za-z_][A-Za-z0-9_]*$/ names.`,\n\t\t\t);\n\t\t}\n\t\tconst entry = outputs[name];\n\t\tif (!entry) throw new ChainOutputValidationError(`Unknown chain output reference '${rawReference}'.`);\n\t\treturn entry.text;\n\t});\n}\n\nfunction compactStructuredText(value: unknown): string {\n\treturn JSON.stringify(value);\n}\n\nexport function outputEntryFromResult(result: SingleResult, stepIndex: number): ChainOutputMapEntry {\n\treturn {\n\t\ttext:\n\t\t\tresult.structuredOutput !== undefined\n\t\t\t\t? compactStructuredText(result.structuredOutput)\n\t\t\t\t: getSingleResultOutput(result),\n\t\t...(result.structuredOutput !== undefined ? { structured: result.structuredOutput } : {}),\n\t\tagent: result.agent,\n\t\tstepIndex,\n\t};\n}\n\nexport function outputEntryFromAsyncResult(\n\tresult: { agent: string; output: string; structuredOutput?: unknown },\n\tstepIndex: number,\n): ChainOutputMapEntry {\n\treturn {\n\t\ttext: result.structuredOutput !== undefined ? compactStructuredText(result.structuredOutput) : result.output,\n\t\t...(result.structuredOutput !== undefined ? { structured: result.structuredOutput } : {}),\n\t\tagent: result.agent,\n\t\tstepIndex,\n\t};\n}\n"]}