connectonion 0.5.10__py3-none-any.whl → 0.6.1__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 (65) hide show
  1. connectonion/__init__.py +17 -16
  2. connectonion/cli/browser_agent/browser.py +488 -145
  3. connectonion/cli/browser_agent/scroll_strategies.py +276 -0
  4. connectonion/cli/commands/copy_commands.py +24 -1
  5. connectonion/cli/commands/deploy_commands.py +15 -0
  6. connectonion/cli/commands/eval_commands.py +286 -0
  7. connectonion/cli/commands/project_cmd_lib.py +1 -1
  8. connectonion/cli/main.py +11 -0
  9. connectonion/console.py +5 -5
  10. connectonion/core/__init__.py +53 -0
  11. connectonion/{agent.py → core/agent.py} +18 -15
  12. connectonion/{llm.py → core/llm.py} +9 -19
  13. connectonion/{tool_executor.py → core/tool_executor.py} +3 -2
  14. connectonion/{tool_factory.py → core/tool_factory.py} +3 -1
  15. connectonion/debug/__init__.py +51 -0
  16. connectonion/{interactive_debugger.py → debug/auto_debug.py} +7 -7
  17. connectonion/{auto_debug_exception.py → debug/auto_debug_exception.py} +3 -3
  18. connectonion/{debugger_ui.py → debug/auto_debug_ui.py} +1 -1
  19. connectonion/{debug_explainer → debug/debug_explainer}/explain_agent.py +1 -1
  20. connectonion/{debug_explainer → debug/debug_explainer}/explain_context.py +1 -1
  21. connectonion/{execution_analyzer → debug/execution_analyzer}/execution_analysis.py +1 -1
  22. connectonion/debug/runtime_inspector/__init__.py +13 -0
  23. connectonion/{debug_agent → debug/runtime_inspector}/agent.py +1 -1
  24. connectonion/{xray.py → debug/xray.py} +1 -1
  25. connectonion/llm_do.py +1 -1
  26. connectonion/logger.py +305 -135
  27. connectonion/network/__init__.py +37 -0
  28. connectonion/{announce.py → network/announce.py} +1 -1
  29. connectonion/{asgi.py → network/asgi.py} +122 -2
  30. connectonion/{connect.py → network/connect.py} +1 -1
  31. connectonion/network/connection.py +123 -0
  32. connectonion/{host.py → network/host.py} +31 -11
  33. connectonion/{trust.py → network/trust.py} +1 -1
  34. connectonion/tui/__init__.py +22 -0
  35. connectonion/tui/chat.py +647 -0
  36. connectonion/useful_events_handlers/reflect.py +2 -2
  37. connectonion/useful_plugins/__init__.py +4 -3
  38. connectonion/useful_plugins/calendar_plugin.py +2 -2
  39. connectonion/useful_plugins/eval.py +2 -2
  40. connectonion/useful_plugins/gmail_plugin.py +2 -2
  41. connectonion/useful_plugins/image_result_formatter.py +2 -2
  42. connectonion/useful_plugins/re_act.py +2 -2
  43. connectonion/useful_plugins/shell_approval.py +2 -2
  44. connectonion/useful_plugins/ui_stream.py +164 -0
  45. {connectonion-0.5.10.dist-info → connectonion-0.6.1.dist-info}/METADATA +4 -3
  46. connectonion-0.6.1.dist-info/RECORD +123 -0
  47. connectonion/debug_agent/__init__.py +0 -13
  48. connectonion-0.5.10.dist-info/RECORD +0 -115
  49. /connectonion/{events.py → core/events.py} +0 -0
  50. /connectonion/{tool_registry.py → core/tool_registry.py} +0 -0
  51. /connectonion/{usage.py → core/usage.py} +0 -0
  52. /connectonion/{debug_explainer → debug/debug_explainer}/__init__.py +0 -0
  53. /connectonion/{debug_explainer → debug/debug_explainer}/explainer_prompt.md +0 -0
  54. /connectonion/{debug_explainer → debug/debug_explainer}/root_cause_analysis_prompt.md +0 -0
  55. /connectonion/{decorators.py → debug/decorators.py} +0 -0
  56. /connectonion/{execution_analyzer → debug/execution_analyzer}/__init__.py +0 -0
  57. /connectonion/{execution_analyzer → debug/execution_analyzer}/execution_analysis_prompt.md +0 -0
  58. /connectonion/{debug_agent → debug/runtime_inspector}/prompts/debug_assistant.md +0 -0
  59. /connectonion/{debug_agent → debug/runtime_inspector}/runtime_inspector.py +0 -0
  60. /connectonion/{relay.py → network/relay.py} +0 -0
  61. /connectonion/{static → network/static}/docs.html +0 -0
  62. /connectonion/{trust_agents.py → network/trust_agents.py} +0 -0
  63. /connectonion/{trust_functions.py → network/trust_functions.py} +0 -0
  64. {connectonion-0.5.10.dist-info → connectonion-0.6.1.dist-info}/WHEEL +0 -0
  65. {connectonion-0.5.10.dist-info → connectonion-0.6.1.dist-info}/entry_points.txt +0 -0
