| 243 | } |
| 244 | if (!ids.insert(it->second).second) { |
| 245 | throw std::runtime_error("workflow batch item id collision in " + step_id + ": " + it->second); |
| 246 | } |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | void load_workflow_inputs( |
| 251 | const engine::io::json::Value & root, |
| 252 | const WorkflowRunOptions & options, |
| 253 | WorkflowContext & context) { |
| 254 | const auto * inputs = root.find("inputs"); |
| 255 | if (inputs != nullptr && !inputs->is_null()) { |
| 256 | if (!inputs->is_object()) { |
| 257 | throw std::runtime_error("workflow inputs must be an object"); |
| 258 | } |
| 259 | for (const auto & [key, value] : inputs->as_object()) { |
| 260 | if (!value.is_string()) { |
| 261 | throw std::runtime_error("workflow input default must be a string: " + key); |
| 262 | } |
| 263 | context.values[key] = value.as_string(); |
| 264 | } |
| 265 | } |
| 266 | for (const auto & [key, value] : options.workflow_inputs) { |
| 267 | context.values[key] = value; |
| 268 | } |
| 269 | for (auto & [_, value] : context.values) { |
| 270 | value = expand_value(value, context); |
no test coverage detected