applied-cli 0.5.54__tar.gz → 0.5.55__tar.gz
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.
- {applied_cli-0.5.54 → applied_cli-0.5.55}/PKG-INFO +1 -1
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/client.py +3 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/flow_helpers.py +3 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/tools.py +65 -7
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli.egg-info/PKG-INFO +1 -1
- {applied_cli-0.5.54 → applied_cli-0.5.55}/pyproject.toml +1 -1
- {applied_cli-0.5.54 → applied_cli-0.5.55}/README.md +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/__init__.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/agent_scoped_flows.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/cli.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/conversation_lookup.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/conversations.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/credentials.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli/formatters.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli.egg-info/SOURCES.txt +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli.egg-info/dependency_links.txt +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli.egg-info/entry_points.txt +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli.egg-info/requires.txt +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/applied_cli.egg-info/top_level.txt +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/setup.cfg +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/tests/test_agent_scoped_flows.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/tests/test_audit_tools.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/tests/test_benchmark_scenario_tools.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/tests/test_cli.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/tests/test_client.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/tests/test_conversation_tools.py +0 -0
- {applied_cli-0.5.54 → applied_cli-0.5.55}/tests/test_flow_tools.py +0 -0
|
@@ -1174,6 +1174,7 @@ class AppliedClient:
|
|
|
1174
1174
|
source_handle: str | None = None,
|
|
1175
1175
|
target_handle: str | None = None,
|
|
1176
1176
|
label: str | None = None,
|
|
1177
|
+
metadata: dict[str, Any] | None = None,
|
|
1177
1178
|
) -> dict:
|
|
1178
1179
|
"""Create an edge connecting two nodes."""
|
|
1179
1180
|
body: dict[str, Any] = {
|
|
@@ -1186,6 +1187,8 @@ class AppliedClient:
|
|
|
1186
1187
|
body["target_handle"] = target_handle
|
|
1187
1188
|
if label:
|
|
1188
1189
|
body["label"] = label
|
|
1190
|
+
if metadata:
|
|
1191
|
+
body["metadata"] = metadata
|
|
1189
1192
|
|
|
1190
1193
|
return await self._request(
|
|
1191
1194
|
"POST",
|
|
@@ -28,6 +28,7 @@ _CANONICAL_EXECUTOR_TYPES: tuple[str, ...] = (
|
|
|
28
28
|
"mutate_ticket",
|
|
29
29
|
"mutate_conversation",
|
|
30
30
|
"mutate_message",
|
|
31
|
+
"end_conversation",
|
|
31
32
|
)
|
|
32
33
|
|
|
33
34
|
_EXECUTOR_UI_LABELS: dict[str, str] = {
|
|
@@ -49,6 +50,7 @@ _EXECUTOR_UI_LABELS: dict[str, str] = {
|
|
|
49
50
|
"mutate_ticket": "Ticket",
|
|
50
51
|
"mutate_conversation": "Conversation",
|
|
51
52
|
"mutate_message": "Add Message",
|
|
53
|
+
"end_conversation": "End Conversation",
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
_EXECUTOR_ALIASES: dict[str, tuple[str, ...]] = {
|
|
@@ -70,6 +72,7 @@ _EXECUTOR_ALIASES: dict[str, tuple[str, ...]] = {
|
|
|
70
72
|
"mutate_ticket": ("ticket",),
|
|
71
73
|
"mutate_conversation": ("conversation",),
|
|
72
74
|
"mutate_message": ("add message",),
|
|
75
|
+
"end_conversation": ("end conversation", "end call", "close conversation"),
|
|
73
76
|
}
|
|
74
77
|
|
|
75
78
|
_BRANCH_DEFAULT_ALIASES = {
|
|
@@ -2500,6 +2500,9 @@ async def flow_edge_create(
|
|
|
2500
2500
|
branch: str | int | None = None,
|
|
2501
2501
|
target_handle: str | None = None,
|
|
2502
2502
|
label: str | None = None,
|
|
2503
|
+
metadata: dict | None = None,
|
|
2504
|
+
temporal_timeout_seconds: int | None = None,
|
|
2505
|
+
temporal_disabled_contact_groups: dict | None = None,
|
|
2503
2506
|
) -> str:
|
|
2504
2507
|
"""
|
|
2505
2508
|
Connect two nodes with an edge.
|
|
@@ -2513,7 +2516,14 @@ async def flow_edge_create(
|
|
|
2513
2516
|
branch: Branch path alias for conversational branch nodes, e.g. "1",
|
|
2514
2517
|
"branch 2", or "default". Preferred over source_handle for branch nodes.
|
|
2515
2518
|
target_handle: Input handle name (for mapping)
|
|
2516
|
-
label: Edge label/condition
|
|
2519
|
+
label: Edge label/condition describing when to traverse this edge
|
|
2520
|
+
metadata: Edge metadata dict. For temporal edges, include a "temporal"
|
|
2521
|
+
key (or use the temporal_* convenience params below).
|
|
2522
|
+
temporal_timeout_seconds: Convenience param to create a temporal edge
|
|
2523
|
+
that auto-fires after this many seconds of inactivity.
|
|
2524
|
+
temporal_disabled_contact_groups: Optional dict of contact group
|
|
2525
|
+
overrides for the temporal edge, e.g.
|
|
2526
|
+
{"__default__": false, "<group_id>": true}.
|
|
2517
2527
|
|
|
2518
2528
|
Returns:
|
|
2519
2529
|
Created edge
|
|
@@ -2523,6 +2533,14 @@ async def flow_edge_create(
|
|
|
2523
2533
|
|
|
2524
2534
|
resolved_source_handle = normalize_branch_handle(branch or source_handle)
|
|
2525
2535
|
|
|
2536
|
+
# Build metadata with temporal settings
|
|
2537
|
+
metadata = dict(metadata or {})
|
|
2538
|
+
if temporal_timeout_seconds is not None:
|
|
2539
|
+
temporal = metadata.setdefault("temporal", {})
|
|
2540
|
+
temporal["timeout_seconds"] = temporal_timeout_seconds
|
|
2541
|
+
if temporal_disabled_contact_groups is not None:
|
|
2542
|
+
temporal["disabled_contact_groups"] = temporal_disabled_contact_groups
|
|
2543
|
+
|
|
2526
2544
|
try:
|
|
2527
2545
|
flow = await client.get_flow(flow_id)
|
|
2528
2546
|
except AppliedAPIError as e:
|
|
@@ -2589,6 +2607,7 @@ async def flow_edge_create(
|
|
|
2589
2607
|
source_handle=resolved_source_handle,
|
|
2590
2608
|
target_handle=target_handle,
|
|
2591
2609
|
label=label,
|
|
2610
|
+
metadata=metadata or None,
|
|
2592
2611
|
)
|
|
2593
2612
|
except AppliedAPIError as e:
|
|
2594
2613
|
# Add extra context for edge errors
|
|
@@ -2602,14 +2621,33 @@ async def flow_edge_create(
|
|
|
2602
2621
|
)
|
|
2603
2622
|
return _format_error(e) + extra
|
|
2604
2623
|
|
|
2624
|
+
edge_id = edge.get("id")
|
|
2625
|
+
|
|
2626
|
+
# Follow-up update to persist label and metadata (backend create
|
|
2627
|
+
# endpoint may not pass these through to the model).
|
|
2628
|
+
needs_update = label or metadata
|
|
2629
|
+
if needs_update and edge_id:
|
|
2630
|
+
updates: dict = {}
|
|
2631
|
+
if label:
|
|
2632
|
+
updates["label"] = label
|
|
2633
|
+
if metadata:
|
|
2634
|
+
updates["metadata"] = metadata
|
|
2635
|
+
try:
|
|
2636
|
+
edge = await client.update_edge(flow_id, edge_id, **updates)
|
|
2637
|
+
except AppliedAPIError:
|
|
2638
|
+
pass # best-effort; edge was already created
|
|
2639
|
+
|
|
2605
2640
|
result = "# Created Edge\n"
|
|
2606
|
-
result += f"id: {
|
|
2641
|
+
result += f"id: {edge_id}\n"
|
|
2607
2642
|
result += f"source: {edge.get('source')}\n"
|
|
2608
2643
|
result += f"target: {edge.get('target')}\n"
|
|
2609
2644
|
if resolved_source_handle is not None:
|
|
2610
2645
|
result += f"source_handle: {resolved_source_handle}\n"
|
|
2611
2646
|
if label:
|
|
2612
2647
|
result += f"label: {label}\n"
|
|
2648
|
+
if metadata.get("temporal"):
|
|
2649
|
+
temporal = metadata["temporal"]
|
|
2650
|
+
result += f"temporal_timeout_seconds: {temporal.get('timeout_seconds')}\n"
|
|
2613
2651
|
result += "\nTip: run flow_layout(flow_id) after wiring a complex flow to tidy node positions.\n"
|
|
2614
2652
|
|
|
2615
2653
|
return result
|
|
@@ -2666,6 +2704,8 @@ async def flow_edge_update(
|
|
|
2666
2704
|
edge_id: str,
|
|
2667
2705
|
label: str | None = None,
|
|
2668
2706
|
metadata: dict | None = None,
|
|
2707
|
+
temporal_timeout_seconds: int | None = None,
|
|
2708
|
+
temporal_disabled_contact_groups: dict | None = None,
|
|
2669
2709
|
) -> str:
|
|
2670
2710
|
"""
|
|
2671
2711
|
Update an edge's properties.
|
|
@@ -2674,21 +2714,39 @@ async def flow_edge_update(
|
|
|
2674
2714
|
client: Authenticated AppliedClient
|
|
2675
2715
|
flow_id: The flow UUID
|
|
2676
2716
|
edge_id: The edge UUID
|
|
2677
|
-
label: New label/condition
|
|
2678
|
-
metadata: New metadata
|
|
2717
|
+
label: New label/condition describing when to traverse this edge
|
|
2718
|
+
metadata: New metadata dict. For temporal edges, include a "temporal"
|
|
2719
|
+
key or use the temporal_* convenience params.
|
|
2720
|
+
temporal_timeout_seconds: Set/update the temporal timeout in seconds.
|
|
2721
|
+
Makes this edge auto-fire after inactivity.
|
|
2722
|
+
temporal_disabled_contact_groups: Contact group overrides for the
|
|
2723
|
+
temporal edge, e.g. {"__default__": false, "<group_id>": true}.
|
|
2679
2724
|
|
|
2680
2725
|
Returns:
|
|
2681
2726
|
Updated edge
|
|
2682
2727
|
"""
|
|
2683
|
-
|
|
2728
|
+
metadata = dict(metadata or {}) if metadata else {}
|
|
2729
|
+
if temporal_timeout_seconds is not None:
|
|
2730
|
+
temporal = metadata.setdefault("temporal", {})
|
|
2731
|
+
temporal["timeout_seconds"] = temporal_timeout_seconds
|
|
2732
|
+
if temporal_disabled_contact_groups is not None:
|
|
2733
|
+
temporal["disabled_contact_groups"] = temporal_disabled_contact_groups
|
|
2734
|
+
|
|
2735
|
+
updates: dict = {}
|
|
2684
2736
|
if label is not None:
|
|
2685
2737
|
updates["label"] = label
|
|
2686
|
-
if metadata
|
|
2738
|
+
if metadata:
|
|
2687
2739
|
updates["metadata"] = metadata
|
|
2688
2740
|
|
|
2689
2741
|
edge = await client.update_edge(flow_id, edge_id, **updates)
|
|
2690
2742
|
|
|
2691
|
-
|
|
2743
|
+
result = f"# Updated Edge\nid: {edge.get('id')}"
|
|
2744
|
+
if label is not None:
|
|
2745
|
+
result += f"\nlabel: {label}"
|
|
2746
|
+
if metadata.get("temporal"):
|
|
2747
|
+
temporal = metadata["temporal"]
|
|
2748
|
+
result += f"\ntemporal_timeout_seconds: {temporal.get('timeout_seconds')}"
|
|
2749
|
+
return result
|
|
2692
2750
|
|
|
2693
2751
|
|
|
2694
2752
|
async def flow_edge_delete(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|