connectonion/console.py CHANGED
@@ -110,7 +110,7 @@ class Console:
110
110
  ● ─────────────────────
111
111
  connectonion v0.5.1
112
112
  o4-mini · 3 tools
113
- .co/logs/ · .co/sessions/
113
+ .co/logs/ · .co/evals/
114
114
 
115
115
  Args:
116
116
  agent_name: Name of the agent
@@ -156,7 +156,7 @@ class Console:
156
156
 
157
157
  # Add log paths if logging is enabled
158
158
  if log_dir:
159
- lines.append(f" [{DIM_COLOR}]{log_dir}logs/ · {log_dir}sessions/[/{DIM_COLOR}]")
159
+ lines.append(f" [{DIM_COLOR}]{log_dir}logs/ · {log_dir}evals/[/{DIM_COLOR}]")
160
160
 
161
161
  # Add Aaron's message for free tier users
162
162
  if aaron_message:
@@ -182,7 +182,7 @@ class Console:
182
182
  if meta_line:
183
183
  plain_lines.append(f" {meta_line}")
184
184
  if log_dir:
185
- plain_lines.append(f" {log_dir}logs/ · {log_dir}sessions/")
185
+ plain_lines.append(f" {log_dir}logs/ · {log_dir}evals/")
186
186
  if aaron_message:
187
187
  plain_lines.append(f" {aaron_message}")
188
188
  plain_lines.append(f" {separator}")
@@ -484,12 +484,12 @@ class Console:
484
484
 
485
485
  [co] ═══════════════════════════════════════
486
486
  [co] ✓ done · 2.3k tokens · $0.005 · 3.4s
487
- [co] saved → .co/sessions/research-assistant.yaml
487
+ [co] saved → .co/evals/research-assistant.yaml
488
488
 
489
489
  Args:
490
490
  duration_s: Total duration in seconds
491
491
  session: Agent's current_session dict (contains trace with usage)
