connectonion 0.5.8__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 (113) hide show
  1. connectonion/__init__.py +78 -0
  2. connectonion/address.py +320 -0
  3. connectonion/agent.py +450 -0
  4. connectonion/announce.py +84 -0
  5. connectonion/asgi.py +287 -0
  6. connectonion/auto_debug_exception.py +181 -0
  7. connectonion/cli/__init__.py +3 -0
  8. connectonion/cli/browser_agent/__init__.py +5 -0
  9. connectonion/cli/browser_agent/browser.py +243 -0
  10. connectonion/cli/browser_agent/prompt.md +107 -0
  11. connectonion/cli/commands/__init__.py +1 -0
  12. connectonion/cli/commands/auth_commands.py +527 -0
  13. connectonion/cli/commands/browser_commands.py +27 -0
  14. connectonion/cli/commands/create.py +511 -0
  15. connectonion/cli/commands/deploy_commands.py +220 -0
  16. connectonion/cli/commands/doctor_commands.py +173 -0
  17. connectonion/cli/commands/init.py +469 -0
  18. connectonion/cli/commands/project_cmd_lib.py +828 -0
  19. connectonion/cli/commands/reset_commands.py +149 -0
  20. connectonion/cli/commands/status_commands.py +168 -0
  21. connectonion/cli/docs/co-vibecoding-principles-docs-contexts-all-in-one.md +2010 -0
  22. connectonion/cli/docs/connectonion.md +1256 -0
  23. connectonion/cli/docs.md +123 -0
  24. connectonion/cli/main.py +148 -0
  25. connectonion/cli/templates/meta-agent/README.md +287 -0
  26. connectonion/cli/templates/meta-agent/agent.py +196 -0
  27. connectonion/cli/templates/meta-agent/prompts/answer_prompt.md +9 -0
  28. connectonion/cli/templates/meta-agent/prompts/docs_retrieve_prompt.md +15 -0
  29. connectonion/cli/templates/meta-agent/prompts/metagent.md +71 -0
  30. connectonion/cli/templates/meta-agent/prompts/think_prompt.md +18 -0
  31. connectonion/cli/templates/minimal/README.md +56 -0
  32. connectonion/cli/templates/minimal/agent.py +40 -0
  33. connectonion/cli/templates/playwright/README.md +118 -0
  34. connectonion/cli/templates/playwright/agent.py +336 -0
  35. connectonion/cli/templates/playwright/prompt.md +102 -0
  36. connectonion/cli/templates/playwright/requirements.txt +3 -0
  37. connectonion/cli/templates/web-research/agent.py +122 -0
  38. connectonion/connect.py +128 -0
  39. connectonion/console.py +539 -0
  40. connectonion/debug_agent/__init__.py +13 -0
  41. connectonion/debug_agent/agent.py +45 -0
  42. connectonion/debug_agent/prompts/debug_assistant.md +72 -0
  43. connectonion/debug_agent/runtime_inspector.py +406 -0
  44. connectonion/debug_explainer/__init__.py +10 -0
  45. connectonion/debug_explainer/explain_agent.py +114 -0
  46. connectonion/debug_explainer/explain_context.py +263 -0
  47. connectonion/debug_explainer/explainer_prompt.md +29 -0
  48. connectonion/debug_explainer/root_cause_analysis_prompt.md +43 -0
  49. connectonion/debugger_ui.py +1039 -0
  50. connectonion/decorators.py +208 -0
  51. connectonion/events.py +248 -0
  52. connectonion/execution_analyzer/__init__.py +9 -0
  53. connectonion/execution_analyzer/execution_analysis.py +93 -0
  54. connectonion/execution_analyzer/execution_analysis_prompt.md +47 -0
  55. connectonion/host.py +579 -0
  56. connectonion/interactive_debugger.py +342 -0
  57. connectonion/llm.py +801 -0
  58. connectonion/llm_do.py +307 -0
  59. connectonion/logger.py +300 -0
  60. connectonion/prompt_files/__init__.py +1 -0
  61. connectonion/prompt_files/analyze_contact.md +62 -0
  62. connectonion/prompt_files/eval_expected.md +12 -0
  63. connectonion/prompt_files/react_evaluate.md +11 -0
  64. connectonion/prompt_files/react_plan.md +16 -0
  65. connectonion/prompt_files/reflect.md +22 -0
  66. connectonion/prompts.py +144 -0
  67. connectonion/relay.py +200 -0
  68. connectonion/static/docs.html +688 -0
  69. connectonion/tool_executor.py +279 -0
  70. connectonion/tool_factory.py +186 -0
  71. connectonion/tool_registry.py +105 -0
  72. connectonion/trust.py +166 -0
  73. connectonion/trust_agents.py +71 -0
  74. connectonion/trust_functions.py +88 -0
  75. connectonion/tui/__init__.py +57 -0
  76. connectonion/tui/divider.py +39 -0
  77. connectonion/tui/dropdown.py +251 -0
  78. connectonion/tui/footer.py +31 -0
  79. connectonion/tui/fuzzy.py +56 -0
  80. connectonion/tui/input.py +278 -0
  81. connectonion/tui/keys.py +35 -0
  82. connectonion/tui/pick.py +130 -0
  83. connectonion/tui/providers.py +155 -0
  84. connectonion/tui/status_bar.py +163 -0
  85. connectonion/usage.py +161 -0
  86. connectonion/useful_events_handlers/__init__.py +16 -0
  87. connectonion/useful_events_handlers/reflect.py +116 -0
  88. connectonion/useful_plugins/__init__.py +20 -0
  89. connectonion/useful_plugins/calendar_plugin.py +163 -0
  90. connectonion/useful_plugins/eval.py +139 -0
  91. connectonion/useful_plugins/gmail_plugin.py +162 -0
  92. connectonion/useful_plugins/image_result_formatter.py +127 -0
  93. connectonion/useful_plugins/re_act.py +78 -0
  94. connectonion/useful_plugins/shell_approval.py +159 -0
  95. connectonion/useful_tools/__init__.py +44 -0
  96. connectonion/useful_tools/diff_writer.py +192 -0
  97. connectonion/useful_tools/get_emails.py +183 -0
  98. connectonion/useful_tools/gmail.py +1596 -0
  99. connectonion/useful_tools/google_calendar.py +613 -0
  100. connectonion/useful_tools/memory.py +380 -0
  101. connectonion/useful_tools/microsoft_calendar.py +604 -0
  102. connectonion/useful_tools/outlook.py +488 -0
  103. connectonion/useful_tools/send_email.py +205 -0
  104. connectonion/useful_tools/shell.py +97 -0
  105. connectonion/useful_tools/slash_command.py +201 -0
  106. connectonion/useful_tools/terminal.py +285 -0
  107. connectonion/useful_tools/todo_list.py +241 -0
  108. connectonion/useful_tools/web_fetch.py +216 -0
  109. connectonion/xray.py +467 -0
  110. connectonion-0.5.8.dist-info/METADATA +741 -0
  111. connectonion-0.5.8.dist-info/RECORD +113 -0
  112. connectonion-0.5.8.dist-info/WHEEL +4 -0
  113. connectonion-0.5.8.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,1256 @@
