isa-agent-sdk 0.1.0__py3-none-any.whl

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.
Files changed (165) hide show
  1. isa_agent_sdk/__init__.py +220 -0
  2. isa_agent_sdk/_hil.py +482 -0
  3. isa_agent_sdk/_messages.py +706 -0
  4. isa_agent_sdk/_query.py +964 -0
  5. isa_agent_sdk/_skills.py +570 -0
  6. isa_agent_sdk/_triggers.py +466 -0
  7. isa_agent_sdk/agent_client.py +792 -0
  8. isa_agent_sdk/agent_types/__init__.py +184 -0
  9. isa_agent_sdk/agent_types/agent_state.py +91 -0
  10. isa_agent_sdk/agent_types/common_types.py +332 -0
  11. isa_agent_sdk/agent_types/event_types.py +601 -0
  12. isa_agent_sdk/agent_types/hardware_types.py +218 -0
  13. isa_agent_sdk/agent_types/request_models.py +329 -0
  14. isa_agent_sdk/agent_types/response_models.py +525 -0
  15. isa_agent_sdk/clients/__init__.py +89 -0
  16. isa_agent_sdk/clients/base.py +206 -0
  17. isa_agent_sdk/clients/mcp_client.py +873 -0
  18. isa_agent_sdk/clients/model_client.py +581 -0
  19. isa_agent_sdk/clients/pool_manager_client.py +356 -0
  20. isa_agent_sdk/clients/session_client.py +844 -0
  21. isa_agent_sdk/clients/storage_client.py +1000 -0
  22. isa_agent_sdk/clients/user_client.py +446 -0
  23. isa_agent_sdk/components/__init__.py +23 -0
  24. isa_agent_sdk/components/billing_service.py +762 -0
  25. isa_agent_sdk/components/consul_discovery.py +112 -0
  26. isa_agent_sdk/components/multimodal_processor.py +416 -0
  27. isa_agent_sdk/components/session_service.py +321 -0
  28. isa_agent_sdk/components/storage_service.py +552 -0
  29. isa_agent_sdk/components/user_service.py +519 -0
  30. isa_agent_sdk/core/__init__.py +4 -0
  31. isa_agent_sdk/core/config/__init__.py +82 -0
  32. isa_agent_sdk/core/config/agent_config.py +329 -0
  33. isa_agent_sdk/core/config/consul_config.py +47 -0
  34. isa_agent_sdk/core/config/infra_config.py +148 -0
  35. isa_agent_sdk/core/config/lightning_config.py +89 -0
  36. isa_agent_sdk/core/config/logging_config.py +21 -0
  37. isa_agent_sdk/core/config/model_config.py +104 -0
  38. isa_agent_sdk/core/config/service_config.py +104 -0
  39. isa_agent_sdk/core/errors/__init__.py +3 -0
  40. isa_agent_sdk/core/errors/error_handler.py +240 -0
  41. isa_agent_sdk/core/resilience/__init__.py +4 -0
  42. isa_agent_sdk/core/resilience/circuit_breaker.py +205 -0
  43. isa_agent_sdk/core/resilience/connection_limiter.py +191 -0
  44. isa_agent_sdk/core/resilience/rate_limiter.py +202 -0
  45. isa_agent_sdk/core/resilience/system_protection.py +202 -0
  46. isa_agent_sdk/core/resilience/timeouts.py +123 -0
  47. isa_agent_sdk/graphs/__init__.py +14 -0
  48. isa_agent_sdk/graphs/base_graph.py +180 -0
  49. isa_agent_sdk/graphs/coding_graph.py +298 -0
  50. isa_agent_sdk/graphs/conversation_graph.py +127 -0
  51. isa_agent_sdk/graphs/graph_config_service.py +574 -0
  52. isa_agent_sdk/graphs/graph_registry_with_auth.py +581 -0
  53. isa_agent_sdk/graphs/graph_stream.py +252 -0
  54. isa_agent_sdk/graphs/research_graph.py +208 -0
  55. isa_agent_sdk/graphs/smart_agent_graph.py +917 -0
  56. isa_agent_sdk/graphs/utils/__init__.py +5 -0
  57. isa_agent_sdk/graphs/utils/context_init.py +1235 -0
  58. isa_agent_sdk/graphs/utils/context_schema.py +120 -0
  59. isa_agent_sdk/graphs/utils/context_update.py +117 -0
  60. isa_agent_sdk/graphs/utils/graph_lifecycle.py +267 -0
  61. isa_agent_sdk/graphs/utils/memory_utils.py +616 -0
  62. isa_agent_sdk/nodes/__init__.py +33 -0
  63. isa_agent_sdk/nodes/agent_executor_node.py +1099 -0
  64. isa_agent_sdk/nodes/agent_nodes/react_agent.py +298 -0
  65. isa_agent_sdk/nodes/base_node.py +727 -0
  66. isa_agent_sdk/nodes/docs/entry_node.md +275 -0
  67. isa_agent_sdk/nodes/docs/failsafe_node.md +314 -0
  68. isa_agent_sdk/nodes/docs/guardrail_node.md +550 -0
  69. isa_agent_sdk/nodes/docs/model_node.md +328 -0
  70. isa_agent_sdk/nodes/docs/response_node.md +0 -0
  71. isa_agent_sdk/nodes/docs/revise_node.md +441 -0
  72. isa_agent_sdk/nodes/docs/router_node.md +356 -0
  73. isa_agent_sdk/nodes/docs/tool_node.md +352 -0
  74. isa_agent_sdk/nodes/failsafe_node.py +650 -0
  75. isa_agent_sdk/nodes/guardrail_node.py +375 -0
  76. isa_agent_sdk/nodes/reason_node.py +665 -0
  77. isa_agent_sdk/nodes/response_node.py +339 -0
  78. isa_agent_sdk/nodes/sense_node.py +514 -0
  79. isa_agent_sdk/nodes/summarization_node.py +308 -0
  80. isa_agent_sdk/nodes/tool_node.py +655 -0
  81. isa_agent_sdk/nodes/utils/__init__.py +15 -0
  82. isa_agent_sdk/nodes/utils/artifact_detector.py +293 -0
  83. isa_agent_sdk/nodes/utils/background_hil_detector.py +349 -0
  84. isa_agent_sdk/nodes/utils/credential_auth.py +0 -0
  85. isa_agent_sdk/nodes/utils/event_trigger_manager.py +702 -0
  86. isa_agent_sdk/nodes/utils/oauth_auth.py +0 -0
  87. isa_agent_sdk/nodes/utils/tool_hil_detector.py +185 -0
  88. isa_agent_sdk/nodes/utils/tool_hil_router.py +182 -0
  89. isa_agent_sdk/options.py +409 -0
  90. isa_agent_sdk/services/auto_detection/DESIGN.md +1601 -0
  91. isa_agent_sdk/services/auto_detection/MCP_PROGRESS_INTEGRATION.md +473 -0
  92. isa_agent_sdk/services/auto_detection/README.md +197 -0
  93. isa_agent_sdk/services/auto_detection/tool_profiler.py +384 -0
  94. isa_agent_sdk/services/background_jobs/README.md +353 -0
  95. isa_agent_sdk/services/background_jobs/__init__.py +286 -0
  96. isa_agent_sdk/services/background_jobs/docs/DOCKER_TEST_RESULTS.md +340 -0
  97. isa_agent_sdk/services/background_jobs/docs/INTEGRATION_COMPLETE.md +454 -0
  98. isa_agent_sdk/services/background_jobs/docs/integration.md +225 -0
  99. isa_agent_sdk/services/background_jobs/nats_task_queue.py +372 -0
  100. isa_agent_sdk/services/background_jobs/redis_state_manager.py +362 -0
  101. isa_agent_sdk/services/background_jobs/task_models.py +105 -0
  102. isa_agent_sdk/services/background_jobs/task_worker.py +479 -0
  103. isa_agent_sdk/services/background_jobs/tests/test_task_approval.py +339 -0
  104. isa_agent_sdk/services/base_service.py +33 -0
  105. isa_agent_sdk/services/chat_service.py +1209 -0
  106. isa_agent_sdk/services/feedback/INDUSTRY_ANALYSIS.md +313 -0
  107. isa_agent_sdk/services/feedback/MIGRATION_SUMMARY.md +255 -0
  108. isa_agent_sdk/services/feedback/README.md +437 -0
  109. isa_agent_sdk/services/feedback/__init__.py +82 -0
  110. isa_agent_sdk/services/feedback/aggregator.py +297 -0
  111. isa_agent_sdk/services/feedback/analyzers/__init__.py +13 -0
  112. isa_agent_sdk/services/feedback/analyzers/pattern_analyzer.py +355 -0
  113. isa_agent_sdk/services/feedback/analyzers/semantic_analyzer.py +267 -0
  114. isa_agent_sdk/services/feedback/collectors.py +155 -0
  115. isa_agent_sdk/services/feedback/feedback_service.py +338 -0
  116. isa_agent_sdk/services/feedback/models.py +372 -0
  117. isa_agent_sdk/services/feedback/old/README.md +1 -0
  118. isa_agent_sdk/services/feedback/tests/test_feedback_service_mvp.py +217 -0
  119. isa_agent_sdk/services/hardware_service.py +299 -0
  120. isa_agent_sdk/services/human_in_the_loop/README.md +327 -0
  121. isa_agent_sdk/services/human_in_the_loop/__init__.py +132 -0
  122. isa_agent_sdk/services/human_in_the_loop/docs/TOOL_AUTH_HIL_FLOW_EXPLAINED.md +361 -0
  123. isa_agent_sdk/services/human_in_the_loop/hil_service.py +489 -0
  124. isa_agent_sdk/services/human_in_the_loop/interrupt_manager.py +343 -0
  125. isa_agent_sdk/services/human_in_the_loop/models.py +600 -0
  126. isa_agent_sdk/services/human_in_the_loop/old/FEATURE_COMPARISON.md +126 -0
  127. isa_agent_sdk/services/human_in_the_loop/old/README.md +1 -0
  128. isa_agent_sdk/services/human_in_the_loop/scenario_handlers.py +518 -0
  129. isa_agent_sdk/services/human_in_the_loop/tests/__init__.py +4 -0
  130. isa_agent_sdk/services/human_in_the_loop/tests/debug_failed_scenarios.py +165 -0
  131. isa_agent_sdk/services/human_in_the_loop/tests/test_hil_scenarios.py +683 -0
  132. isa_agent_sdk/services/human_in_the_loop/tests/test_hil_service.py +492 -0
  133. isa_agent_sdk/services/human_in_the_loop/tests/test_plan_tools_hil_auto.py +253 -0
  134. isa_agent_sdk/services/human_in_the_loop/tests/test_plan_tools_hil_integration.py +582 -0
  135. isa_agent_sdk/services/human_in_the_loop/tests/test_timeout_handler.py +373 -0
  136. isa_agent_sdk/services/human_in_the_loop/timeout_handler.py +290 -0
  137. isa_agent_sdk/services/human_in_the_loop/validators.py +237 -0
  138. isa_agent_sdk/services/lightning/__init__.py +35 -0
  139. isa_agent_sdk/services/lightning/adapter.py +163 -0
  140. isa_agent_sdk/services/lightning/lightning_store.py +111 -0
  141. isa_agent_sdk/services/lightning/service.py +375 -0
  142. isa_agent_sdk/services/lightning/tracer.py +178 -0
  143. isa_agent_sdk/services/persistence/__init__.py +31 -0
  144. isa_agent_sdk/services/persistence/durable_service.py +673 -0
  145. isa_agent_sdk/services/persistence/execution_manager.py +490 -0
  146. isa_agent_sdk/services/persistence/session_checkpointer.py +582 -0
  147. isa_agent_sdk/services/persistence/tests/check_manual_checkpoint.py +68 -0
  148. isa_agent_sdk/services/persistence/tests/check_recent_checkpoints.py +67 -0
  149. isa_agent_sdk/services/trace/__init__.py +25 -0
  150. isa_agent_sdk/services/trace/mcp_callback.py +252 -0
  151. isa_agent_sdk/services/trace/migrations/README.md +82 -0
  152. isa_agent_sdk/services/trace/model.py +0 -0
  153. isa_agent_sdk/services/trace/model_callback.py +288 -0
  154. isa_agent_sdk/services/trace/trace_writer.py +248 -0
  155. isa_agent_sdk/services/triggers/__init__.py +39 -0
  156. isa_agent_sdk/services/triggers/nats_event_bus.py +568 -0
  157. isa_agent_sdk/services/triggers/trigger_service.py +545 -0
  158. isa_agent_sdk/services/utils/stream_processor.py +993 -0
  159. isa_agent_sdk/utils/__init__.py +13 -0
  160. isa_agent_sdk/utils/logger.py +230 -0
  161. isa_agent_sdk/utils/task_manager.py +208 -0
  162. isa_agent_sdk-0.1.0.dist-info/METADATA +171 -0
  163. isa_agent_sdk-0.1.0.dist-info/RECORD +165 -0
  164. isa_agent_sdk-0.1.0.dist-info/WHEEL +5 -0
  165. isa_agent_sdk-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,220 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ isA Agent SDK