492
- session_path: Optional path to session file
492
+ session_path: Optional path to eval file
493
493
  """
494
494
  # Calculate totals from trace
495
495
  trace = session.get('trace', [])
@@ -0,0 +1,53 @@
1
+ """Core agent execution engine.
2
+
3
+ This module contains the minimal set of components needed to run an agent:
4
+ - Agent: Main orchestrator
5
+ - LLM: Multi-provider LLM abstraction
6
+ - Events: Event system for lifecycle hooks
7
+ - Tools: Tool execution, factory, and registry
8
+ - Usage: Token tracking and cost calculation
9
+ """
10
+
11
+ from .agent import Agent
12
+ from .llm import LLM, create_llm, TokenUsage
13
+ from .events import (
14
+ EventHandler,
15
+ after_user_input,
16
+ before_llm,
17
+ after_llm,
18
+ before_each_tool,
19
+ before_tools,
20
+ after_each_tool,
21
+ after_tools,
22
+ on_error,
23
+ on_complete,
24
+ )
25
+ from .tool_factory import create_tool_from_function, extract_methods_from_instance, is_class_instance
26
+ from .tool_registry import ToolRegistry
27
+ from .tool_executor import execute_and_record_tools, execute_single_tool
28
+ from .usage import TokenUsage, calculate_cost, get_context_limit
29
+
30
+ __all__ = [
31
+ "Agent",
32
+ "LLM",
33
+ "create_llm",
34
+ "TokenUsage",
35
+ "EventHandler",
36
+ "after_user_input",
37
+ "before_llm",
38
+ "after_llm",
39
+ "before_each_tool",
40
+ "before_tools",
41
+ "after_each_tool",
42
+ "after_tools",
43
+ "on_error",
44
+ "on_complete",
45
+ "create_tool_from_function",
46
+ "extract_methods_from_instance",
47
+ "is_class_instance",
48
+ "ToolRegistry",
49
+ "execute_and_record_tools",
50
+ "execute_single_tool",
51
+ "calculate_cost",
52
+ "get_context_limit",
53
+ ]
@@ -2,9 +2,9 @@
2
2
  Purpose: Orchestrate AI agent execution with LLM calls, tool execution, and automatic logging
3
3
  LLM-Note:
4
4
  Dependencies: imports from [llm.py, tool_factory.py, prompts.py, decorators.py, logger.py, tool_executor.py, tool_registry.py] | imported by [__init__.py, debug_agent/__init__.py] | tested by [tests/test_agent.py, tests/test_agent_prompts.py, tests/test_agent_workflows.py]
5
- Data flow: receives user prompt: str from Agent.input() → creates/extends current_session with messages → calls llm.complete() with tool schemas → receives LLMResponse with tool_calls → executes tools via tool_executor.execute_and_record_tools() → appends tool results to messages → repeats loop until no tool_calls or max_iterations → logger logs to .co/logs/{name}.log and .co/sessions/{name}_{timestamp}.yaml → returns final response: str
6
- State/Effects: modifies self.current_session['messages', 'trace', 'turn', 'iteration'] | writes to .co/logs/{name}.log and .co/sessions/ via logger.py
7
- Integration: exposes Agent(name, tools, system_prompt, model, log, quiet), .input(prompt), .execute_tool(name, args), .add_tool(func), .remove_tool(name), .list_tools(), .reset_conversation() | tools stored in ToolRegistry with attribute access (agent.tools.tool_name) and instance storage (agent.tools.gmail) | tool execution delegates to tool_executor module | log defaults to .co/logs/ (None), can be True (current dir), False (disabled), or custom path | quiet=True suppresses console but keeps session logging | trust enforcement moved to host() for network access control
5
+ Data flow: receives user prompt: str from Agent.input() → creates/extends current_session with messages → calls llm.complete() with tool schemas → receives LLMResponse with tool_calls → executes tools via tool_executor.execute_and_record_tools() → appends tool results to messages → repeats loop until no tool_calls or max_iterations → logger logs to .co/logs/{name}.log and .co/evals/{name}.yaml → returns final response: str
6
+ State/Effects: modifies self.current_session['messages', 'trace', 'turn', 'iteration'] | writes to .co/logs/{name}.log and .co/evals/ via logger.py
7
+ Integration: exposes Agent(name, tools, system_prompt, model, log, quiet), .input(prompt), .execute_tool(name, args), .add_tool(func), .remove_tool(name), .list_tools(), .reset_conversation() | tools stored in ToolRegistry with attribute access (agent.tools.tool_name) and instance storage (agent.tools.gmail) | tool execution delegates to tool_executor module | log defaults to .co/logs/ (None), can be True (current dir), False (disabled), or custom path | quiet=True suppresses console but keeps eval logging | trust enforcement moved to host() for network access control
8
8
  Performance: max_iterations=10 default (configurable per-input) | session state persists across turns for multi-turn conversations | ToolRegistry provides O(1) tool lookup via .get() or attribute access
9
9
  Errors: LLM errors bubble up | tool execution errors captured in trace and returned to LLM for retry
10
10
  """