1
+ # ConnectOnion Framework - Complete Reference for AI Assistants
2
+
3
+ ## Context for AI Assistants
4
+
5
+ You are helping a developer who wants to use ConnectOnion, a Python framework for creating AI agents with behavior tracking. This document contains everything you need to help them write effective ConnectOnion code.
6
+
7
+ **Key Principles:**
8
+ - Keep simple things simple, make hard things possible
9
+ - Function-based tools are preferred over classes
10
+ - Activity logging to .co/logs/ (Python SDK only)
11
+ - Default settings work for most use cases
12
+
13
+ ---
14
+
15
+ ## What is ConnectOnion?
16
+
17
+ ConnectOnion is a simple Python framework for creating AI agents that can use tools and track their behavior. Think of it as a way to build ChatGPT-like agents with custom tools.
18
+
19
+ **Core Features:**
20
+ - Turn regular Python functions into agent tools automatically
21
+ - Control agent behavior with max_iterations parameter
22
+ - Automatic behavior tracking and history
23
+ - System prompts for agent personality
24
+ - Built-in OpenAI integration
25
+ - Debugging with @xray decorator
26
+
27
+ ---
28
+
29
+ ## Installation & Setup
30
+
31
+ ```bash
32
+ pip install connectonion
33
+ ```
34
+
35
+ **Environment Setup:**
36
+ ```bash
37
+ export OPENAI_API_KEY="your-api-key-here"
38
+ # Or use .env file
39
+ ```
40
+
41
+ ---
42
+
43
+ ## CLI Reference - Quick Project Setup
44
+
45
+ ConnectOnion includes a CLI for quickly scaffolding agent projects.
46
+
47
+ ### Installation
48
+ The CLI is automatically installed with ConnectOnion:
49
+ ```bash
50
+ pip install connectonion
51
+ # Provides two commands: 'co' and 'connectonion'
52
+ ```
53
+
54
+ ### Initialize a Project
55
+
56
+ ```bash
57
+ # Create meta-agent (default) - ConnectOnion development assistant
58
+ mkdir meta-agent
59
+ cd meta-agent
60
+ co init
61
+
62
+ # Create web automation agent
63
+ mkdir playwright-agent
64
+ cd playwright-agent
65
+ co init --template playwright
66
+ ```
67
+
68
+ ### CLI Options
69
+
70
+ - `co init` - Initialize a new agent project
71
+ - `--template, -t` - Choose template: `meta-agent` (default), `playwright`
72
+ - `--force` - Overwrite existing files
73
+
74
+ ### What Gets Created
75
+
76
+ ```
77
+ my-project/
78
+ ├── agent.py # Main agent implementation
79
+ ├── prompt.md # System prompt (markdown)
80
+ ├── .env.example # Environment variables template
81
+ ├── .co/ # ConnectOnion metadata
82
+ │ ├── config.toml # Project configuration
83
+ │ └── docs/
84
+ │ └── connectonion.md # Embedded framework documentation
85
+ └── .gitignore # Git ignore rules (if in git repo)
86
+ ```
87
+
88
+ ### Available Templates
89
+
90
+ **Meta-Agent (Default)** - ConnectOnion development assistant with built-in tools:
91
+ - `answer_connectonion_question()` - Expert answers from embedded docs
92
+ - `create_agent_from_template()` - Generate complete agent code
93
+ - `generate_tool_code()` - Create tool functions
94
+ - `create_test_for_agent()` - Generate pytest test suites
95
+ - `think()` - Self-reflection to analyze task completion
96
+ - `generate_todo_list()` - Create structured plans (uses GPT-4o-mini)
97
+ - `suggest_project_structure()` - Architecture recommendations
98
+
99
+ **Playwright Template** - Web automation with stateful browser control:
100
+ - `start_browser()` - Launch browser instance
101
+ - `navigate()` - Go to URLs
102
+ - `scrape_content()` - Extract page content
103
+ - `fill_form()` - Fill and submit forms
104
+ - `take_screenshot()` - Capture pages
105
+ - `extract_links()` - Get all links
106
+ - `execute_javascript()` - Run JS code
107
+ - `close_browser()` - Clean up resources
108
+
109
+ Note: Playwright template requires `pip install playwright && playwright install`
110
+
111
+ ### Interactive Features
112
+
113
+ The CLI will:
114
+ - Warn if you're in a special directory (home, root, system)
115
+ - Ask for confirmation if the directory is not empty
116
+ - Automatically detect git repositories and update `.gitignore`
117
+ - Provide clear next steps after initialization
118
+
119
+ ### Quick Start After Init
120
+
121
+ ```bash
122
+ # 1. Copy environment template
123
+ cp .env.example .env
124
+
125
+ # 2. Add your OpenAI API key to .env
126
+ echo "OPENAI_API_KEY=sk-your-key-here" > .env
127
+
128
+ # 3. Run your agent
129
+ python agent.py
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Quick Start Template
135
+
136
+ ```python
137
+ from connectonion import Agent
138
+
139
+ # 1. Define tools as regular functions
140
+ def search(query: str) -> str:
141
+ """Search for information."""
142
+ return f"Found information about {query}"
143
+
144
+ def calculate(expression: str) -> float:
145
+ """Perform mathematical calculations."""
146
+ return eval(expression) # Use safely in production
147
+
148
+ # 2. Create agent
149
+ agent = Agent(
150
+ name="my_assistant",
151
+ system_prompt="You are a helpful assistant.",
152
+ tools=[search, calculate]
153
+ # max_iterations=10 (default)
154
+ )
155
+
156
+ # 3. Use agent
157
+ result = agent.input("What is 25 * 4?")
158
+ print(result)
159
+ ```
160
+
161
+ **Example output (will vary):**
162
+
163
+ ```
164
+ 100
165
+ ```
166
+
167
+ ---
168
+
169
+ ## How ConnectOnion Works - The Agent Loop
170
+
171
+ ### Input → Processing → Output Flow
172
+
173
+ ```python
174
+ # 1. User provides input
175
+ result = agent.input("Search for Python tutorials and summarize them")
176
+
177
+ # 2. Agent processes in iterations:
178
+ # Iteration 1: LLM decides → "I need to search first"
179
+ # → Calls search("Python tutorials")
180
+ # → Gets result: "Found 10 tutorials about Python"
181
+
182
+ # Iteration 2: LLM continues → "Now I need to summarize"
183
+ # → Calls summarize("Found 10 tutorials...")
184
+ # → Gets result: "Summary: Python tutorials cover..."
185
+
186
+ # Iteration 3: LLM concludes → "Task complete"
187
+ # → Returns final answer (no more tool calls)
188
+
189
+ # 3. User gets final result
190
+ print(result) # "Here's a summary of Python tutorials: ..."
191
+ ```
192
+
193
+ ### The Agent Execution Loop
194
+
195
+ Each `agent.input()` call follows this pattern:
196
+
197
+ 1. **Setup**: Agent receives user prompt + system prompt
198
+ 2. **Loop** (up to `max_iterations` times):
199
+ - Send current conversation to LLM
200
+ - If LLM returns tool calls → execute them → add results to conversation
201
+ - If LLM returns text only → task complete, exit loop
202
+ 3. **Return**: Final LLM response to user
203
+
204
+ ### Message Flow Example
205
+
206
+ ```python
207
+ # Internal conversation that builds up:
208
+
209
+ # Initial messages
210
+ [
211
+ {"role": "system", "content": "You are a helpful assistant..."},
212
+ {"role": "user", "content": "Search for Python tutorials and summarize"}
213
+ ]
214
+
215
+ # After iteration 1 (LLM called search tool)
216
+ [
217
+ {"role": "system", "content": "You are a helpful assistant..."},
218
+ {"role": "user", "content": "Search for Python tutorials and summarize"},
219
+ {"role": "assistant", "tool_calls": [{"name": "search", "arguments": {"query": "Python tutorials"}}]},
220
+ {"role": "tool", "content": "Found 10 tutorials about Python basics...", "tool_call_id": "call_1"}
221
+ ]
222
+
223
+ # After iteration 2 (LLM called summarize tool)
224
+ [
225
+ # ... previous messages ...
226
+ {"role": "assistant", "tool_calls": [{"name": "summarize", "arguments": {"text": "Found 10 tutorials..."}}]},
227
+ {"role": "tool", "content": "Summary: Python tutorials cover variables, functions...", "tool_call_id": "call_2"}
228
+ ]
229
+
230
+ # Final iteration (LLM provides answer)
231
+ [
232
+ # ... previous messages ...
233
+ {"role": "assistant", "content": "Here's a summary of Python tutorials: They cover..."}
234
+ ]
235
+ ```
236
+
237
+ ### Input/Output Types
238
+
239
+ **Input to `agent.input()`:**
240
+ - `prompt` (str): User's request/question
241
+ - `max_iterations` (optional int): Override iteration limit for this request
242
+
243
+ **Output from `agent.input()`:**
244
+ - String: Final LLM response to user
245
+ - If max iterations reached: `"Task incomplete: Maximum iterations (N) reached."`
246
+
247
+ **Tool Function Signatures:**
248
+ ```python
249
+ # Tools always follow this pattern:
250
+ def tool_name(param1: type, param2: type = default) -> return_type:
251
+ """Description for LLM."""
252
+ # Your logic here
253
+ return result # Must match return_type
254
+ ```
255
+
256
+ ### Automatic Behavior Tracking
257
+
258
+ Every `agent.input()` call creates a record:
259
+
260
+ ```python
261
+ # Automatic tracking in ~/.connectonion/agents/{name}/behavior.json
262
+ {
263
+ "timestamp": "2024-01-15T10:30:00",
264
+ "user_prompt": "Search for Python tutorials and summarize",
265
+ "tool_calls": [
266
+ {
267
+ "name": "search",
268
+ "arguments": {"query": "Python tutorials"},
269
+ "result": "Found 10 tutorials...",
270
+ "status": "success",
271
+ "timing": 245.3 # milliseconds
272
+ },
273
+ {
274
+ "name": "summarize",
275
+ "arguments": {"text": "Found 10 tutorials..."},
276
+ "result": "Summary: Python tutorials...",
277
+ "status": "success",
278
+ "timing": 156.7
279
+ }
280
+ ],
281
+ "result": "Here's a summary of Python tutorials...",
282
+ "duration": 2.34 # total seconds
283
+ }
284
+
285
+ # Access history
286
+ print(agent.history.summary()) # Human-readable summary
287
+ print(len(agent.history.records)) # Number of tasks completed
288
+ ```
289
+
290
+ ---
291
+
292
+ ## Core API Reference
293
+
294
+ ### Agent Class
295
+
296
+ ```python
297
+ class Agent:
298
+ def __init__(
299
+ self,
300
+ name: str,
301
+ llm: Optional[LLM] = None,
302
+ tools: Optional[List[Callable]] = None,
303
+ system_prompt: Union[str, Path, None] = None,
304
+ api_key: Optional[str] = None,
305
+ model: str = "gpt-4-mini",
306
+ max_iterations: int = 10
307
+ )
308
+
309
+ def input(self, prompt: str, max_iterations: Optional[int] = None) -> str:
310
+ """Send input to agent and get response."""
311
+
312
+ def add_tool(self, tool: Callable):
313
+ """Add a new tool to the agent."""
314
+
315
+ def remove_tool(self, tool_name: str) -> bool:
316
+ """Remove a tool by name."""
317
+
318
+ def list_tools(self) -> List[str]:
319
+ """List all available tool names."""
320
+ ```
321
+
322
+ ### Key Parameters Explained
323
+
324
+ **max_iterations** (Default: 10):
325
+ - Controls how many tool calls the agent can make per task
326
+ - Simple tasks: 3-5 iterations
327
+ - Standard workflows: 10-15 iterations
328
+ - Complex analysis: 20-40 iterations
329
+ - Research projects: 30-50 iterations
330
+
331
+ **system_prompt** (Recommended: Use markdown files):
332
+ - **Path/str: Load from file (RECOMMENDED)** - Keep prompts separate from code
333
+ - String: Direct prompt text (only for very simple cases)
334
+ - None: Uses default helpful assistant prompt
335
+
336
+ ---
337
+
338
+ ## Function-Based Tools (Recommended Approach)
339
+
340
+ ### Basic Tool Creation
341
+
342
+ ```python
343
+ def my_tool(param: str, optional_param: int = 10) -> str:
344
+ """This docstring becomes the tool description."""
345
+ return f"Processed {param} with value {optional_param}"
346
+
347
+ # Automatic conversion - just pass the function!
348
+ agent = Agent("assistant", tools=[my_tool])
349
+ ```
350
+
351
+ ### Tool Guidelines
352
+
353
+ **Type Hints are Required:**
354
+ ```python
355
+ # Good - clear types
356
+ def search(query: str, limit: int = 10) -> str:
357
+ return f"Found {limit} results for {query}"
358
+
359
+ # Bad - no type hints
360
+ def search(query, limit=10):
361
+ return f"Found {limit} results for {query}"
362
+ ```
363
+
364
+ **Docstrings Become Descriptions:**
365
+ ```python
366
+ def analyze_data(data: str, method: str = "standard") -> str:
367
+ """Analyze data using specified method.
368
+
369
+ Methods: standard, detailed, quick
370
+ """
371
+ return f"Analysis complete using {method} method"
372
+ ```
373
+
374
+ ### Tool Descriptions and Schemas (What the LLM Sees)
375
+
376
+ The first line of a tool's docstring is used as the human‑readable description. ConnectOnion also builds a JSON schema from the function signature and type hints.
377
+
378
+ ```python
379
+ from typing import Literal, Annotated
380
+
381
+ Priority = Literal["low", "normal", "high"]
382
+
383
+ def create_ticket(
384
+ title: str,
385
+ description: str,
386
+ priority: Priority = "normal",
387
+ assignee: Annotated[str, "email"] | None = None,
388
+ ) -> str:
389
+ """Create a ticket and return its ID."""
390
+ return "T-1024"
391
+
392
+ # Internally, the agent exposes a schema like this to the LLM:
393
+ schema = {
394
+ "name": "create_ticket",
395
+ "description": "Create a ticket and return its ID.",
396
+ "parameters": {
397
+ "type": "object",
398
+ "properties": {
399
+ "title": {"type": "string"},
400
+ "description": {"type": "string"},
401
+ "priority": {"enum": ["low", "normal", "high"]},
402
+ "assignee": {"type": "string"}
403
+ },
404
+ "required": ["title", "description"]
405
+ }
406
+ }
407
+ ```
408
+
409
+ Best practices for descriptions:
410
+
411
+ - Start with a concise, imperative one‑liner: “Create…”, “Search…”, “Summarize…”.
412
+ - Mention key constraints and side effects (“Sends network request”, “Writes to disk”).
413
+ - Clarify required vs optional parameters and valid ranges/enums.
414
+ - Prefer deterministic behavior; if not, state what is non‑deterministic.
415
+ - Keep the first line under ~90 characters; add additional details on following lines.
416
+
417
+ ---
418
+
419
+ ## Stateful Tools with Playwright (Shared Context via Classes)
420
+
421
+ **✅ RECOMMENDED: Pass the class instance directly to ConnectOnion!**
422
+
423
+ ConnectOnion automatically discovers all public methods with type hints when you pass a class instance. This is much cleaner than listing methods individually.
424
+
425
+ Use a class instance when tools need to share state (browser, cache, DB handles). You can also mix class methods with regular function tools.
426
+
427
+ Prerequisites:
428
+
429
+ ```bash
430
+ pip install playwright
431
+ playwright install
432
+ ```
433
+
434
+ ```python
435
+ from connectonion import Agent
436
+
437
+ try:
438
+ from playwright.sync_api import sync_playwright
439
+ except ImportError:
440
+ raise SystemExit("Install Playwright: pip install playwright && playwright install")
441
+
442
+
443
+ class BrowserAutomation:
444
+ """Real browser session with shared context across tool calls."""
445
+
446
+ def __init__(self):
447
+ self._p = None
448
+ self._browser = None
449
+ self._page = None
450
+ self._screenshots: list[str] = []
451
+
452
+ def start_browser(self, headless: bool = True) -> str:
453
+ """Start a Chromium browser session."""
454
+ self._p = sync_playwright().start()
455
+ self._browser = self._p.chromium.launch(headless=headless)
456
+ self._page = self._browser.new_page()
457
+ return f"Browser started (headless={headless})"
458
+
459
+ def goto(self, url: str) -> str:
460
+ """Navigate to a URL and return the page title."""
461
+ if not self._page:
462
+ return "Error: Browser not started"
463
+ self._page.goto(url)
464
+ return self._page.title()
465
+
466
+ def screenshot(self, filename: str = "page.png") -> str:
467
+ """Save a screenshot and return the filename."""
468
+ if not self._page:
469
+ return "Error: Browser not started"
470
+ self._page.screenshot(path=filename)
471
+ self._screenshots.append(filename)
472
+ return filename
473
+
474
+ def close(self) -> str:
475
+ """Close resources and end the session."""
476
+ try:
477
+ if self._page:
478
+ self._page.close()
479
+ if self._browser:
480
+ self._browser.close()
481
+ if self._p:
482
+ self._p.stop()
483
+ return "Browser closed"
484
+ finally:
485
+ self._page = None
486
+ self._browser = None
487
+ self._p = None
488
+
489
+
490
+ def format_title(title: str) -> str:
491
+ """Format a page title for logs or UIs."""
492
+ return f"[PAGE] {title}"
493
+
494
+
495
+ # Mix class instance (stateful tools) and regular functions
496
+ browser = BrowserAutomation()
497
+ agent = Agent(
498
+ name="web_assistant",
499
+ tools=[browser, format_title],
500
+ system_prompt="You are a web automation assistant. Be explicit about each step."
501
+ )
502
+
503
+ # Manual session (no LLM) — call tools directly
504
+ print(agent.tools.start_browser.run(headless=True))
505
+ title = agent.tools.goto.run("https://example.com")
506
+ print(agent.tools.format_title.run(title=title))
507
+ print(agent.tools.screenshot.run(filename="example.png"))
508
+ print(agent.tools.close.run())
509
+ ```
510
+
511
+ **Example output:**
512
+
513
+ ```
514
+ Browser started (headless=True)
515
+ [PAGE] Example Domain
516
+ example.png
517
+ Browser closed
518
+ ```
519
+
520
+ Agent‑driven session (LLM decides which tools to call):
521
+
522
+ ```python
523
+ # Natural language instruction — the agent chooses and orders tool calls
524
+ result = agent.input(
525
+ """
526
+ Open https://example.com, return the page title, take a screenshot named
527
+ example.png, then close the browser.
528
+ """
529
+ )
530
+ print(result)
531
+ ```
532
+
533
+ **Example output (simplified):**
534
+
535
+ ```
536
+ Title: Example Domain
537
+ Screenshot saved: example.png
538
+ Browser session closed.
539
+ ```
540
+
541
+ Why this pattern works:
542
+
543
+ - Class instance keeps shared state (browser/page) across calls.
544
+ - Function tools are great for lightweight utilities (formatting, parsing, saving records).
545
+ - The agent exposes both as callable tools with proper schemas and docstring descriptions.
546
+
547
+ ---
548
+
549
+ ## max_iterations Control
550
+
551
+ ### Basic Usage
552
+
553
+ ```python
554
+ # Default: 10 iterations (good for most tasks)
555
+ agent = Agent("helper", tools=[...])
556
+
557
+ # Simple tasks - fewer iterations
558
+ calc_agent = Agent("calculator", tools=[calculate], max_iterations=5)
559
+
560
+ # Complex tasks - more iterations
561
+ research_agent = Agent("researcher", tools=[...], max_iterations=25)
562
+ ```
563
+
564
+ ### Per-Request Override
565
+
566
+ ```python
567
+ agent = Agent("flexible", tools=[...])
568
+
569
+ # Normal task
570
+ result = agent.input("Simple question")
571
+
572
+ # Complex task needs more iterations
573
+ result = agent.input(
574
+ "Analyze all data and generate comprehensive report",
575
+ max_iterations=30
576
+ )
577
+ ```
578
+
579
+ ### When You Hit the Limit
580
+
581
+ ```python
582
+ # Error message when limit reached:
583
+ "Task incomplete: Maximum iterations (10) reached."
584
+
585
+ # Solutions:
586
+ # 1. Increase agent's default
587
+ agent.max_iterations = 20
588
+
589
+ # 2. Override for specific task
590
+ result = agent.input("complex task", max_iterations=25)
591
+
592
+ # 3. Break task into smaller parts
593
+ result1 = agent.input("First analyze the data")
594
+ result2 = agent.input(f"Based on {result1}, create summary")
595
+ ```
596
+
597
+ ---
598
+
599
+ ## System Prompts & Personality
600
+
601
+ **Best Practice: Use Markdown Files for System Prompts**
602
+
603
+ Keep your prompts separate from code for better maintainability, version control, and collaboration.
604
+
605
+ ### Recommended: Load from Markdown File
606
+
607
+ ```python
608
+ # ✅ RECOMMENDED: Load from markdown file
609
+ agent = Agent(
610
+ name="support_agent",
611
+ system_prompt="prompts/customer_support.md", # Clean separation
612
+ tools=[...]
613
+ )
614
+
615
+ # Using Path object (also good)
616
+ from pathlib import Path
617
+ agent = Agent(
618
+ name="data_analyst",
619
+ system_prompt=Path("prompts") / "data_analyst.md",
620
+ tools=[...]
621
+ )
622
+
623
+ # Any extension works (.md, .txt, .prompt, etc.)
624
+ agent = Agent(
625
+ name="coder",
626
+ system_prompt="prompts/senior_developer.txt",
627
+ tools=[...]
628
+ )
629
+ ```
630
+
631
+ ### Example Prompt File (`prompts/customer_support.md`)
632
+
633
+ ```markdown
634
+ # Customer Support Agent
635
+
636
+ You are a senior customer support specialist with 10+ years of experience.
637
+
638
+ ## Your Expertise
639
+ - Empathetic communication with frustrated customers
640
+ - Root cause analysis for technical issues
641
+ - Clear, step-by-step problem solving
642
+ - Escalation management
643
+
644
+ ## Guidelines
645
+ 1. **Always acknowledge** the customer's concern first
646
+ 2. **Ask clarifying questions** to understand the real problem
647
+ 3. **Provide actionable solutions** with clear next steps
648
+ 4. **Follow up** to ensure satisfaction
649
+
650
+ ## Tone
651
+ - Professional but warm
652
+ - Patient and understanding
653
+ - Confident in your recommendations
654
+ - Never dismissive of concerns
655
+
656
+ ## Example Responses
657
+ When a customer is frustrated:
658
+ > "I completely understand your frustration with this issue. Let me help you resolve this right away. Can you tell me exactly what happened when you tried to [action]?"
659
+ ```
660
+
661
+ ### Why Markdown Files Are Better
662
+
663
+ **✅ Advantages:**
664
+ - **Version Control**: Track prompt changes over time
665
+ - **Collaboration**: Team members can easily review and edit prompts
666
+ - **Readability**: Markdown formatting makes prompts clear and professional
667
+ - **Reusability**: Share prompts across different agents
668
+ - **No Code Pollution**: Keep business logic separate from implementation
669
+ - **IDE Support**: Syntax highlighting and formatting in markdown files
670
+
671
+ **❌ Avoid Inline Strings:**
672
+ ```python
673
+ # ❌ DON'T DO THIS - Hard to maintain
674
+ agent = Agent(
675
+ name="support",
676
+ system_prompt="You are a customer support agent. Be helpful and friendly. Always ask follow-up questions. Use empathetic language. Provide step-by-step solutions...", # This gets messy!
677
+ tools=[...]
678
+ )
679
+ ```
680
+
681
+ ### Advanced Prompt Organization
682
+
683
+ ```python
684
+ # Organize prompts by role/domain
685
+ prompts/
686
+ ├── customer_support/
687
+ │ ├── tier1_support.md
688
+ │ ├── technical_support.md
689
+ │ └── billing_support.md
690
+ ├── data_analysis/
691
+ │ ├── financial_analyst.md
692
+ │ └── research_analyst.md
693
+ └── development/
694
+ ├── code_reviewer.md
695
+ └── senior_developer.md
696
+
697
+ # Load specific prompts
698
+ support_agent = Agent(
699
+ name="tier1_support",
700
+ system_prompt="prompts/customer_support/tier1_support.md",
701
+ tools=[create_ticket, search_kb, escalate]
702
+ )
703
+
704
+ analyst_agent = Agent(
705
+ name="financial_analyst",
706
+ system_prompt="prompts/data_analysis/financial_analyst.md",
707
+ tools=[fetch_data, analyze_trends, generate_report]
708
+ )
709
+ ```
710
+
711
+ ### Simple Cases Only
712
+
713
+ For very simple, single-line prompts, inline strings are acceptable:
714
+
715
+ ```python
716
+ # ✅ OK for simple cases
717
+ calculator = Agent(
718
+ name="calc",
719
+ system_prompt="You are a helpful calculator. Always show your work step by step.",
720
+ tools=[calculate]
721
+ )
722
+ ```
723
+
724
+ ---
725
+
726
+ ## Debugging with @xray
727
+
728
+ Debug your agent's tool execution with real-time insights - see what your AI agent is thinking.
729
+
730
+ ### Quick Start
731
+
732
+ ```python
733
+ from connectonion.decorators import xray
734
+
735
+ @xray
736
+ def my_tool(text: str) -> str:
737
+ """Process some text."""
738
+
739
+ # Now you can see inside the agent's mind!
740
+ print(xray.agent.name) # "my_assistant"
741
+ print(xray.task) # "Process this document"
742
+ print(xray.iteration) # 1, 2, 3...
743
+
744
+ return f"Processed: {text}"
745
+ ```
746
+
747
+ That's it! Add `@xray` to any tool to unlock debugging superpowers.
748
+
749
+ ### What You Can Access
750
+
751
+ Inside any `@xray` decorated function:
752
+
753
+ ```python
754
+ xray.agent # The Agent instance calling this tool
755
+ xray.task # Original request from user
756
+ xray.messages # Full conversation history
757
+ xray.iteration # Which round of tool calls (1-10)
758
+ xray.previous_tools # Tools called before this one
759
+ ```
760
+
761
+ ### Real Example
762
+
763
+ ```python
764
+ @xray
765
+ def search_database(query: str) -> str:
766
+ """Search our database."""
767
+
768
+ # See what led to this search
769
+ print(f"User asked: {xray.task}")
770
+ print(f"This is iteration {xray.iteration}")
771
+
772
+ if xray.previous_tools:
773
+ print(f"Already tried: {xray.previous_tools}")
774
+
775
+ # Adjust behavior based on context
776
+ if xray.iteration > 2:
777
+ return "No results found, please refine your search"
778
+
779
+ return f"Found 5 results for '{query}'"
780
+ ```
781
+
782
+ ### Visual Execution Trace
783
+
784
+ See the complete flow of your agent's work from inside a tool:
785
+
786
+ ```python
787
+ @xray
788
+ def analyze_data(text: str) -> str:
789
+ """Analyze data and show execution trace."""
790
+
791
+ # Show what happened so far
792
+ xray.trace()
793
+
794
+ return "Analysis complete"
795
+ ```
796
+
797
+ **Output:**
798
+ ```
799
+ Task: "Find Python tutorials and summarize them"
800
+
801
+ [1] • 89ms search_database(query="Python tutorials")
802
+ IN → query: "Python tutorials"
803
+ OUT ← "Found 5 results for 'Python tutorials'"
804
+
805
+ [2] • 234ms summarize_text(text="Found 5 results...", max_words=50)
806
+ IN → text: "Found 5 results for 'Python tutorials'"
807
+ IN → max_words: 50
808
+ OUT ← "5 Python tutorials found covering basics to advanced topics"
809
+
810
+ Total: 323ms • 2 steps • 1 iterations
811
+ ```
812
+
813
+ ### Debug in Your IDE
814
+
815
+ Set a breakpoint and explore:
816
+
817
+ ```python
818
+ @xray
819
+ def analyze_sentiment(text: str) -> str:
820
+ # 🎯 Set breakpoint on next line
821
+ sentiment = "positive" # When stopped here in debugger:
822
+ # >>> xray
823
+ # <XrayContext active>
824
+ # agent: 'my_bot'
825
+ # task: 'How do people feel about Python?'
826
+ # >>> xray.messages
827
+ # [{'role': 'user', 'content': '...'}, ...]
828
+
829
+ return sentiment
830
+ ```
831
+
832
+ ### Practical Use Cases
833
+
834
+ **1. Understand Why a Tool Was Called**
835
+ ```python
836
+ @xray
837
+ def emergency_shutdown():
838
+ """Shutdown the system."""
839
+
840
+ # Check why this drastic action was requested
841
+ print(f"Shutdown requested because: {xray.task}")
842
+ print(f"After trying: {xray.previous_tools}")
843
+
844
+ # Maybe don't shutdown if it's the first try
845
+ if xray.iteration == 1:
846
+ return "Try restarting first"
847
+
848
+ return "System shutdown complete"
849
+ ```
850
+
851
+ **2. Adaptive Tool Behavior**
852
+ ```python
853
+ @xray
854
+ def fetch_data(source: str) -> str:
855
+ """Fetch data from a source."""
856
+
857
+ # Use cache on repeated calls
858
+ if "fetch_data" in xray.previous_tools:
859
+ return "Using cached data"
860
+
861
+ # Fresh fetch on first call
862
+ return f"Fresh data from {source}"
863
+ ```
864
+
865
+ **3. Debug Complex Flows**
866
+ ```python
867
+ @xray
868
+ def process_order(order_id: str) -> str:
869
+ """Process an order."""
870
+
871
+ # See the full context when debugging
872
+ if xray.agent:
873
+ print(f"Processing for agent: {xray.agent.name}")
874
+ print(f"Original request: {xray.task}")
875
+ print(f"Conversation length: {len(xray.messages)}")
876
+
877
+ return f"Order {order_id} processed"
878
+ ```
879
+
880
+ ### Tips
881
+
882
+ 1. **Development Only** - Remove @xray in production for best performance
883
+ 2. **Combine with IDE** - Set breakpoints for interactive debugging
884
+ 3. **Use trace()** - Call `xray.trace()` to see full execution flow
885
+ 4. **Check context** - Always verify `xray.agent` exists before using
886
+
887
+ ### Common Patterns
888
+
889
+ **Logging What Matters:**
890
+ ```python
891
+ @xray
892
+ def important_action(data: str) -> str:
893
+ # Log with context
894
+ if xray.agent:
895
+ logger.info(f"Agent {xray.agent.name} performing action")
896
+ logger.info(f"Original task: {xray.task}")
897
+ logger.info(f"Iteration: {xray.iteration}")
898
+
899
+ return "Action completed"
900
+ ```
901
+
902
+ **Conditional Logic:**
903
+ ```python
904
+ @xray
905
+ def smart_search(query: str) -> str:
906
+ # Different strategies based on context
907
+ if xray.iteration > 1:
908
+ # Broaden search on retry
909
+ query = f"{query} OR related"
910
+
911
+ if "analyze" in xray.previous_tools:
912
+ # We already analyzed, search differently
913
+ query = f"summary of {query}"
914
+
915
+ return f"Results for: {query}"
916
+ ```
917
+
918
+ ---
919
+
920
+ ## Common Patterns & Examples
921
+
922
+ ### Pattern 1: Simple Calculator Bot
923
+
924
+ ```python
925
+ def calculate(expression: str) -> float:
926
+ """Perform mathematical calculations."""
927
+ try:
928
+ # Safe eval for demo - use proper parsing in production
929
+ allowed = "0123456789+-*/(). "
930
+ if all(c in allowed for c in expression):
931
+ return eval(expression)
932
+ else:
933
+ raise ValueError("Invalid characters")
934
+ except Exception as e:
935
+ raise ValueError(f"Calculation error: {e}")
936
+
937
+ calc_agent = Agent(
938
+ name="calculator",
939
+ system_prompt="You are a helpful calculator. Always show your work.",
940
+ tools=[calculate],
941
+ max_iterations=5 # Math rarely needs many iterations
942
+ )
943
+
944
+ result = calc_agent.input("What is (25 + 15) * 3?")
945
+ ```
946
+
947
+ ### Pattern 2: Research Assistant
948
+
949
+ ```python
950
+ def web_search(query: str, num_results: int = 5) -> str:
951
+ """Search the web for information."""
952
+ # Your search implementation
953
+ return f"Found {num_results} results for '{query}'"
954
+
955
+ def summarize(text: str, length: str = "medium") -> str:
956
+ """Summarize text content."""
957
+ # Your summarization implementation
958
+ return f"Summary ({length}): {text[:100]}..."
959
+
960
+ def save_notes(content: str, filename: str = "research.txt") -> str:
961
+ """Save content to a file."""
962
+ # Your file saving implementation
963
+ return f"Saved content to {filename}"
964
+
965
+ research_agent = Agent(
966
+ name="researcher",
967
+ system_prompt="You are a thorough researcher who provides well-sourced information.",
968
+ tools=[web_search, summarize, save_notes],
969
+ max_iterations=25 # Research involves many steps
970
+ )
971
+
972
+ result = research_agent.input(
973
+ "Research the latest developments in quantum computing and save a summary"
974
+ )
975
+ ```
976
+
977
+ ### Pattern 3: File Analyzer
978
+
979
+ ```python
980
+ def read_file(filepath: str) -> str:
981
+ """Read contents of a text file."""
982
+ try:
983
+ with open(filepath, 'r', encoding='utf-8') as f:
984
+ return f.read()
985
+ except FileNotFoundError:
986
+ return f"Error: File {filepath} not found"
987
+ except Exception as e:
988
+ return f"Error reading file: {e}"
989
+
990
+ def analyze_text(text: str, analysis_type: str = "summary") -> str:
991
+ """Analyze text content."""
992
+ if analysis_type == "summary":
993
+ return f"Text summary: {len(text)} characters, {len(text.split())} words"
994
+ elif analysis_type == "sentiment":
995
+ return "Sentiment analysis: Neutral tone detected"
996
+ else:
997
+ return f"Analysis type '{analysis_type}' not supported"
998
+
999
+ def generate_report(findings: str, format: str = "markdown") -> str:
1000
+ """Generate a formatted report."""
1001
+ if format == "markdown":
1002
+ return f"# Analysis Report\n\n{findings}\n\nGenerated by ConnectOnion"
1003
+ else:
1004
+ return findings
1005
+
1006
+ file_agent = Agent(
1007
+ name="file_analyzer",
1008
+ system_prompt="You are a document analyst who provides detailed insights.",
1009
+ tools=[read_file, analyze_text, generate_report],
1010
+ max_iterations=15
1011
+ )
1012
+ ```
1013
+
1014
+ ### Pattern 4: Multi-Agent Coordination
1015
+
1016
+ ```python
1017
+ # Specialized agents for different tasks
1018
+ calculator = Agent("calc", tools=[calculate], max_iterations=5)
1019
+ researcher = Agent("research", tools=[web_search, summarize], max_iterations=20)
1020
+ writer = Agent("writer", tools=[generate_report, save_notes], max_iterations=10)
1021
+
1022
+ def coordinate_agents(task: str) -> str:
1023
+ """Coordinate multiple agents for complex tasks."""
1024
+ if "calculate" in task.lower():
1025
+ return calculator.input(task)
1026
+ elif "research" in task.lower():
1027
+ return researcher.input(task)
1028
+ elif "write" in task.lower():
1029
+ return writer.input(task)
1030
+ else:
1031
+ # Default to research agent for general tasks
1032
+ return researcher.input(task)
1033
+ ```
1034
+
1035
+ ---
1036
+
1037
+ ## Advanced Patterns
1038
+
1039
+ ### Auto-Retry with Increasing Limits
1040
+
1041
+ ```python
1042
+ def smart_input(agent: Agent, prompt: str, max_retries: int = 3) -> str:
1043
+ """Automatically retry with higher iteration limits if needed."""
1044
+ limits = [10, 25, 50]
1045
+
1046
+ for i, limit in enumerate(limits):
1047
+ result = agent.input(prompt, max_iterations=limit)
1048
+ if "Maximum iterations" not in result:
1049
+ return result
1050
+ if i < max_retries - 1:
1051
+ print(f"Retrying with {limits[i+1]} iterations...")
1052
+
1053
+ return "Task too complex even with maximum iterations"
1054
+
1055
+ # Usage
1056
+ agent = Agent("adaptive", tools=[...])
1057
+ result = smart_input(agent, "Complex multi-step task")
1058
+ ```
1059
+
1060
+ ### Self-Adjusting Agent
1061
+
1062
+ ```python
1063
+ class SmartAgent:
1064
+ def __init__(self, name: str, tools: list):
1065
+ self.agent = Agent(name, tools=tools)
1066
+ self.task_patterns = {
1067
+ 'simple': (['what', 'when', 'calculate'], 5),
1068
+ 'moderate': (['analyze', 'compare', 'summarize'], 15),
1069
+ 'complex': (['research', 'comprehensive', 'detailed'], 30)
1070
+ }
1071
+
1072
+ def input(self, prompt: str) -> str:
1073
+ # Detect complexity from keywords
1074
+ max_iter = 10 # default
1075
+ prompt_lower = prompt.lower()
1076
+
1077
+ for pattern_name, (keywords, iterations) in self.task_patterns.items():
1078
+ if any(keyword in prompt_lower for keyword in keywords):
1079
+ max_iter = iterations
1080
+ break
1081
+
1082
+ return self.agent.input(prompt, max_iterations=max_iter)
1083
+
1084
+ # Usage
1085
+ smart = SmartAgent("adaptive", tools=[...])
1086
+ smart.input("What is 2+2?") # Uses 5 iterations
1087
+ smart.input("Research and analyze market trends") # Uses 30 iterations
1088
+ ```
1089
+
1090
+ ---
1091
+
1092
+ ## Best Practices
1093
+
1094
+ ### Tool Design
1095
+
1096
+ ✅ **Good:**
1097
+ ```python
1098
+ def search_papers(query: str, max_results: int = 10, field: str = "all") -> str:
1099
+ """Search academic papers with specific parameters."""
1100
+ return f"Found {max_results} papers about '{query}' in {field}"
1101
+ ```
1102
+
1103
+ ❌ **Avoid:**
1104
+ ```python
1105
+ def search(q, n=10): # No type hints
1106
+ return "some results" # Vague return
1107
+ ```
1108
+
1109
+ ### Error Handling
1110
+
1111
+ ✅ **Good:**
1112
+ ```python
1113
+ def read_file(filepath: str) -> str:
1114
+ """Read file with proper error handling."""
1115
+ try:
1116
+ with open(filepath, 'r') as f:
1117
+ return f.read()
1118
+ except FileNotFoundError:
1119
+ return f"Error: File '{filepath}' not found"
1120
+ except PermissionError:
1121
+ return f"Error: Permission denied for '{filepath}'"
1122
+ except Exception as e:
1123
+ return f"Error reading file: {e}"
1124
+ ```
1125
+
1126
+ ### Agent Configuration
1127
+
1128
+ ✅ **Good:**
1129
+ ```python
1130
+ # Clear purpose, markdown prompts, appropriate limits
1131
+ data_analyst = Agent(
1132
+ name="data_analyst",
1133
+ system_prompt="prompts/data_scientist.md", # Use markdown files!
1134
+ tools=[load_data, analyze_stats, create_visualization],
1135
+ max_iterations=20 # Data analysis can be multi-step
1136
+ )
1137
+ ```
1138
+
1139
+ ❌ **Avoid:**
1140
+ ```python
1141
+ # Vague purpose, inline prompts, arbitrary limits
1142
+ agent = Agent(
1143
+ name="agent",
1144
+ system_prompt="You are an agent that does stuff. Be helpful and do things when asked. Always be polite and provide good answers...", # Too long inline!
1145
+ tools=[lots_of_random_tools],
1146
+ max_iterations=100 # Way too high
1147
+ )
1148
+ ```
1149
+
1150
+ ### System Prompt Best Practices
1151
+
1152
+ ✅ **Use Markdown Files:**
1153
+ ```python
1154
+ # Recommended approach
1155
+ agent = Agent(
1156
+ name="support_specialist",
1157
+ system_prompt="prompts/customer_support.md",
1158
+ tools=[create_ticket, search_kb]
1159
+ )
1160
+ ```
1161
+
1162
+ ❌ **Avoid Inline Strings:**
1163
+ ```python
1164
+ # Hard to maintain and review
1165
+ agent = Agent(
1166
+ name="support_specialist",
1167
+ system_prompt="You are a customer support specialist. Always be empathetic. Ask clarifying questions. Provide step-by-step solutions. Use professional language...",
1168
+ tools=[create_ticket, search_kb]
1169
+ )
1170
+ ```
1171
+
1172
+ ---
1173
+
1174
+ ## Troubleshooting Guide
1175
+
1176
+ ### Common Issues & Solutions
1177
+
1178
+ **Issue: "Maximum iterations reached"**
1179
+ ```python
1180
+ # Check what happened
1181
+ if "Maximum iterations" in result:
1182
+ # Look at the last record to see what went wrong
1183
+ last_record = agent.history.records[-1]
1184
+ for tool_call in last_record.tool_calls:
1185
+ if tool_call['status'] == 'error':
1186
+ print(f"Tool {tool_call['name']} failed: {tool_call['result']}")
1187
+
1188
+ # Solutions:
1189
+ # 1. Increase iterations
1190
+ result = agent.input(prompt, max_iterations=30)
1191
+
1192
+ # 2. Break down the task
1193
+ step1 = agent.input("First, analyze the data")
1194
+ step2 = agent.input(f"Based on {step1}, create summary")
1195
+ ```
1196
+
1197
+ **Issue: Tools not working**
1198
+ ```python
1199
+ # Check tool registration
1200
+ print(agent.list_tools()) # See what tools are available
1201
+
1202
+ # Check tool schemas
1203
+ for tool in agent.tools:
1204
+ print(tool.to_function_schema())
1205
+ ```
1206
+
1207
+ **Issue: Unexpected behavior**
1208
+ ```python
1209
+ # Use @xray for debugging
1210
+ @xray
1211
+ def debug_tool(input: str) -> str:
1212
+ context = get_xray_context()
1213
+ print(f"Iteration: {context.iteration}")
1214
+ print(f"Previous tools: {context.previous_tools}")
1215
+ return f"Processed: {input}"
1216
+ ```
1217
+
1218
+ ---
1219
+
1220
+ ## When to Use ConnectOnion
1221
+
1222
+ ### Good Use Cases
1223
+ - Building custom AI assistants with specific tools
1224
+ - Automating workflows that need multiple steps
1225
+ - Creating domain-specific chatbots (customer support, data analysis, etc.)
1226
+ - Prototyping agent behaviors with automatic tracking
1227
+ - Educational projects to understand agent architectures
1228
+
1229
+ ### Not Ideal For
1230
+ - Simple single-function calls (just call the function directly)
1231
+ - Real-time applications requiring <100ms response times
1232
+ - Production systems without proper error handling and security
1233
+ - Tasks that don't benefit from LLM reasoning
1234
+
1235
+ ---
1236
+
1237
+ ## Links & Resources
1238
+
1239
+ - **GitHub**: https://github.com/openonion/connectonion
1240
+ - **PyPI**: https://pypi.org/project/connectonion/
1241
+ - **Latest Version**: 0.0.1b4
1242
+
1243
+ ---
1244
+
1245
+ ## AI Assistant Instructions
1246
+
1247
+ When helping users with ConnectOnion:
1248
+
1249
+ 1. **Start Simple**: Use the basic patterns first, add complexity only when needed
1250
+ 2. **Type Hints**: Always include proper type hints in tool functions
1251
+ 3. **Error Handling**: Add try/catch blocks for robust tools
1252
+ 4. **Iteration Limits**: Help users choose appropriate max_iterations based on task complexity
1253
+ 5. **Debugging**: Suggest @xray decorator when users have issues
1254
+ 6. **Best Practices**: Guide users toward function-based tools over complex classes
1255
+
1256
+ Remember: ConnectOnion is designed to make simple things simple and hard things possible. Start with the basics and build up complexity gradually.