|
14 | 14 | UiPathRuntimeEdge, |
15 | 15 | UiPathRuntimeGraph, |
16 | 16 | UiPathRuntimeNode, |
| 17 | + transform_attachments, |
| 18 | + transform_nullable_types, |
| 19 | + transform_references, |
17 | 20 | ) |
18 | 21 |
|
19 | 22 | try: |
@@ -322,120 +325,38 @@ def get_entrypoints_schema( |
322 | 325 | } |
323 | 326 |
|
324 | 327 | if hasattr(graph, "input_schema"): |
325 | | - if hasattr(graph.input_schema, "model_json_schema"): |
326 | | - input_schema = graph.input_schema.model_json_schema() |
327 | | - unpacked_ref_def_properties, input_circular_dependency = _resolve_refs( |
328 | | - input_schema |
329 | | - ) |
| 328 | + input_schema = graph.get_input_jsonschema() |
| 329 | + unpacked_ref_def_properties, input_circular_dependency = transform_references( |
| 330 | + input_schema |
| 331 | + ) |
330 | 332 |
|
331 | | - # Process the schema to handle nullable types |
332 | | - processed_properties = _process_nullable_types( |
333 | | - unpacked_ref_def_properties.get("properties", {}) |
334 | | - ) |
| 333 | + # Process the schema to handle nullable types |
| 334 | + processed_properties = transform_nullable_types( |
| 335 | + unpacked_ref_def_properties.get("properties", {}) |
| 336 | + ) |
335 | 337 |
|
336 | | - schema["input"]["properties"] = processed_properties |
337 | | - schema["input"]["required"] = unpacked_ref_def_properties.get( |
338 | | - "required", [] |
339 | | - ) |
| 338 | + schema["input"]["properties"] = processed_properties |
| 339 | + schema["input"]["required"] = unpacked_ref_def_properties.get("required", []) |
| 340 | + schema["input"] = transform_attachments(schema["input"]) |
340 | 341 |
|
341 | 342 | if hasattr(graph, "output_schema"): |
342 | | - if hasattr(graph.output_schema, "model_json_schema"): |
343 | | - output_schema = graph.output_schema.model_json_schema() |
344 | | - unpacked_ref_def_properties, output_circular_dependency = _resolve_refs( |
345 | | - output_schema |
346 | | - ) |
| 343 | + output_schema = graph.get_output_jsonschema() |
| 344 | + unpacked_ref_def_properties, output_circular_dependency = transform_references( |
| 345 | + output_schema |
| 346 | + ) |
347 | 347 |
|
348 | | - # Process the schema to handle nullable types |
349 | | - processed_properties = _process_nullable_types( |
350 | | - unpacked_ref_def_properties.get("properties", {}) |
351 | | - ) |
| 348 | + # Process the schema to handle nullable types |
| 349 | + processed_properties = transform_nullable_types( |
| 350 | + unpacked_ref_def_properties.get("properties", {}) |
| 351 | + ) |
352 | 352 |
|
353 | | - schema["output"]["properties"] = processed_properties |
354 | | - schema["output"]["required"] = unpacked_ref_def_properties.get( |
355 | | - "required", [] |
356 | | - ) |
| 353 | + schema["output"]["properties"] = processed_properties |
| 354 | + schema["output"]["required"] = unpacked_ref_def_properties.get("required", []) |
| 355 | + schema["output"] = transform_attachments(schema["output"]) |
357 | 356 |
|
358 | 357 | return SchemaDetails(schema, input_circular_dependency, output_circular_dependency) |
359 | 358 |
|
360 | 359 |
|
361 | | -def _resolve_refs(schema, root=None, visited=None): |
362 | | - """Recursively resolves $ref references in a JSON schema, handling circular references. |
363 | | -
|
364 | | - Returns: |
365 | | - tuple: (resolved_schema, has_circular_dependency) |
366 | | - """ |
367 | | - if root is None: |
368 | | - root = schema |
369 | | - |
370 | | - if visited is None: |
371 | | - visited = set() |
372 | | - |
373 | | - has_circular = False |
374 | | - |
375 | | - if isinstance(schema, dict): |
376 | | - if "$ref" in schema: |
377 | | - ref_path = schema["$ref"] |
378 | | - |
379 | | - if ref_path in visited: |
380 | | - # Circular dependency detected |
381 | | - return { |
382 | | - "type": "object", |
383 | | - "description": f"Circular reference to {ref_path}", |
384 | | - }, True |
385 | | - |
386 | | - visited.add(ref_path) |
387 | | - |
388 | | - # Resolve the reference |
389 | | - ref_parts = ref_path.lstrip("#/").split("/") |
390 | | - ref_schema = root |
391 | | - for part in ref_parts: |
392 | | - ref_schema = ref_schema.get(part, {}) |
393 | | - |
394 | | - result, circular = _resolve_refs(ref_schema, root, visited) |
395 | | - has_circular = has_circular or circular |
396 | | - |
397 | | - # Remove from visited after resolution (allows the same ref in different branches) |
398 | | - visited.discard(ref_path) |
399 | | - |
400 | | - return result, has_circular |
401 | | - |
402 | | - resolved_dict = {} |
403 | | - for k, v in schema.items(): |
404 | | - resolved_value, circular = _resolve_refs(v, root, visited) |
405 | | - resolved_dict[k] = resolved_value |
406 | | - has_circular = has_circular or circular |
407 | | - return resolved_dict, has_circular |
408 | | - |
409 | | - elif isinstance(schema, list): |
410 | | - resolved_list = [] |
411 | | - for item in schema: |
412 | | - resolved_item, circular = _resolve_refs(item, root, visited) |
413 | | - resolved_list.append(resolved_item) |
414 | | - has_circular = has_circular or circular |
415 | | - return resolved_list, has_circular |
416 | | - |
417 | | - return schema, False |
418 | | - |
419 | | - |
420 | | -def _process_nullable_types( |
421 | | - schema: dict[str, Any] | list[Any] | Any, |
422 | | -) -> dict[str, Any] | list[Any]: |
423 | | - """Process the schema to handle nullable types by removing anyOf with null and keeping the base type.""" |
424 | | - if isinstance(schema, dict): |
425 | | - if "anyOf" in schema and len(schema["anyOf"]) == 2: |
426 | | - types = [t.get("type") for t in schema["anyOf"]] |
427 | | - if "null" in types: |
428 | | - non_null_type = next( |
429 | | - t for t in schema["anyOf"] if t.get("type") != "null" |
430 | | - ) |
431 | | - return non_null_type |
432 | | - |
433 | | - return {k: _process_nullable_types(v) for k, v in schema.items()} |
434 | | - elif isinstance(schema, list): |
435 | | - return [_process_nullable_types(item) for item in schema] |
436 | | - return schema |
437 | | - |
438 | | - |
439 | 360 | __all__ = [ |
440 | 361 | "get_graph_schema", |
441 | 362 | "get_entrypoints_schema", |
|
0 commit comments