@@ -18,11 +18,11 @@ from .llm import LLM, create_llm, TokenUsage
18
18
  from .usage import get_context_limit
19
19
  from .tool_factory import create_tool_from_function, extract_methods_from_instance, is_class_instance
20
20
  from .tool_registry import ToolRegistry
21
- from .prompts import load_system_prompt
22
- from .decorators import (
21
+ from ..prompts import load_system_prompt
22
+ from ..debug.decorators import (
23
23
  _is_replay_enabled # Only need this for replay check
24
24
  )
25
- from .logger import Logger
25
+ from ..logger import Logger
26
26
  from .tool_executor import execute_and_record_tools, execute_single_tool
27
27
  from .events import EventHandler
28
28
 
@@ -51,11 +51,14 @@ class Agent:
51
51
  # Current session context (runtime only)
52
52
  self.current_session = None
53
53
 
54
+ # Connection to client (None locally, injected by host() for WebSocket)
55
+ self.connection = None
56
+
54
57
  # Token usage tracking
55
58
  self.total_cost: float = 0.0 # Cumulative cost in USD
56
59
  self.last_usage: Optional[TokenUsage] = None # From most recent LLM call
57
60
 
58
- # Initialize logger (unified: terminal + file + YAML sessions)
61
+ # Initialize logger (unified: terminal + file + YAML evals)
59
62
  # Environment variable override (highest priority)
60
63
  effective_log = log
61
64
  if os.getenv('CONNECTONION_LOG'):
@@ -250,16 +253,16 @@ class Agent:
250
253
 
251
254
  self.current_session['result'] = result
252
255
 
253
- # Print completion summary
254
- if self.logger.console:
255
- session_path = f".co/sessions/{self.name}.yaml" if self.logger.enable_sessions else None
256
- self.logger.console.print_completion(duration, self.current_session, session_path)
257
-
258
256
  self._invoke_events('on_complete')
259
257
 
260
- # Log turn to YAML session (after on_complete so handlers can modify state)
258
+ # Log turn to YAML eval (after on_complete so handlers can modify state)
261
259
  self.logger.log_turn(prompt, result, duration * 1000, self.current_session, self.llm.model)
262
260
 
261
+ # Print completion summary (after log_turn so we have the eval path)
262
+ if self.logger.console:
263
+ eval_path = self.logger.get_eval_path()
264
+ self.logger.console.print_completion(duration, self.current_session, eval_path)
265
+
263
266
  return result
264
267
 
265
268
  def reset_conversation(self):
@@ -444,7 +447,7 @@ class Agent:
444
447
  # Single prompt mode
445
448
  agent.auto_debug("Find information about Python")
446
449
  """
447
- from .interactive_debugger import InteractiveDebugger
448
- debugger = InteractiveDebugger(self)
450
+ from .debug import AutoDebugger
451
+ debugger = AutoDebugger(self)
449
452
  debugger.start_debug_session(prompt)
450
453
 
@@ -734,28 +734,18 @@ class OpenOnionLLM(LLM):
734
734
  )
735
735
 
736
736
  def structured_complete(self, messages: List[Dict], output_schema: Type[BaseModel], **kwargs) -> BaseModel:
737
- """Get structured Pydantic output using OpenAI-compatible API."""
738
- response = self.client.responses.parse(
737
+ """Get structured Pydantic output using OpenAI-compatible chat completions API.
738
+
739
+ Uses beta.chat.completions.parse() which routes through /v1/chat/completions,
740
+ allowing proper provider routing for Gemini, OpenAI, and other models.
741
+ """
742
+ completion = self.client.beta.chat.completions.parse(
739
743
  model=self.model,
740
- input=messages,
741
- text_format=output_schema,
744
+ messages=messages,
745
+ response_format=output_schema,
742
746
  **kwargs
743
747
  )
744
-
745
- # Handle edge cases
746
- if response.status == "incomplete":
747
- if response.incomplete_details.reason == "max_output_tokens":
748
- raise ValueError("Response incomplete: maximum output tokens reached")
749
- elif response.incomplete_details.reason == "content_filter":
750
- raise ValueError("Response incomplete: content filtered")
751
-
752
- # Check for refusal
753
- if response.output and len(response.output) > 0:
754
- first_content = response.output[0].content[0] if response.output[0].content else None
755
- if first_content and hasattr(first_content, 'type') and first_content.type == "refusal":
756
- raise ValueError(f"Model refused to respond: {first_content.refusal}")
757
-
758
- return response.output_parsed
748
+ return completion.choices[0].message.parsed
759
749
 
760
750
 
761
751
  def create_llm(model: str, api_key: Optional[str] = None, **kwargs) -> LLM:
@@ -13,7 +13,7 @@ import time
13
13
  import json
14
14
  from typing import List, Dict, Any, Optional, Callable
15
15
 
16
- from .xray import (
16
+ from ..debug.xray import (
17
17
  inject_xray_context,
18
18
  clear_xray_context,
19
19
  is_xray_enabled
@@ -165,7 +165,8 @@ def execute_single_tool(
165
165
  agent.current_session['pending_tool'] = {
166
166
  'name': tool_name,
167
167
  'arguments': tool_args,
168
- 'id': tool_id
168
+ 'id': tool_id,
169
+ 'description': getattr(tool_func, 'description', '')
169
170
  }
170
171
 
171
172
  # Invoke before_each_tool events
@@ -29,7 +29,9 @@ def create_tool_from_function(func: Callable) -> Callable:
29
29
  by inspecting its signature and docstring.
30
30
  """
31
31
  name = func.__name__
32
- description = inspect.getdoc(func) or f"Execute the {name} tool."
32
+ raw_doc = inspect.getdoc(func)
33
+ # Extract summary only (first paragraph) - Args/Returns sections are not sent to LLM
34
+ description = raw_doc.split('\n\n')[0].strip() if raw_doc else f"Execute the {name} tool."
33
35
 
34
36
  # Build the parameters schema from the function signature
35
37
  sig = inspect.signature(func)
@@ -0,0 +1,51 @@
1
+ """Debug tools for agent development and troubleshooting.
2
+
3
+ This module contains:
4
+ - xray: Runtime context injection for tool inspection
5
+ - decorators: replay, xray_replay for debugging
6
+ - auto_debug: Interactive debugging with breakpoints (AutoDebugger, AutoDebugUI)
7
+ - auto_debug_exception: Exception handling and debugging
8
+ - runtime_inspector: AI-powered runtime state inspection for crash debugging
9
+ - debug_explainer: AI-powered explanation of tool choices
10
+
11
+ Note: Uses lazy imports to avoid circular dependency with agent.py
12
+ """
13
+
14
+ # xray and decorators can be imported eagerly (no circular dependency)
15
+ from .xray import xray
16
+ from .decorators import replay, xray_replay
17
+
18
+ __all__ = [
19
+ "xray",
20
+ "replay",
21
+ "xray_replay",
22
+ "AutoDebugger",
23
+ "AutoDebugUI",
24
+ "BreakpointContext",
25
+ "BreakpointAction",
26
+ "auto_debug_exception",
27
+ "create_debug_agent",
28
+ "RuntimeInspector",
29
+ "explain_tool_choice",
30
+ "RuntimeContext",
31
+ ]
32
+
33
+
34
+ def __getattr__(name):
35
+ """Lazy import to avoid circular dependency with agent.py."""
36
+ if name == "AutoDebugger":
37
+ from .auto_debug import AutoDebugger
38
+ return AutoDebugger
39
+ elif name in ("AutoDebugUI", "BreakpointContext", "BreakpointAction"):
40
+ from .auto_debug_ui import AutoDebugUI, BreakpointContext, BreakpointAction
41
+ return {"AutoDebugUI": AutoDebugUI, "BreakpointContext": BreakpointContext, "BreakpointAction": BreakpointAction}[name]
42
+ elif name == "auto_debug_exception":
43
+ from .auto_debug_exception import auto_debug_exception
44
+ return auto_debug_exception
45
+ elif name in ("create_debug_agent", "RuntimeInspector"):
46
+ from .runtime_inspector import create_debug_agent, RuntimeInspector
47
+ return {"create_debug_agent": create_debug_agent, "RuntimeInspector": RuntimeInspector}[name]
48
+ elif name in ("explain_tool_choice", "RuntimeContext"):
49
+ from .debug_explainer import explain_tool_choice, RuntimeContext
50
+ return {"explain_tool_choice": explain_tool_choice, "RuntimeContext": RuntimeContext}[name]
51
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
@@ -13,25 +13,25 @@ LLM-Note:
13
13
  """
14
14
 
15
15
  from typing import Any, Dict, Optional, List
16
- from .debugger_ui import DebuggerUI, BreakpointContext, BreakpointAction
16
+ from .auto_debug_ui import AutoDebugUI, BreakpointContext, BreakpointAction
17
17
 
18
18
 
19
- class InteractiveDebugger:
19
+ class AutoDebugger:
20
20
  """Orchestrates debugging sessions for AI agents.
21
21
 
22
22
  This class handles the debugging logic and intercepts tool execution,
23
23
  delegating all UI interactions to the DebuggerUI class.
24
24
  """
25
25
 
26
- def __init__(self, agent: Any, ui: Optional[DebuggerUI] = None):
26
+ def __init__(self, agent: Any, ui: Optional[AutoDebugUI] = None):
27
27
  """Initialize debugger with an agent instance and optional UI.
28
28
 
29
29
  Args:
30
30
  agent: The Agent instance to debug
31
- ui: Optional DebuggerUI instance (creates default if None)
31
+ ui: Optional AutoDebugUI instance (creates default if None)
32
32
  """
33
33
  self.agent = agent
34
- self.ui = ui or DebuggerUI()
34
+ self.ui = ui or AutoDebugUI()
35
35
  self.original_execute_single_tool = None
36
36
 
37
37
  def start_debug_session(self, prompt: Optional[str] = None):
@@ -99,7 +99,7 @@ class InteractiveDebugger:
99
99
  - Pause execution and show UI if breakpoint conditions are met
100
100
  - Only affect this specific agent instance
101
101
  """
102
- from . import tool_executor
102
+ from ..core import tool_executor
103
103
  from .xray import is_xray_enabled
104
104
 
105
105
  # Store original function for restoration later
@@ -141,7 +141,7 @@ class InteractiveDebugger:
141
141
  tool execution function.
142
142
  """
143
143
  if self.original_execute_single_tool:
144
- from . import tool_executor
144
+ from ..core import tool_executor
145
145
  tool_executor.execute_single_tool = self.original_execute_single_tool
146
146
 
147
147
  def _show_breakpoint_ui_and_wait_for_continue(self, tool_name: str, tool_args: Dict, trace_entry: Dict):
@@ -57,7 +57,7 @@ def auto_debug_exception(model: str = "o4-mini"):
57
57
  original_hook(exc_type, exc_value, exception_traceback)
58
58
 
59
59
  # Then add our AI analysis
60
- from .console import Console
60
+ from ..console import Console
61
61
  console = Console()
62
62
 
63
63
  # Find the most relevant frame (last user code, not library)
@@ -125,7 +125,7 @@ def auto_debug_exception(model: str = "o4-mini"):
125
125
 
126
126
  try:
127
127
  # Use debug agent with runtime inspection tools
128
- from .debug_agent import create_debug_agent
128
+ from .runtime_inspector import create_debug_agent
129
129
 
130
130
  # Pass the actual frame and traceback for runtime inspection!
131
131
  agent = create_debug_agent(
@@ -176,6 +176,6 @@ You have LIVE ACCESS to the crashed program's state! Use your tools to investiga
176
176
  sys.excepthook = handle_exception
177
177
 
178
178
  # Simple confirmation
179
- from .console import Console
179
+ from ..console import Console
180
180
  console = Console()
181
181
  console.print(f"[green]✅ Exception debugging enabled[/green] - AI will analyze uncaught exceptions with runtime inspection")
@@ -51,7 +51,7 @@ class BreakpointContext:
51
51
  tool_function: Optional[Any] = None # The actual tool function for source inspection
52
52
 
53
53
 
54
- class DebuggerUI:
54
+ class AutoDebugUI:
55
55
  """Handles all user interaction and display for the debugger."""
56
56
 
57
57
  def __init__(self):
@@ -31,7 +31,7 @@ def explain_tool_choice(
31
31
  Returns:
32
32
  Explanation string from the AI agent
33
33
  """
34
- from ..agent import Agent
34
+ from ...core.agent import Agent
35
35
  import inspect
36
36
 
37
37
  # Get all the information we need
@@ -12,7 +12,7 @@ LLM-Note:
12
12
  from typing import Dict, List, Any
13
13
  from pathlib import Path
14
14
  from pydantic import BaseModel
15
- from ..llm_do import llm_do
15
+ from ...llm_do import llm_do
16
16
 
17
17
 
18
18
  class RootCauseAnalysis(BaseModel):
@@ -16,7 +16,7 @@ Analyzes the entire execution trace and provides suggestions for improvement.
16
16
  from pathlib import Path
17
17
  from pydantic import BaseModel
18
18
  from typing import List
19
- from ..llm_do import llm_do
19
+ from ...llm_do import llm_do
20
20
 
21
21
 
22
22
  class ExecutionAnalysis(BaseModel):
@@ -0,0 +1,13 @@
1
+ """Runtime inspector for AI-powered crash debugging.
2
+
3
+ Provides RuntimeInspector class and factory function to create debug agents
4
+ that can experiment, test, and validate fixes using actual crashed program data.
5
+ """
6
+
7
+ from .agent import create_debug_agent
8
+ from .runtime_inspector import RuntimeInspector
9
+
10
+ __all__ = [
11
+ "create_debug_agent",
12
+ "RuntimeInspector"
13
+ ]
@@ -10,7 +10,7 @@ LLM-Note:
10
10
  """
11
11
 
12
12
  from pathlib import Path
13
- from ..agent import Agent
13
+ from ...core.agent import Agent
14
14
  from .runtime_inspector import RuntimeInspector
15
15
 
16
16
 
@@ -14,7 +14,7 @@ This module provides the @xray decorator and xray context for debugging AI agent
14
14
  See everything your agent is thinking during tool execution.
15
15
 
16
16
  Usage:
17
- from connectonion.xray import xray
17
+ from connectonion import xray # or: from connectonion.debug import xray
18
18
 
19
19
  @xray
20
20
  def my_tool(query: str):
connectonion/llm_do.py CHANGED
@@ -222,7 +222,7 @@ from typing import Union, Type, Optional, TypeVar
222
222
  from pathlib import Path
223
223
  from pydantic import BaseModel
224
224
  from .prompts import load_system_prompt
225
- from .llm import create_llm
225
+ from .core.llm import create_llm
226
226
 
227
227
  T = TypeVar('T', bound=BaseModel)
228
228