4
+ =============
5
+
6
+ A complete AI Agent SDK for building intelligent agents with advanced features.
7
+ Compatible with Claude Agent SDK patterns, with additional capabilities.
8
+
9
+ Quick Start:
10
+ from isa_agent_sdk import query, ISAAgentOptions
11
+
12
+ # Simple usage
13
+ async for msg in query("Hello, world!"):
14
+ print(msg.content)
15
+
16
+ # With options
17
+ async for msg in query(
18
+ "Fix the bug",
19
+ options=ISAAgentOptions(
20
+ allowed_tools=["Read", "Edit", "Bash"],
21
+ execution_mode="collaborative"
22
+ )
23
+ ):
24
+ print(msg)
25
+
26
+ # Human-in-the-loop
27
+ from isa_agent_sdk import request_tool_permission, checkpoint
28
+
29
+ authorized = await request_tool_permission("delete_file", {"path": "data.txt"})
30
+ if authorized:
31
+ # proceed...
32
+
33
+ # HTTP Client (for deployed apps)
34
+ from isa_agent_sdk import ISAAgent
35
+
36
+ client = ISAAgent(base_url="http://localhost:8000")
37
+ response = client.chat.create(message="Hello!", user_id="user123")
38
+
39
+ Features:
40
+ - Claude Agent SDK-compatible API
41
+ - Streaming message interface
42
+ - Built-in tools (Read, Write, Edit, Bash, etc.)
43
+ - MCP server integration
44
+ - Skills system (prompt injection)
45
+ - Human-in-the-Loop (durable execution, survives restarts)
46
+ - Multiple execution modes (reactive, collaborative, proactive)
47
+ - Multiple environments (cloud_pool, cloud_shared, desktop)
48
+ - Event triggers (proactive agent activation)
49
+ """
50
+
51
+ # Version
52
+ __version__ = "0.1.0"
53
+
54
+ # Configuration options (no circular imports)
55
+ from .options import (
56
+ ISAAgentOptions,
57
+ Options, # Alias
58
+ ExecutionEnv,
59
+ ExecutionMode,
60
+ ToolDiscoveryMode,
61
+ PermissionMode,
62
+ GuardrailMode,
63
+ MCPServerConfig,
64
+ AgentDefinition,
65
+ HookMatcher,
66
+ PoolConfig,
67
+ TriggerConfig,
68
+ )
69
+
70
+ # HTTP Client (standalone, no circular imports)
71
+ from .agent_client import (
72
+ ISAAgent,
73
+ ISAAgentSync,
74
+ AgentEvent,
75
+ AgentResponse,
76
+ SessionInfo,
77
+ EventType,
78
+ )
79
+
80
+
81
+ # Cache for lazily imported modules
82
+ _lazy_modules = {}
83
+
84
+ # Lazy imports for modules with complex dependencies
85
+ def __getattr__(name):
86
+ """Lazy import for modules with circular dependency potential"""
87
+ import importlib
88
+
89
+ # Core query functions
90
+ if name in ("query", "query_sync", "ask", "ask_sync", "execute_tool",
91
+ "get_available_tools", "get_session_state", "resume",
92
+ "resume_sync", "QueryExecutor"):
93
+ if "_query" not in _lazy_modules:
94
+ _lazy_modules["_query"] = importlib.import_module("._query", "isa_agent_sdk")
95
+ return getattr(_lazy_modules["_query"], name)
96
+
97
+ # Message types
98
+ if name in ("AgentMessage", "ConversationHistory", "ISAEventType",
99
+ "EventData", "EventEmitter", "EventCategory",
100
+ "MESSAGE_TYPE_MAP", "REVERSE_TYPE_MAP"):
101
+ if "_messages" not in _lazy_modules:
102
+ _lazy_modules["_messages"] = importlib.import_module("._messages", "isa_agent_sdk")
103
+ return getattr(_lazy_modules["_messages"], name)
104
+
105
+ # Human-in-the-Loop
106
+ if name in ("get_hil", "request_tool_permission", "request_authorization",
107
+ "collect_input", "collect_credentials", "collect_selection",
108
+ "request_review", "request_plan_approval", "request_execution_choice",
109
+ "checkpoint", "get_hil_stats", "clear_hil_history"):
110
+ if "_hil" not in _lazy_modules:
111
+ _lazy_modules["_hil"] = importlib.import_module("._hil", "isa_agent_sdk")
112
+ return getattr(_lazy_modules["_hil"], name)
113
+
114
+ # Skills system
115
+ if name in ("Skill", "SkillManager", "BUILTIN_SKILLS", "get_skill_manager",
116
+ "load_skill", "load_builtin_skill", "activate_skills",
117
+ "get_skill_injection", "list_builtin_skills"):
118
+ if "_skills" not in _lazy_modules:
119
+ _lazy_modules["_skills"] = importlib.import_module("._skills", "isa_agent_sdk")
120
+ return getattr(_lazy_modules["_skills"], name)
121
+
122
+ # Event Triggers
123
+ if name in ("TriggerType", "TriggerCondition", "register_trigger",
124
+ "unregister_trigger", "get_user_triggers", "get_trigger_stats",
125
+ "initialize_triggers", "shutdown_triggers", "get_trigger_manager",
126
+ "register_price_trigger", "register_schedule_trigger",
127
+ "register_event_pattern_trigger"):
128
+ if "_triggers" not in _lazy_modules:
129
+ _lazy_modules["_triggers"] = importlib.import_module("._triggers", "isa_agent_sdk")
130
+ return getattr(_lazy_modules["_triggers"], name)
131
+
132
+ raise AttributeError(f"module 'isa_agent_sdk' has no attribute '{name}'")
133
+
134
+ __all__ = [
135
+ # Version
136
+ "__version__",
137
+
138
+ # Core functions
139
+ "query",
140
+ "query_sync",
141
+ "ask",
142
+ "ask_sync",
143
+ "execute_tool",
144
+ "get_available_tools",
145
+ "get_session_state",
146
+ "resume",
147
+ "resume_sync",
148
+ "QueryExecutor",
149
+
150
+ # Options
151
+ "ISAAgentOptions",
152
+ "Options",
153
+ "ExecutionEnv",
154
+ "ExecutionMode",
155
+ "ToolDiscoveryMode",
156
+ "PermissionMode",
157
+ "GuardrailMode",
158
+ "MCPServerConfig",
159
+ "AgentDefinition",
160
+ "HookMatcher",
161
+ "PoolConfig",
162
+ "TriggerConfig",
163
+
164
+ # Messages
165
+ "AgentMessage",
166
+ "ConversationHistory",
167
+ "ISAEventType",
168
+ "EventData",
169
+ "EventEmitter",
170
+ "EventCategory",
171
+ "MESSAGE_TYPE_MAP",
172
+ "REVERSE_TYPE_MAP",
173
+
174
+ # Human-in-the-Loop
175
+ "get_hil",
176
+ "request_tool_permission",
177
+ "request_authorization",
178
+ "collect_input",
179
+ "collect_credentials",
180
+ "collect_selection",
181
+ "request_review",
182
+ "request_plan_approval",
183
+ "request_execution_choice",
184
+ "checkpoint",
185
+ "get_hil_stats",
186
+ "clear_hil_history",
187
+
188
+ # Skills
189
+ "Skill",
190
+ "SkillManager",
191
+ "BUILTIN_SKILLS",
192
+ "get_skill_manager",
193
+ "load_skill",
194
+ "load_builtin_skill",
195
+ "activate_skills",
196
+ "get_skill_injection",
197
+ "list_builtin_skills",
198
+
199
+ # Event Triggers
200
+ "TriggerType",
201
+ "TriggerCondition",
202
+ "register_trigger",
203
+ "unregister_trigger",
204
+ "get_user_triggers",
205
+ "get_trigger_stats",
206
+ "initialize_triggers",
207
+ "shutdown_triggers",
208
+ "get_trigger_manager",
209
+ "register_price_trigger",
210
+ "register_schedule_trigger",
211
+ "register_event_pattern_trigger",
212
+
213
+ # HTTP Client
214
+ "ISAAgent",
215
+ "ISAAgentSync",
216
+ "AgentEvent",
217
+ "AgentResponse",
218
+ "SessionInfo",
219
+ "EventType",
220
+ ]
isa_agent_sdk/_hil.py ADDED
@@ -0,0 +1,482 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ isA Agent SDK - Human-in-the-Loop Integration
4
+ ==============================================
5
+
6
+ SDK wrapper around the existing HIL service.
7
+ Provides Claude SDK-compatible interface while using isA's powerful
8
+ durable execution HIL system underneath.
9
+
10
+ isA's HIL is MORE powerful than Claude SDK hooks:
11
+ - Durable execution (survives restarts via LangGraph checkpointing)
12
+ - Async human responses (can wait hours/days)
13
+ - Full scenarios: authorization, review, input validation with retry
14
+
15
+ Example:
16
+ from isa_agent_sdk import query, ISAAgentOptions
17
+ from isa_agent_sdk.hil import request_tool_permission, collect_input
18
+
19
+ # Request permission before dangerous operation
20
+ authorized = await request_tool_permission(
21
+ tool_name="delete_file",
22
+ tool_args={"path": "/important/data.txt"},
23
+ reason="User requested file deletion"
24
+ )
25
+
26
+ if authorized:
27
+ # Proceed with operation
28
+ ...
29
+ """
30
+
31
+ from typing import Dict, Any, Optional, List
32
+
33
+ # Import the existing HIL service - REUSE, don't duplicate!
34
+ from .services.human_in_the_loop import get_hil_service, HILService
35
+ from .services.human_in_the_loop.models import InterruptStats
36
+
37
+
38
+ def get_hil() -> HILService:
39
+ """
40
+ Get the HIL service instance.
41
+
42
+ Returns:
43
+ HILService singleton instance
44
+ """
45
+ return get_hil_service()
46
+
47
+
48
+ # === Authorization Methods ===
49
+
50
+ async def request_tool_permission(
51
+ tool_name: str,
52
+ tool_args: Dict[str, Any],
53
+ security_level: str = "HIGH",
54
+ reason: Optional[str] = None,
55
+ user_id: str = "default"
56
+ ) -> bool:
57
+ """
58
+ Request permission to execute a tool.
59
+
60
+ This pauses graph execution until human responds.
61
+ Uses durable execution - survives process restarts.
62
+
63
+ Args:
64
+ tool_name: Name of tool requesting permission
65
+ tool_args: Arguments for the tool
66
+ security_level: Security level (LOW, MEDIUM, HIGH, CRITICAL)
67
+ reason: Reason for needing this tool
68
+ user_id: User identifier
69
+
70
+ Returns:
71
+ True if authorized, False if rejected
72
+
73
+ Example:
74
+ authorized = await request_tool_permission(
75
+ tool_name="web_crawl",
76
+ tool_args={"url": "https://example.com"},
77
+ security_level="HIGH",
78
+ reason="Need to fetch page content"
79
+ )
80
+ """
81
+ hil = get_hil_service()
82
+ return await hil.request_authorization(
83
+ scenario="tool_authorization",
84
+ data={
85
+ "action": f"Execute tool: {tool_name}",
86
+ "tool_name": tool_name,
87
+ "tool_args": tool_args,
88
+ "reason": reason or f"Tool {tool_name} requires authorization",
89
+ "risk_level": security_level.lower(),
90
+ "context": {"tool_name": tool_name, "args": tool_args}
91
+ },
92
+ user_id=user_id,
93
+ node_source="sdk"
94
+ )
95
+
96
+
97
+ async def request_authorization(
98
+ action: str,
99
+ reason: str,
100
+ context: Optional[Dict[str, Any]] = None,
101
+ risk_level: str = "medium",
102
+ user_id: str = "default"
103
+ ) -> bool:
104
+ """
105
+ Request generic authorization for an action.
106
+
107
+ Args:
108
+ action: Description of the action
109
+ reason: Why authorization is needed
110
+ context: Additional context
111
+ risk_level: Risk level (low, medium, high, critical)
112
+ user_id: User identifier
113
+
114
+ Returns:
115
+ True if authorized, False if rejected
116
+
117
+ Example:
118
+ authorized = await request_authorization(
119
+ action="Delete all temporary files",
120
+ reason="Cleanup requested by user",
121
+ risk_level="high"
122
+ )
123
+ """
124
+ hil = get_hil_service()
125
+ return await hil.request_authorization(
126
+ scenario="generic",
127
+ data={
128
+ "action": action,
129
+ "reason": reason,
130
+ "risk_level": risk_level,
131
+ "context": context or {}
132
+ },
133
+ user_id=user_id,
134
+ node_source="sdk"
135
+ )
136
+
137
+
138
+ # === Input Collection Methods ===
139
+
140
+ async def collect_input(
141
+ prompt: str,
142
+ description: Optional[str] = None,
143
+ input_type: str = "text",
144
+ schema: Optional[Dict[str, Any]] = None,
145
+ user_id: str = "default"
146
+ ) -> Any:
147
+ """
148
+ Collect input from the user.
149
+
150
+ Pauses execution until user provides input.
151
+
152
+ Args:
153
+ prompt: Question/prompt for the user
154
+ description: Additional description
155
+ input_type: Type of input (text, number, boolean, selection)
156
+ schema: JSON schema for validation
157
+ user_id: User identifier
158
+
159
+ Returns:
160
+ User's input (validated if schema provided)
161
+
162
+ Example:
163
+ email = await collect_input(
164
+ prompt="What is your email address?",
165
+ input_type="text",
166
+ schema={"type": "string", "format": "email"}
167
+ )
168
+ """
169
+ hil = get_hil_service()
170
+ return await hil.request_input(
171
+ scenario="generic",
172
+ data={
173
+ "prompt": prompt,
174
+ "description": description or prompt,
175
+ "input_type": input_type,
176
+ "schema": schema
177
+ },
178
+ user_id=user_id,
179
+ node_source="sdk"
180
+ )
181
+
182
+
183
+ async def collect_credentials(
184
+ prompt: str,
185
+ credential_type: str = "api_key",
186
+ description: Optional[str] = None,
187
+ user_id: str = "default"
188
+ ) -> str:
189
+ """
190
+ Collect credentials from the user.
191
+
192
+ Args:
193
+ prompt: Prompt for credentials
194
+ credential_type: Type (api_key, password, token)
195
+ description: Additional description
196
+ user_id: User identifier
197
+
198
+ Returns:
199
+ Credential string
200
+
201
+ Example:
202
+ api_key = await collect_credentials(
203
+ prompt="Enter your OpenAI API key",
204
+ credential_type="api_key"
205
+ )
206
+ """
207
+ hil = get_hil_service()
208
+ return await hil.request_input(
209
+ scenario="credentials",
210
+ data={
211
+ "input_type": "credentials",
212
+ "prompt": prompt,
213
+ "description": description or prompt,
214
+ "credential_type": credential_type
215
+ },
216
+ user_id=user_id,
217
+ node_source="sdk"
218
+ )
219
+
220
+
221
+ async def collect_selection(
222
+ prompt: str,
223
+ options: List[str],
224
+ description: Optional[str] = None,
225
+ user_id: str = "default"
226
+ ) -> str:
227
+ """
228
+ Collect a selection from predefined options.
229
+
230
+ Args:
231
+ prompt: Question for the user
232
+ options: List of options to choose from
233
+ description: Additional description
234
+ user_id: User identifier
235
+
236
+ Returns:
237
+ Selected option
238
+
239
+ Example:
240
+ choice = await collect_selection(
241
+ prompt="Which database should I use?",
242
+ options=["PostgreSQL", "MySQL", "SQLite"]
243
+ )
244
+ """
245
+ hil = get_hil_service()
246
+ return await hil.request_input(
247
+ scenario="selection",
248
+ data={
249
+ "input_type": "selection",
250
+ "prompt": prompt,
251
+ "description": description or prompt,
252
+ "options": options
253
+ },
254
+ user_id=user_id,
255
+ node_source="sdk"
256
+ )
257
+
258
+
259
+ # === Review Methods ===
260
+
261
+ async def request_review(
262
+ content: str,
263
+ content_type: str = "text",
264
+ instructions: Optional[str] = None,
265
+ editable: bool = True,
266
+ user_id: str = "default"
267
+ ) -> Dict[str, Any]:
268
+ """
269
+ Request human review of content.
270
+
271
+ Args:
272
+ content: Content to review
273
+ content_type: Type (text, code, plan, config)
274
+ instructions: Review instructions
275
+ editable: Whether user can edit
276
+ user_id: User identifier
277
+
278
+ Returns:
279
+ Dict with 'approved' (bool), 'edited_content' (if edited), 'action' (str)
280
+
281
+ Example:
282
+ result = await request_review(
283
+ content=generated_code,
284
+ content_type="code",
285
+ instructions="Review this code before execution",
286
+ editable=True
287
+ )
288
+ if result['approved']:
289
+ code = result.get('edited_content', generated_code)
290
+ """
291
+ hil = get_hil_service()
292
+ return await hil.request_review(
293
+ scenario=content_type if content_type in ["code", "config"] else "generic",
294
+ data={
295
+ "content": content,
296
+ "content_type": content_type,
297
+ "instructions": instructions or f"Please review this {content_type}",
298
+ "editable": editable
299
+ },
300
+ user_id=user_id,
301
+ node_source="sdk"
302
+ )
303
+
304
+
305
+ async def request_plan_approval(
306
+ plan: str,
307
+ plan_title: Optional[str] = None,
308
+ user_id: str = "default"
309
+ ) -> Dict[str, Any]:
310
+ """
311
+ Request approval for an execution plan.
312
+
313
+ Args:
314
+ plan: The plan content (text or JSON)
315
+ plan_title: Title for the plan
316
+ user_id: User identifier
317
+
318
+ Returns:
319
+ Dict with 'approved' (bool), 'edited_content' (if edited)
320
+
321
+ Example:
322
+ result = await request_plan_approval(
323
+ plan="1. Read file\\n2. Parse data\\n3. Update database",
324
+ plan_title="Data Migration Plan"
325
+ )
326
+ """
327
+ hil = get_hil_service()
328
+ return await hil.request_review(
329
+ scenario="execution_plan",
330
+ data={
331
+ "content": plan,
332
+ "content_type": "execution_plan",
333
+ "instructions": f"Review execution plan: {plan_title or 'Untitled'}",
334
+ "editable": True
335
+ },
336
+ user_id=user_id,
337
+ node_source="sdk"
338
+ )
339
+
340
+
341
+ # === Execution Choice ===
342
+
343
+ async def request_execution_choice(
344
+ prompt: str,
345
+ options: List[Dict[str, str]],
346
+ estimated_time_seconds: Optional[float] = None,
347
+ recommendation: Optional[str] = None,
348
+ user_id: str = "default"
349
+ ) -> str:
350
+ """
351
+ Request user choice for execution strategy.
352
+
353
+ Useful for long-running tasks where user can choose
354
+ between quick/comprehensive/background execution.
355
+
356
+ Args:
357
+ prompt: Description of the situation
358
+ options: List of options with 'value', 'label', 'description'
359
+ estimated_time_seconds: Estimated execution time
360
+ recommendation: Recommended option value
361
+ user_id: User identifier
362
+
363
+ Returns:
364
+ Selected option value
365
+
366
+ Example:
367
+ choice = await request_execution_choice(
368
+ prompt="This task will take ~60 seconds",
369
+ options=[
370
+ {"value": "quick", "label": "Quick", "description": "Fast (~30s)"},
371
+ {"value": "full", "label": "Full", "description": "Complete (~60s)"},
372
+ {"value": "background", "label": "Background", "description": "Run async"}
373
+ ],
374
+ recommendation="background"
375
+ )
376
+ """
377
+ hil = get_hil_service()
378
+ return await hil.request_execution_choice(
379
+ scenario="long_running_task",
380
+ data={
381
+ "prompt": prompt,
382
+ "options": options,
383
+ "estimated_time_seconds": estimated_time_seconds,
384
+ "recommendation": recommendation
385
+ },
386
+ user_id=user_id,
387
+ node_source="sdk"
388
+ )
389
+
390
+
391
+ # === Checkpoint (Collaborative Mode) ===
392
+
393
+ async def checkpoint(
394
+ message: str,
395
+ context: Optional[Dict[str, Any]] = None,
396
+ require_approval: bool = True,
397
+ user_id: str = "default"
398
+ ) -> bool:
399
+ """
400
+ Create a checkpoint in collaborative mode.
401
+
402
+ Pauses execution for human review/approval before continuing.
403
+
404
+ Args:
405
+ message: Checkpoint message/question
406
+ context: Additional context to show
407
+ require_approval: Whether to require explicit approval
408
+ user_id: User identifier
409
+
410
+ Returns:
411
+ True if approved to continue, False otherwise
412
+
413
+ Example:
414
+ # In collaborative mode, checkpoint every N steps
415
+ approved = await checkpoint(
416
+ message="Completed step 3. Ready to proceed?",
417
+ context={"completed": ["step1", "step2", "step3"]}
418
+ )
419
+ """
420
+ if not require_approval:
421
+ return True
422
+
423
+ hil = get_hil_service()
424
+ return await hil.request_authorization(
425
+ scenario="generic",
426
+ data={
427
+ "action": "Continue execution",
428
+ "reason": message,
429
+ "risk_level": "low",
430
+ "context": context or {}
431
+ },
432
+ user_id=user_id,
433
+ node_source="sdk_checkpoint"
434
+ )
435
+
436
+
437
+ # === Statistics ===
438
+
439
+ def get_hil_stats() -> InterruptStats:
440
+ """
441
+ Get HIL interrupt statistics.
442
+
443
+ Returns:
444
+ InterruptStats with total, by_type, by_node, latest
445
+ """
446
+ hil = get_hil_service()
447
+ return hil.get_interrupt_stats()
448
+
449
+
450
+ def clear_hil_history() -> None:
451
+ """Clear HIL interrupt history"""
452
+ hil = get_hil_service()
453
+ hil.clear_interrupt_history()
454
+
455
+
456
+ __all__ = [
457
+ # Service access
458
+ "get_hil",
459
+
460
+ # Authorization
461
+ "request_tool_permission",
462
+ "request_authorization",
463
+
464
+ # Input collection
465
+ "collect_input",
466
+ "collect_credentials",
467
+ "collect_selection",
468
+
469
+ # Review
470
+ "request_review",
471
+ "request_plan_approval",
472
+
473
+ # Execution choice
474
+ "request_execution_choice",
475
+
476
+ # Collaborative mode
477
+ "checkpoint",
478
+
479
+ # Statistics
480
+ "get_hil_stats",
481
+ "clear_hil_history",
482
+ ]