connectonion 0.6.2__py3-none-any.whl → 0.6.4__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 (410) hide show
  1. connectonion/__init__.py +46 -9
  2. connectonion/cli/__init__.py +11 -1
  3. connectonion/cli/browser_agent/__init__.py +11 -1
  4. connectonion/cli/browser_agent/browser.py +13 -3
  5. connectonion/cli/browser_agent/element_finder.py +8 -0
  6. connectonion/cli/browser_agent/highlight_screenshot.py +9 -1
  7. connectonion/cli/browser_agent/scroll.py +8 -0
  8. connectonion/cli/co_ai/__init__.py +6 -0
  9. connectonion/cli/co_ai/agent.py +87 -0
  10. connectonion/cli/co_ai/agents/__init__.py +5 -0
  11. connectonion/cli/co_ai/agents/registry.py +57 -0
  12. connectonion/cli/co_ai/commands/__init__.py +45 -0
  13. connectonion/cli/co_ai/commands/compact.py +173 -0
  14. connectonion/cli/co_ai/commands/cost.py +77 -0
  15. connectonion/cli/co_ai/commands/export.py +60 -0
  16. connectonion/cli/co_ai/commands/help.py +80 -0
  17. connectonion/cli/co_ai/commands/init.py +101 -0
  18. connectonion/cli/co_ai/commands/sessions.py +55 -0
  19. connectonion/cli/co_ai/commands/tasks.py +63 -0
  20. connectonion/cli/co_ai/commands/undo.py +103 -0
  21. connectonion/cli/co_ai/context.py +127 -0
  22. connectonion/cli/co_ai/main.py +52 -0
  23. connectonion/cli/co_ai/plugins/__init__.py +5 -0
  24. connectonion/cli/co_ai/plugins/system_reminder.py +154 -0
  25. connectonion/cli/co_ai/prompts/agents/explore.md +79 -0
  26. connectonion/cli/co_ai/prompts/agents/plan.md +60 -0
  27. connectonion/cli/co_ai/prompts/assembler.py +303 -0
  28. connectonion/cli/{docs/co-vibecoding-principles-docs-contexts-all-in-one.md → co_ai/prompts/connectonion/README.md} +26 -0
  29. connectonion/cli/co_ai/prompts/connectonion/api.md +457 -0
  30. connectonion/cli/co_ai/prompts/connectonion/cli/README.md +805 -0
  31. connectonion/cli/co_ai/prompts/connectonion/cli/auth.md +46 -0
  32. connectonion/cli/co_ai/prompts/connectonion/cli/browser.md +235 -0
  33. connectonion/cli/co_ai/prompts/connectonion/cli/copy.md +184 -0
  34. connectonion/cli/co_ai/prompts/connectonion/cli/create.md +335 -0
  35. connectonion/cli/co_ai/prompts/connectonion/cli/init.md +431 -0
  36. connectonion/cli/co_ai/prompts/connectonion/co-directory-structure.md +214 -0
  37. connectonion/cli/co_ai/prompts/connectonion/concepts/agent.md +1078 -0
  38. connectonion/cli/co_ai/prompts/connectonion/concepts/events.md +816 -0
  39. connectonion/cli/co_ai/prompts/connectonion/concepts/llm_do.md +256 -0
  40. connectonion/cli/co_ai/prompts/connectonion/concepts/max_iterations.md +362 -0
  41. connectonion/cli/co_ai/prompts/connectonion/concepts/models.md +641 -0
  42. connectonion/cli/co_ai/prompts/connectonion/concepts/plugins.md +100 -0
  43. connectonion/cli/co_ai/prompts/connectonion/concepts/prompts.md +122 -0
  44. connectonion/cli/co_ai/prompts/connectonion/concepts/tools.md +512 -0
  45. connectonion/cli/co_ai/prompts/connectonion/concepts/transcribe.md +156 -0
  46. connectonion/cli/co_ai/prompts/connectonion/concepts/trust.md +291 -0
  47. connectonion/cli/co_ai/prompts/connectonion/debug/README.md +18 -0
  48. connectonion/cli/co_ai/prompts/connectonion/debug/auto_debug.md +1026 -0
  49. connectonion/cli/co_ai/prompts/connectonion/debug/console.md +129 -0
  50. connectonion/cli/co_ai/prompts/connectonion/debug/eval-format.md +178 -0
  51. connectonion/cli/co_ai/prompts/connectonion/debug/eval.md +230 -0
  52. connectonion/cli/co_ai/prompts/connectonion/debug/exceptions.md +307 -0
  53. connectonion/cli/co_ai/prompts/connectonion/debug/log.md +117 -0
  54. connectonion/cli/co_ai/prompts/connectonion/debug/xray.md +215 -0
  55. connectonion/cli/co_ai/prompts/connectonion/design-decisions/001-choosing-input-method.md +202 -0
  56. connectonion/cli/co_ai/prompts/connectonion/design-decisions/002-choosing-llm-function-name.md +202 -0
  57. connectonion/cli/co_ai/prompts/connectonion/design-decisions/003-choosing-trust-keyword.md +141 -0
  58. connectonion/cli/co_ai/prompts/connectonion/design-decisions/004-cli-create-flow.md +117 -0
  59. connectonion/cli/co_ai/prompts/connectonion/design-decisions/005-designing-agent-network-protocol.md +503 -0
  60. connectonion/cli/co_ai/prompts/connectonion/design-decisions/006-agent-address-format.md +305 -0
  61. connectonion/cli/co_ai/prompts/connectonion/design-decisions/007-authentication-backend-design.md +240 -0
  62. connectonion/cli/co_ai/prompts/connectonion/design-decisions/008-naming-is-hard.md +228 -0
  63. connectonion/cli/co_ai/prompts/connectonion/design-decisions/009-why-connect-function.md +167 -0
  64. connectonion/cli/co_ai/prompts/connectonion/design-decisions/010-cli-ux-progressive-disclosure.md +176 -0
  65. connectonion/cli/co_ai/prompts/connectonion/design-decisions/011-global-config-identity-management.md +357 -0
  66. connectonion/cli/co_ai/prompts/connectonion/design-decisions/012-tool-execution-separation.md +259 -0
  67. connectonion/cli/co_ai/prompts/connectonion/design-decisions/013-debug-and-logging-design.md +253 -0
  68. connectonion/cli/co_ai/prompts/connectonion/design-decisions/014-hook-system-design.md +510 -0
  69. connectonion/cli/co_ai/prompts/connectonion/design-decisions/015-interactive-auto-debug-design.md +837 -0
  70. connectonion/cli/co_ai/prompts/connectonion/design-decisions/016-why-no-zero-knowledge-proofs.md +358 -0
  71. connectonion/cli/co_ai/prompts/connectonion/design-decisions/017-session-logging-and-eval-format.md +120 -0
  72. connectonion/cli/co_ai/prompts/connectonion/design-decisions/018-event-api-naming.md +274 -0
  73. connectonion/cli/co_ai/prompts/connectonion/design-decisions/019-agent-lifecycle-design.md +655 -0
  74. connectonion/cli/co_ai/prompts/connectonion/design-decisions/020-trust-system-and-network-architecture.md +503 -0
  75. connectonion/cli/co_ai/prompts/connectonion/design-decisions/021-task-storage-jsonl-design.md +496 -0
  76. connectonion/cli/co_ai/prompts/connectonion/design-decisions/022-raw-asgi-implementation.md +273 -0
  77. connectonion/cli/co_ai/prompts/connectonion/examples/agent_reasoning.md +62 -0
  78. connectonion/cli/co_ai/prompts/connectonion/examples/atomic_tools.md +24 -0
  79. connectonion/cli/co_ai/prompts/connectonion/examples/load_guide.md +18 -0
  80. connectonion/cli/co_ai/prompts/connectonion/examples.md +0 -0
  81. connectonion/cli/co_ai/prompts/connectonion/hook-system-options.md +364 -0
  82. connectonion/cli/co_ai/prompts/connectonion/index.md +162 -0
  83. connectonion/cli/co_ai/prompts/connectonion/integrations/README.md +12 -0
  84. connectonion/cli/co_ai/prompts/connectonion/integrations/auth.md +450 -0
  85. connectonion/cli/co_ai/prompts/connectonion/integrations/google.md +431 -0
  86. connectonion/cli/co_ai/prompts/connectonion/integrations/microsoft.md +370 -0
  87. connectonion/cli/co_ai/prompts/connectonion/network/README.md +14 -0
  88. connectonion/cli/co_ai/prompts/connectonion/network/connect.md +543 -0
  89. connectonion/cli/co_ai/prompts/connectonion/network/connection.md +538 -0
  90. connectonion/cli/co_ai/prompts/connectonion/network/deploy.md +123 -0
  91. connectonion/cli/co_ai/prompts/connectonion/network/host.md +1049 -0
  92. connectonion/cli/co_ai/prompts/connectonion/network/protocol/agent-relay-protocol.md +495 -0
  93. connectonion/cli/co_ai/prompts/connectonion/network/protocol/announce-message.md +115 -0
  94. connectonion/cli/co_ai/prompts/connectonion/principles.md +124 -0
  95. connectonion/cli/co_ai/prompts/connectonion/quickstart.md +261 -0
  96. connectonion/cli/co_ai/prompts/connectonion/roadmap.md +81 -0
  97. connectonion/cli/co_ai/prompts/connectonion/templates/README.md +77 -0
  98. connectonion/cli/co_ai/prompts/connectonion/templates/meta-agent.md +152 -0
  99. connectonion/cli/co_ai/prompts/connectonion/templates/minimal.md +105 -0
  100. connectonion/cli/co_ai/prompts/connectonion/templates/playwright.md +130 -0
  101. connectonion/cli/co_ai/prompts/connectonion/templates/web-research.md +144 -0
  102. connectonion/cli/co_ai/prompts/connectonion/tui/README.md +95 -0
  103. connectonion/cli/co_ai/prompts/connectonion/tui/chat.md +181 -0
  104. connectonion/cli/co_ai/prompts/connectonion/tui/divider.md +63 -0
  105. connectonion/cli/co_ai/prompts/connectonion/tui/dropdown.md +83 -0
  106. connectonion/cli/co_ai/prompts/connectonion/tui/footer.md +44 -0
  107. connectonion/cli/co_ai/prompts/connectonion/tui/fuzzy.md +68 -0
  108. connectonion/cli/co_ai/prompts/connectonion/tui/input.md +84 -0
  109. connectonion/cli/co_ai/prompts/connectonion/tui/keys.md +77 -0
  110. connectonion/cli/co_ai/prompts/connectonion/tui/pick.md +71 -0
  111. connectonion/cli/co_ai/prompts/connectonion/tui/providers.md +89 -0
  112. connectonion/cli/co_ai/prompts/connectonion/tui/status_bar.md +67 -0
  113. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/README.md +156 -0
  114. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/calendar_plugin.md +68 -0
  115. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/eval.md +89 -0
  116. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/gmail_plugin.md +68 -0
  117. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/image_result_formatter.md +74 -0
  118. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/re_act.md +86 -0
  119. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/shell_approval.md +69 -0
  120. connectonion/cli/co_ai/prompts/connectonion/useful_tools/README.md +81 -0
  121. connectonion/cli/co_ai/prompts/connectonion/useful_tools/diff_writer.md +138 -0
  122. connectonion/cli/co_ai/prompts/connectonion/useful_tools/get_emails.md +499 -0
  123. connectonion/cli/co_ai/prompts/connectonion/useful_tools/gmail.md +135 -0
  124. connectonion/cli/co_ai/prompts/connectonion/useful_tools/google_calendar.md +106 -0
  125. connectonion/cli/co_ai/prompts/connectonion/useful_tools/memory.md +486 -0
  126. connectonion/cli/co_ai/prompts/connectonion/useful_tools/microsoft_calendar.md +106 -0
  127. connectonion/cli/co_ai/prompts/connectonion/useful_tools/outlook.md +120 -0
  128. connectonion/cli/co_ai/prompts/connectonion/useful_tools/send_email.md +403 -0
  129. connectonion/cli/co_ai/prompts/connectonion/useful_tools/shell.md +95 -0
  130. connectonion/cli/co_ai/prompts/connectonion/useful_tools/slash_command.md +96 -0
  131. connectonion/cli/co_ai/prompts/connectonion/useful_tools/terminal.md +97 -0
  132. connectonion/cli/co_ai/prompts/connectonion/useful_tools/todo_list.md +252 -0
  133. connectonion/cli/co_ai/prompts/connectonion/useful_tools/web_fetch.md +130 -0
  134. connectonion/cli/co_ai/prompts/connectonion/vibe-coding-guide.md +97 -0
  135. connectonion/cli/co_ai/prompts/connectonion/windows-support.md +258 -0
  136. connectonion/cli/co_ai/prompts/main.md +247 -0
  137. connectonion/cli/co_ai/prompts/summarization.md +55 -0
  138. connectonion/cli/co_ai/prompts/system-reminders/agent.md +23 -0
  139. connectonion/cli/co_ai/prompts/system-reminders/plan_mode.md +13 -0
  140. connectonion/cli/co_ai/prompts/system-reminders/security.md +14 -0
  141. connectonion/cli/co_ai/prompts/system-reminders/simplicity.md +14 -0
  142. connectonion/cli/co_ai/prompts/tools/ask_user.md +61 -0
  143. connectonion/cli/co_ai/prompts/tools/background.md +57 -0
  144. connectonion/cli/co_ai/prompts/tools/edit.md +90 -0
  145. connectonion/cli/co_ai/prompts/tools/glob.md +52 -0
  146. connectonion/cli/co_ai/prompts/tools/grep.md +55 -0
  147. connectonion/cli/co_ai/prompts/tools/plan_mode.md +80 -0
  148. connectonion/cli/co_ai/prompts/tools/read.md +40 -0
  149. connectonion/cli/co_ai/prompts/tools/shell.md +67 -0
  150. connectonion/cli/co_ai/prompts/tools/task.md +51 -0
  151. connectonion/cli/co_ai/prompts/tools/todo.md +139 -0
  152. connectonion/cli/co_ai/prompts/tools/write.md +47 -0
  153. connectonion/cli/co_ai/prompts/workflow.md +89 -0
  154. connectonion/cli/co_ai/sessions.py +110 -0
  155. connectonion/cli/co_ai/skills/__init__.py +37 -0
  156. connectonion/cli/co_ai/skills/builtin/commit/SKILL.md +63 -0
  157. connectonion/cli/co_ai/skills/builtin/review-pr/SKILL.md +76 -0
  158. connectonion/cli/co_ai/skills/loader.py +166 -0
  159. connectonion/cli/co_ai/skills/tool.py +46 -0
  160. connectonion/cli/co_ai/tools/__init__.py +92 -0
  161. connectonion/cli/co_ai/tools/ask_user.py +35 -0
  162. connectonion/cli/co_ai/tools/background.py +201 -0
  163. connectonion/cli/co_ai/tools/diff_writer.py +291 -0
  164. connectonion/cli/co_ai/tools/edit.py +89 -0
  165. connectonion/cli/co_ai/tools/glob.py +84 -0
  166. connectonion/cli/co_ai/tools/grep.py +158 -0
  167. connectonion/cli/co_ai/tools/load_guide.py +23 -0
  168. connectonion/cli/co_ai/tools/multi_edit.py +116 -0
  169. connectonion/cli/co_ai/tools/plan_mode.py +169 -0
  170. connectonion/cli/co_ai/tools/read.py +61 -0
  171. connectonion/cli/co_ai/tools/task.py +59 -0
  172. connectonion/cli/co_ai/tools/todo_list.py +159 -0
  173. connectonion/cli/co_ai/tools/write.py +126 -0
  174. connectonion/cli/commands/__init__.py +11 -1
  175. connectonion/cli/commands/ai_commands.py +34 -0
  176. connectonion/cli/commands/copy_commands.py +55 -6
  177. connectonion/cli/commands/create.py +20 -17
  178. connectonion/cli/commands/init.py +19 -22
  179. connectonion/cli/commands/project_cmd_lib.py +15 -0
  180. connectonion/cli/main.py +11 -0
  181. connectonion/console.py +15 -1
  182. connectonion/core/__init__.py +10 -1
  183. connectonion/core/agent.py +37 -16
  184. connectonion/core/exceptions.py +74 -0
  185. connectonion/core/llm.py +54 -6
  186. connectonion/core/tool_executor.py +32 -31
  187. connectonion/core/tool_factory.py +47 -10
  188. connectonion/debug/__init__.py +10 -1
  189. connectonion/debug/debug_explainer/__init__.py +10 -1
  190. connectonion/debug/execution_analyzer/__init__.py +10 -1
  191. connectonion/debug/execution_analyzer/execution_analysis.py +5 -2
  192. connectonion/debug/runtime_inspector/__init__.py +10 -1
  193. connectonion/docs/.package-ignore +6 -0
  194. connectonion/docs/README.md +2036 -0
  195. connectonion/docs/api.md +457 -0
  196. connectonion/docs/archive/001-ai-agent-is-just-prompt-plus-function.md +249 -0
  197. connectonion/docs/archive/README.md +53 -0
  198. connectonion/docs/archive/archive/consolidation-plan.md +72 -0
  199. connectonion/docs/archive/archive/core-principles-extracted.md +239 -0
  200. connectonion/docs/archive/archive/master-principles.md +222 -0
  201. connectonion/docs/archive/archive/principles.md +293 -0
  202. connectonion/docs/archive/archive/simplicity-principles.md +221 -0
  203. connectonion/docs/archive/attack-defense-insights.md +410 -0
  204. connectonion/docs/archive/business-model.md +305 -0
  205. connectonion/docs/archive/core-principles-unified.md +190 -0
  206. connectonion/docs/archive/discussion-journey.md +178 -0
  207. connectonion/docs/archive/economic-analysis.md +323 -0
  208. connectonion/docs/archive/features/01-share-and-find.md +256 -0
  209. connectonion/docs/archive/features/02-agent-authentication.md +93 -0
  210. connectonion/docs/archive/features/03-test-before-trust.md +71 -0
  211. connectonion/docs/archive/features/06-reliability-and-offline.md +197 -0
  212. connectonion/docs/archive/features/README.md +46 -0
  213. connectonion/docs/archive/features-roadmap.md +247 -0
  214. connectonion/docs/archive/mcp-comparison-insights.md +215 -0
  215. connectonion/docs/archive/migration-strategy.md +571 -0
  216. connectonion/docs/archive/mini-whitepaper.md +293 -0
  217. connectonion/docs/archive/network-protocol.md +394 -0
  218. connectonion/docs/archive/semantic-revolution.md +367 -0
  219. connectonion/docs/archive/technical-architecture.md +453 -0
  220. connectonion/docs/archive/the-semantic-insight.md +207 -0
  221. connectonion/docs/archive/threat-model.md +164 -0
  222. connectonion/docs/cli/README.md +805 -0
  223. connectonion/docs/cli/auth.md +46 -0
  224. connectonion/docs/cli/browser.md +235 -0
  225. connectonion/docs/cli/copy.md +232 -0
  226. connectonion/docs/cli/create.md +335 -0
  227. connectonion/docs/cli/init.md +431 -0
  228. connectonion/docs/co-directory-structure.md +214 -0
  229. connectonion/docs/concepts/agent.md +1078 -0
  230. connectonion/docs/concepts/events.md +699 -0
  231. connectonion/docs/concepts/llm_do.md +256 -0
  232. connectonion/docs/concepts/max_iterations.md +362 -0
  233. connectonion/docs/concepts/models.md +641 -0
  234. connectonion/docs/concepts/plugins.md +101 -0
  235. connectonion/docs/concepts/prompts.md +122 -0
  236. connectonion/docs/concepts/session.md +428 -0
  237. connectonion/docs/concepts/tools.md +512 -0
  238. connectonion/docs/concepts/transcribe.md +156 -0
  239. connectonion/docs/concepts/trust.md +291 -0
  240. connectonion/docs/connectonion.md +1256 -0
  241. connectonion/docs/debug/README.md +18 -0
  242. connectonion/docs/debug/auto_debug.md +1026 -0
  243. connectonion/docs/debug/console.md +129 -0
  244. connectonion/docs/debug/eval-format.md +178 -0
  245. connectonion/docs/debug/eval.md +230 -0
  246. connectonion/docs/debug/exceptions.md +307 -0
  247. connectonion/docs/debug/log.md +117 -0
  248. connectonion/docs/debug/xray.md +215 -0
  249. connectonion/docs/design-decisions/001-choosing-input-method.md +202 -0
  250. connectonion/docs/design-decisions/002-choosing-llm-function-name.md +202 -0
  251. connectonion/docs/design-decisions/003-choosing-trust-keyword.md +141 -0
  252. connectonion/docs/design-decisions/004-cli-create-flow.md +117 -0
  253. connectonion/docs/design-decisions/005-designing-agent-network-protocol.md +503 -0
  254. connectonion/docs/design-decisions/006-agent-address-format.md +305 -0
  255. connectonion/docs/design-decisions/007-authentication-backend-design.md +240 -0
  256. connectonion/docs/design-decisions/008-naming-is-hard.md +228 -0
  257. connectonion/docs/design-decisions/009-why-connect-function.md +167 -0
  258. connectonion/docs/design-decisions/010-cli-ux-progressive-disclosure.md +176 -0
  259. connectonion/docs/design-decisions/011-global-config-identity-management.md +357 -0
  260. connectonion/docs/design-decisions/012-tool-execution-separation.md +259 -0
  261. connectonion/docs/design-decisions/013-debug-and-logging-design.md +253 -0
  262. connectonion/docs/design-decisions/014-hook-system-design.md +510 -0
  263. connectonion/docs/design-decisions/015-interactive-auto-debug-design.md +837 -0
  264. connectonion/docs/design-decisions/016-why-no-zero-knowledge-proofs.md +358 -0
  265. connectonion/docs/design-decisions/017-session-logging-and-eval-format.md +120 -0
  266. connectonion/docs/design-decisions/018-event-api-naming.md +274 -0
  267. connectonion/docs/design-decisions/019-agent-lifecycle-design.md +655 -0
  268. connectonion/docs/design-decisions/020-trust-system-and-network-architecture.md +503 -0
  269. connectonion/docs/design-decisions/021-task-storage-jsonl-design.md +496 -0
  270. connectonion/docs/design-decisions/022-raw-asgi-implementation.md +273 -0
  271. connectonion/docs/examples.md +0 -0
  272. connectonion/docs/hook-system-options.md +364 -0
  273. connectonion/docs/integrations/README.md +12 -0
  274. connectonion/docs/integrations/auth.md +450 -0
  275. connectonion/docs/integrations/google.md +431 -0
  276. connectonion/docs/integrations/microsoft.md +370 -0
  277. connectonion/docs/network/README.md +14 -0
  278. connectonion/docs/network/connect.md +629 -0
  279. connectonion/docs/network/deploy.md +124 -0
  280. connectonion/docs/network/host.md +1087 -0
  281. connectonion/docs/network/io.md +538 -0
  282. connectonion/docs/network/protocol/agent-relay-protocol.md +495 -0
  283. connectonion/docs/network/protocol/announce-message.md +115 -0
  284. connectonion/docs/principles.md +124 -0
  285. connectonion/docs/quickstart.md +261 -0
  286. connectonion/docs/roadmap.md +81 -0
  287. connectonion/docs/templates/README.md +77 -0
  288. connectonion/docs/templates/meta-agent.md +152 -0
  289. connectonion/docs/templates/minimal.md +105 -0
  290. connectonion/docs/templates/playwright.md +130 -0
  291. connectonion/docs/templates/web-research.md +144 -0
  292. connectonion/docs/tui/README.md +95 -0
  293. connectonion/docs/tui/chat.md +181 -0
  294. connectonion/docs/tui/divider.md +63 -0
  295. connectonion/docs/tui/dropdown.md +83 -0
  296. connectonion/docs/tui/footer.md +44 -0
  297. connectonion/docs/tui/fuzzy.md +68 -0
  298. connectonion/docs/tui/input.md +84 -0
  299. connectonion/docs/tui/keys.md +77 -0
  300. connectonion/docs/tui/pick.md +71 -0
  301. connectonion/docs/tui/providers.md +89 -0
  302. connectonion/docs/tui/status_bar.md +67 -0
  303. connectonion/docs/useful_plugins/README.md +160 -0
  304. connectonion/docs/useful_plugins/calendar_plugin.md +68 -0
  305. connectonion/docs/useful_plugins/eval.md +89 -0
  306. connectonion/docs/useful_plugins/gmail_plugin.md +68 -0
  307. connectonion/docs/useful_plugins/image_result_formatter.md +74 -0
  308. connectonion/docs/useful_plugins/re_act.md +86 -0
  309. connectonion/docs/useful_plugins/shell_approval.md +69 -0
  310. connectonion/docs/useful_plugins/system_reminder.md +210 -0
  311. connectonion/docs/useful_plugins/tool_approval.md +139 -0
  312. connectonion/docs/useful_prompts/README.md +127 -0
  313. connectonion/docs/useful_prompts/coding_agent.md +214 -0
  314. connectonion/docs/useful_tools/README.md +81 -0
  315. connectonion/docs/useful_tools/ask_user.md +103 -0
  316. connectonion/docs/useful_tools/diff_writer.md +158 -0
  317. connectonion/docs/useful_tools/get_emails.md +519 -0
  318. connectonion/docs/useful_tools/gmail.md +155 -0
  319. connectonion/docs/useful_tools/google_calendar.md +126 -0
  320. connectonion/docs/useful_tools/memory.md +506 -0
  321. connectonion/docs/useful_tools/microsoft_calendar.md +126 -0
  322. connectonion/docs/useful_tools/outlook.md +140 -0
  323. connectonion/docs/useful_tools/send_email.md +423 -0
  324. connectonion/docs/useful_tools/shell.md +115 -0
  325. connectonion/docs/useful_tools/slash_command.md +116 -0
  326. connectonion/docs/useful_tools/terminal.md +115 -0
  327. connectonion/docs/useful_tools/todo_list.md +272 -0
  328. connectonion/docs/useful_tools/web_fetch.md +150 -0
  329. connectonion/docs/vibe-coding-guide.md +97 -0
  330. connectonion/docs/windows-support.md +258 -0
  331. connectonion/logger.py +3 -3
  332. connectonion/network/__init__.py +19 -6
  333. connectonion/network/asgi/__init__.py +81 -0
  334. connectonion/network/asgi/http.py +205 -0
  335. connectonion/network/asgi/websocket.py +217 -0
  336. connectonion/network/connect.py +232 -185
  337. connectonion/network/host/__init__.py +59 -0
  338. connectonion/network/host/auth.py +191 -0
  339. connectonion/network/host/routes.py +135 -0
  340. connectonion/network/host/server.py +289 -0
  341. connectonion/network/host/session.py +78 -0
  342. connectonion/network/io/__init__.py +21 -0
  343. connectonion/network/{connection.py → io/base.py} +17 -42
  344. connectonion/network/io/websocket.py +55 -0
  345. connectonion/network/relay.py +37 -16
  346. connectonion/network/trust/__init__.py +30 -0
  347. connectonion/network/trust/factory.py +138 -0
  348. connectonion/network/{trust_agents.py → trust/prompts.py} +3 -3
  349. connectonion/network/{trust_functions.py → trust/tools.py} +2 -2
  350. connectonion/prompt_files/__init__.py +11 -1
  351. connectonion/prompt_files/react_acknowledge.md +26 -0
  352. connectonion/prompts.py +10 -1
  353. connectonion/tui/chat.py +10 -1
  354. connectonion/tui/divider.py +10 -1
  355. connectonion/tui/dropdown.py +10 -1
  356. connectonion/tui/footer.py +8 -0
  357. connectonion/tui/fuzzy.py +11 -1
  358. connectonion/tui/input.py +118 -70
  359. connectonion/tui/keys.py +133 -6
  360. connectonion/tui/providers.py +11 -1
  361. connectonion/tui/status_bar.py +10 -1
  362. connectonion/useful_events_handlers/__init__.py +8 -0
  363. connectonion/useful_events_handlers/reflect.py +19 -4
  364. connectonion/useful_plugins/__init__.py +3 -1
  365. connectonion/useful_plugins/eval.py +2 -2
  366. connectonion/useful_plugins/gmail_plugin.py +3 -3
  367. connectonion/useful_plugins/image_result_formatter.py +3 -3
  368. connectonion/useful_plugins/re_act.py +114 -28
  369. connectonion/useful_plugins/shell_approval.py +2 -2
  370. connectonion/useful_plugins/system_reminder.py +103 -0
  371. connectonion/useful_plugins/tool_approval.py +233 -0
  372. connectonion/useful_plugins/ui_stream.py +18 -133
  373. connectonion/useful_prompts/README.md +61 -0
  374. connectonion/useful_prompts/__init__.py +45 -0
  375. connectonion/useful_prompts/coding_agent/README.md +106 -0
  376. connectonion/useful_prompts/coding_agent/assembler.py +123 -0
  377. connectonion/useful_prompts/coding_agent/prompts/main.md +227 -0
  378. connectonion/useful_prompts/coding_agent/prompts/tools/ask_user.md +61 -0
  379. connectonion/useful_prompts/coding_agent/prompts/tools/background.md +57 -0
  380. connectonion/useful_prompts/coding_agent/prompts/tools/edit.md +90 -0
  381. connectonion/useful_prompts/coding_agent/prompts/tools/glob.md +52 -0
  382. connectonion/useful_prompts/coding_agent/prompts/tools/grep.md +55 -0
  383. connectonion/useful_prompts/coding_agent/prompts/tools/plan_mode.md +80 -0
  384. connectonion/useful_prompts/coding_agent/prompts/tools/read.md +40 -0
  385. connectonion/useful_prompts/coding_agent/prompts/tools/shell.md +67 -0
  386. connectonion/useful_prompts/coding_agent/prompts/tools/task.md +51 -0
  387. connectonion/useful_prompts/coding_agent/prompts/tools/todo.md +139 -0
  388. connectonion/useful_prompts/coding_agent/prompts/tools/write.md +48 -0
  389. connectonion/useful_prompts/system-reminders/security-warning.md +14 -0
  390. connectonion/useful_prompts/system-reminders/test-reminder.md +11 -0
  391. connectonion/useful_tools/__init__.py +31 -4
  392. connectonion/useful_tools/ask_user.py +35 -0
  393. connectonion/useful_tools/bash.py +69 -0
  394. connectonion/useful_tools/diff_writer.py +186 -94
  395. connectonion/useful_tools/edit.py +102 -0
  396. connectonion/useful_tools/glob_files.py +97 -0
  397. connectonion/useful_tools/grep_files.py +171 -0
  398. connectonion/useful_tools/multi_edit.py +116 -0
  399. connectonion/useful_tools/read_file.py +73 -0
  400. connectonion/useful_tools/shell.py +50 -45
  401. connectonion/useful_tools/write_file.py +129 -0
  402. {connectonion-0.6.2.dist-info → connectonion-0.6.4.dist-info}/METADATA +10 -3
  403. connectonion-0.6.4.dist-info/RECORD +472 -0
  404. connectonion/network/asgi.py +0 -407
  405. connectonion/network/host.py +0 -616
  406. connectonion/network/trust.py +0 -166
  407. connectonion-0.6.2.dist-info/RECORD +0 -129
  408. /connectonion/cli/{docs → co_ai/prompts/connectonion}/connectonion.md +0 -0
  409. {connectonion-0.6.2.dist-info → connectonion-0.6.4.dist-info}/WHEEL +0 -0
  410. {connectonion-0.6.2.dist-info → connectonion-0.6.4.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,816 @@
1
+ # Event System (on_events)
2
+
3
+ ConnectOnion's event system lets you hook into the agent lifecycle to add custom behavior like logging, performance monitoring, or adding reasoning steps between tool uses.
4
+
5
+ ---
6
+
7
+ ## Quick Start (60 seconds)
8
+
9
+ ```python
10
+ from connectonion import Agent, after_llm
11
+
12
+ def log_llm_call(agent):
13
+ """Log LLM calls"""
14
+ last_trace = agent.current_session['trace'][-1]
15
+ if last_trace['type'] == 'llm_call':
16
+ print(f"LLM call took {last_trace['duration_ms']:.0f}ms")
17
+
18
+ agent = Agent(
19
+ "assistant",
20
+ tools=[search],
21
+ on_events=[
22
+ after_llm(log_llm_call)
23
+ ]
24
+ )
25
+ ```
26
+
27
+ **Group multiple handlers:**
28
+
29
+ ```python
30
+ from connectonion import Agent, before_each_tool
31
+
32
+ def check_shell(agent):
33
+ ...
34
+
35
+ def check_email(agent):
36
+ ...
37
+
38
+ agent = Agent(
39
+ "assistant",
40
+ on_events=[
41
+ before_each_tool(check_shell, check_email), # both handlers for same event
42
+ ]
43
+ )
44
+ ```
45
+
46
+ **That's it!** Your events run automatically at the right lifecycle points.
47
+
48
+ > **Note: Alternative Decorator Syntax**
49
+ >
50
+ > You can also use decorator syntax: `@before_each_tool` instead of `before_each_tool(fn)`.
51
+ > ```python
52
+ > @before_each_tool
53
+ > def check_shell(agent):
54
+ > ...
55
+ >
56
+ > on_events=[check_shell] # works!
57
+ > ```
58
+ > We recommend the wrapper style `before_each_tool(fn)` because it's easier for LLMs to understand when reading your code. But if you find decorators more elegant, feel free to use them.
59
+
60
+ ---
61
+
62
+ ## Event Types
63
+
64
+ | Event | When It Runs | Fires | Use For |
65
+ |-------|--------------|-------|---------|
66
+ | `after_user_input` | After user provides input | Once per turn | Add context, timestamps, initialize turn state |
67
+ | `before_llm` | Before each LLM call | Multiple per turn | Modify messages for each LLM call |
68
+ | `after_llm` | After LLM responds | Multiple per turn | Log LLM calls, analyze responses |
69
+ | `before_tools` | Before ALL tools in round | Once per round | Prepare shared context for all tools |
70
+ | `before_each_tool` | Before tool execution | Per tool call | Validate args, approval checks (no message changes!) |
71
+ | `after_each_tool` | After each tool completes | Per tool call | Log performance, side effects (no message changes!) |
72
+ | `after_tools` | After ALL tools in round | Once per round | Add reflection, **ONLY place safe to modify messages** |
73
+ | `on_error` | When tool fails | Per tool error | Custom error handling, retries |
74
+ | `on_complete` | After agent finishes | Once per input() | Metrics, cleanup, final summary |
75
+
76
+ > **Note on message injection:** Use `after_tools` (not `after_each_tool`) when adding messages to ensure compatibility with all LLM providers. Anthropic Claude requires tool results to immediately follow tool_calls.
77
+
78
+ ---
79
+
80
+ ## Your Event Function
81
+
82
+ **All events receive the `agent` instance:**
83
+
84
+ ```python
85
+ def my_event(agent):
86
+ # Access everything:
87
+ agent.current_session['messages'] # Full conversation
88
+ agent.current_session['trace'] # Execution history
89
+ agent.current_session['iteration'] # Current iteration (1-10)
90
+ agent.current_session['turn'] # Current turn number
91
+ agent.current_session['user_prompt'] # Current user input
92
+
93
+ # Only in before_each_tool events:
94
+ agent.current_session['pending_tool'] # Tool about to execute
95
+ # {'name': 'bash', 'arguments': {'command': 'ls'}, 'id': 'call_123'}
96
+
97
+ # Modify the agent:
98
+ agent.current_session['messages'].append({
99
+ 'role': 'system',
100
+ 'content': 'Added by my event!'
101
+ })
102
+ ```
103
+
104
+ **What's in the trace?**
105
+
106
+ The most recent trace entry shows what just happened:
107
+
108
+ ```python
109
+ def my_event(agent):
110
+ last_trace = agent.current_session['trace'][-1]
111
+
112
+ # For user_input events:
113
+ last_trace['type'] # 'user_input'
114
+ last_trace['prompt'] # "Search for Python"
115
+ last_trace['turn'] # 1
116
+ last_trace['timestamp'] # 1234567890.123
117
+
118
+ # For llm_call events:
119
+ last_trace['type'] # 'llm_call'
120
+ last_trace['model'] # 'gpt-4o-mini'
121
+ last_trace['duration_ms'] # 234.5
122
+ last_trace['tool_calls_count'] # 2
123
+ last_trace['iteration'] # 1
124
+ last_trace['timestamp'] # 1234567890.123
125
+
126
+ # For tool_execution events:
127
+ last_trace['type'] # 'tool_execution'
128
+ last_trace['tool_name'] # 'search'
129
+ last_trace['arguments'] # {'query': 'Python'}
130
+ last_trace['result'] # "Python is a programming language..."
131
+ last_trace['status'] # 'success' | 'error' | 'not_found'
132
+ last_trace['timing'] # 123.4 (milliseconds)
133
+ last_trace['call_id'] # 'call_abc123'
134
+ last_trace['iteration'] # 1
135
+ last_trace['timestamp'] # 1234567890.456
136
+
137
+ # For error status:
138
+ last_trace['error'] # "Division by zero"
139
+ last_trace['error_type'] # "ZeroDivisionError"
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Examples
145
+
146
+ ### Approve Dangerous Commands (before_each_tool)
147
+
148
+ Use `before_each_tool` to intercept and approve tool calls before execution:
149
+
150
+ ```python
151
+ from connectonion import Agent, before_each_tool
152
+
153
+ def approve_dangerous_commands(agent):
154
+ """Ask for approval before dangerous bash commands"""
155
+ pending = agent.current_session.get('pending_tool')
156
+ if not pending:
157
+ return
158
+
159
+ # Only check bash commands
160
+ if pending['name'] != 'bash':
161
+ return
162
+
163
+ command = pending['arguments'].get('command', '')
164
+
165
+ # Check for dangerous patterns
166
+ if 'rm ' in command or 'sudo ' in command:
167
+ print(f"\n⚠️ Dangerous command: {command}")
168
+ response = input("Execute? (y/N): ")
169
+ if response.lower() != 'y':
170
+ raise ValueError("Command rejected by user")
171
+
172
+ agent = Agent(
173
+ "assistant",
174
+ tools=[bash],
175
+ on_events=[before_each_tool(approve_dangerous_commands)]
176
+ )
177
+ ```
178
+
179
+ **Note:** `pending_tool` is only available during `before_each_tool` events. It contains:
180
+ - `name`: Tool name (e.g., "bash")
181
+ - `arguments`: Tool arguments (e.g., `{'command': 'rm -rf /tmp'}`)
182
+ - `id`: Tool call ID
183
+
184
+ ---
185
+
186
+ ### Add Context Once Per Turn
187
+
188
+ Use `after_user_input` to add context that should only be set once per turn:
189
+
190
+ ```python
191
+ from connectonion import Agent, after_user_input
192
+ from datetime import datetime
193
+
194
+ def add_timestamp(agent):
195
+ """Add current time once when user provides input"""
196
+ agent.current_session['messages'].append({
197
+ 'role': 'system',
198
+ 'content': f'Current time: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}'
199
+ })
200
+
201
+ agent = Agent("assistant", tools=[search], on_events=[after_user_input(add_timestamp)])
202
+ ```
203
+
204
+ ### Add Reflection After Tools
205
+
206
+ Use `llm_do` to make the agent reflect on tool results and plan next steps. **Important:** Use `after_tools` when adding messages to ensure compatibility with all LLM providers:
207
+
208
+ ```python
209
+ from connectonion import Agent, after_tools, llm_do
210
+
211
+ def add_reflection(agent):
212
+ """Add reasoning after all tools in a round complete"""
213
+ trace = agent.current_session['trace'][-1]
214
+
215
+ if trace['type'] == 'tool_execution' and trace['status'] == 'success':
216
+ tool_name = trace['tool_name']
217
+ tool_args = trace['arguments']
218
+ result = trace['result']
219
+
220
+ # Use llm_do to generate reflection
221
+ reflection_prompt = f"""
222
+ You just used the {tool_name} tool with arguments {tool_args}.
223
+ Result: {result[:200]}
224
+
225
+ Provide a brief reflection:
226
+ 1. What did we learn?
227
+ 2. What should we do next?
228
+ 3. Are we making progress toward the goal?
229
+ """
230
+
231
+ reflection = llm_do(
232
+ reflection_prompt,
233
+ system_prompt="You are a thoughtful analyst. Be concise.",
234
+ temperature=0.3
235
+ )
236
+
237
+ # Add reflection to conversation (safe in after_tools)
238
+ agent.current_session['messages'].append({
239
+ 'role': 'assistant',
240
+ 'content': f"🤔 Reflection: {reflection}"
241
+ })
242
+
243
+ print(f"💭 Reflection: {reflection[:100]}...")
244
+
245
+ agent = Agent(
246
+ "researcher",
247
+ tools=[search, analyze],
248
+ on_events=[after_tools(add_reflection)] # Use after_tools for message injection
249
+ )
250
+
251
+ # Now the agent will reflect after each round of tool use!
252
+ agent.input("Research the latest AI trends and analyze their impact")
253
+ # 💭 Reflection: We learned about transformer models. Next, we should analyze...
254
+ ```
255
+
256
+ ### Performance Monitoring
257
+
258
+ ```python
259
+ from connectonion import Agent, after_llm, after_each_tool
260
+
261
+ def monitor_llm_performance(agent):
262
+ """Track LLM call performance"""
263
+ trace = agent.current_session['trace'][-1]
264
+ if trace['type'] == 'llm_call':
265
+ duration = trace['duration_ms']
266
+ model = trace['model']
267
+ if duration > 5000: # More than 5 seconds
268
+ print(f"⚡ Slow LLM call: {model} took {duration/1000:.1f}s")
269
+
270
+ def monitor_tool_performance(agent):
271
+ """Track slow tool executions"""
272
+ trace = agent.current_session['trace'][-1]
273
+ if trace['type'] == 'tool_execution':
274
+ timing = trace.get('timing', 0)
275
+ tool_name = trace['tool_name']
276
+
277
+ if timing > 1000: # More than 1 second
278
+ print(f"⚡ Slow tool: {tool_name} took {timing:.0f}ms")
279
+
280
+ agent = Agent(
281
+ "assistant",
282
+ tools=[search],
283
+ on_events=[
284
+ after_llm(monitor_llm_performance),
285
+ after_each_tool(monitor_tool_performance) # per-tool monitoring
286
+ ]
287
+ )
288
+ ```
289
+
290
+ ### Custom Error Handling
291
+
292
+ ```python
293
+ from connectonion import Agent, on_error
294
+
295
+ def handle_tool_error(agent):
296
+ """Log and handle tool failures"""
297
+ trace = agent.current_session['trace'][-1]
298
+ if trace['type'] == 'tool_execution' and trace['status'] == 'error':
299
+ tool_name = trace['tool_name']
300
+ error = trace.get('error', 'Unknown error')
301
+ error_type = trace.get('error_type', 'Unknown')
302
+
303
+ print(f"⚠️ {tool_name} failed with {error_type}: {error}")
304
+
305
+ # Could send to logging service, retry, etc.
306
+ # Note: If this event raises an exception, the agent stops
307
+
308
+ agent = Agent("assistant", tools=[search], on_events=[on_error(handle_tool_error)])
309
+ ```
310
+
311
+ ### Task Completion Handler (on_complete)
312
+
313
+ Use `on_complete` to run logic after the agent finishes a task:
314
+
315
+ ```python
316
+ from connectonion import Agent, on_complete
317
+
318
+ def log_completion(agent):
319
+ """Log when task completes"""
320
+ trace = agent.current_session['trace']
321
+
322
+ llm_calls = sum(1 for t in trace if t['type'] == 'llm_call')
323
+ tool_calls = sum(1 for t in trace if t['type'] == 'tool_execution')
324
+ errors = sum(1 for t in trace if t.get('status') == 'error')
325
+
326
+ print(f"✅ Task complete: {llm_calls} LLM calls, {tool_calls} tools, {errors} errors")
327
+
328
+ agent = Agent(
329
+ "assistant",
330
+ tools=[search],
331
+ on_events=[on_complete(log_completion)]
332
+ )
333
+
334
+ agent.input("Search for Python")
335
+ # ✅ Task complete: 2 LLM calls, 1 tools, 0 errors
336
+ ```
337
+
338
+ **Use cases for `on_complete`:**
339
+ - Final metrics and statistics
340
+ - Cleanup temporary resources
341
+ - Send task completion notifications
342
+ - Log total execution time
343
+ - Update external systems
344
+
345
+ ### Session Statistics
346
+
347
+ ```python
348
+ from connectonion import Agent, after_llm
349
+
350
+ def session_stats(agent):
351
+ """Print session statistics after each LLM call"""
352
+ trace = agent.current_session['trace']
353
+
354
+ llm_calls = sum(1 for t in trace if t['type'] == 'llm_call')
355
+ tool_calls = sum(1 for t in trace if t['type'] == 'tool_execution')
356
+ errors = sum(1 for t in trace if t.get('status') == 'error')
357
+
358
+ print(f"📊 Stats: {llm_calls} LLM calls | {tool_calls} tool calls | {errors} errors")
359
+
360
+ agent = Agent("assistant", tools=[search], on_events=[after_llm(session_stats)])
361
+ ```
362
+
363
+ ### Smart Tool Selection with Reflection
364
+
365
+ Help the agent think about which tool to use next:
366
+
367
+ ```python
368
+ from connectonion import Agent, after_tools, llm_do
369
+ from pydantic import BaseModel
370
+
371
+ class ToolRecommendation(BaseModel):
372
+ next_tool: str
373
+ reasoning: str
374
+ confidence: float
375
+
376
+ def suggest_next_tool(agent):
377
+ """Suggest which tool to use next based on current progress"""
378
+ trace = agent.current_session['trace'][-1]
379
+
380
+ if trace['type'] == 'tool_execution' and trace['status'] == 'success':
381
+ tool_name = trace['tool_name']
382
+ result = trace['result']
383
+
384
+ # Get list of available tools
385
+ available_tools = agent.list_tools()
386
+
387
+ suggestion_prompt = f"""
388
+ We just used: {tool_name}
389
+ Result: {result[:200]}
390
+
391
+ Available tools: {', '.join(available_tools)}
392
+
393
+ What tool should we use next and why?
394
+ """
395
+
396
+ suggestion = llm_do(
397
+ suggestion_prompt,
398
+ output=ToolRecommendation,
399
+ system_prompt="You are a strategic planner. Consider the goal and current progress.",
400
+ temperature=0.2
401
+ )
402
+
403
+ # Add suggestion as a system message (safe in after_tools)
404
+ agent.current_session['messages'].append({
405
+ 'role': 'system',
406
+ 'content': f"Suggestion: Use {suggestion.next_tool}. {suggestion.reasoning}"
407
+ })
408
+
409
+ print(f"💡 Suggested next tool: {suggestion.next_tool} (confidence: {suggestion.confidence})")
410
+
411
+ agent = Agent(
412
+ "strategist",
413
+ tools=[search, analyze, summarize],
414
+ on_events=[after_tools(suggest_next_tool)] # Use after_tools for message injection
415
+ )
416
+ ```
417
+
418
+ ---
419
+
420
+ ## Organizing Event Code
421
+
422
+ ### Keep Each Function Focused
423
+
424
+ Each helper function should do one thing:
425
+
426
+ ```python
427
+ # my_events.py
428
+
429
+ def log_llm_timing(agent):
430
+ """Single job: Log LLM timing"""
431
+ trace = agent.current_session['trace'][-1]
432
+ if trace['type'] == 'llm_call':
433
+ duration = trace['duration_ms']
434
+ print(f"💬 LLM: {duration:.0f}ms")
435
+
436
+ def log_tool_timing(agent):
437
+ """Single job: Log tool timing"""
438
+ trace = agent.current_session['trace'][-1]
439
+ if trace['type'] == 'tool_execution':
440
+ timing = trace['timing']
441
+ print(f"🔧 Tool: {timing:.0f}ms")
442
+
443
+ def add_reflection(agent):
444
+ """Single job: Add reflection after tools"""
445
+ from connectonion import llm_do
446
+
447
+ trace = agent.current_session['trace'][-1]
448
+ if trace['type'] == 'tool_execution' and trace['status'] == 'success':
449
+ reflection = llm_do(
450
+ f"Reflect on this tool result: {trace['result'][:200]}",
451
+ system_prompt="Be concise. What did we learn?",
452
+ temperature=0.3
453
+ )
454
+ agent.current_session['messages'].append({
455
+ 'role': 'assistant',
456
+ 'content': f"💭 {reflection}"
457
+ })
458
+ ```
459
+
460
+ ### Compose Into Event Handlers
461
+
462
+ Then compose them in your event handler with explicit order:
463
+
464
+ ```python
465
+ # main.py
466
+ from my_events import log_llm_timing, log_tool_timing, add_reflection
467
+ from connectonion import Agent, after_llm, after_each_tool, after_tools
468
+
469
+ def handle_after_llm(agent):
470
+ """Compose multiple concerns in explicit order"""
471
+ log_llm_timing(agent) # 1. Log timing
472
+ # Order is clear and explicit!
473
+
474
+ def handle_after_each_tool(agent):
475
+ """Handle per-tool concerns (no message injection)"""
476
+ log_tool_timing(agent) # Log timing for each tool
477
+ # Clear execution order
478
+
479
+ def handle_after_tools(agent):
480
+ """Handle batch concerns (safe for message injection)"""
481
+ add_reflection(agent) # Add reflection after all tools complete
482
+ # Safe to add messages here
483
+
484
+ agent = Agent(
485
+ "assistant",
486
+ tools=[search],
487
+ on_events=[
488
+ after_llm(handle_after_llm),
489
+ after_each_tool(handle_after_each_tool), # per-tool
490
+ after_tools(handle_after_tools) # batch
491
+ ]
492
+ )
493
+ ```
494
+
495
+ **Why this is better:**
496
+ - ✅ **Explicit order** - you see exactly what runs when
497
+ - ✅ **Single responsibility** - each function does one thing
498
+ - ✅ **Easy to test** - test each function independently
499
+ - ✅ **Easy to debug** - clear execution flow
500
+ - ✅ **Reusable** - compose functions differently for different agents
501
+
502
+ ---
503
+
504
+ ## Recommended Project Structure
505
+
506
+ For projects using events, organize your code like this:
507
+
508
+ ```
509
+ my_project/
510
+ ├── main.py # Main agent setup
511
+ ├── tools/
512
+ │ ├── __init__.py
513
+ │ ├── search.py # search() tool
514
+ │ └── calculate.py # calculate() tool
515
+ └── events/
516
+ ├── __init__.py # Export event handlers
517
+ ├── handlers.py # Main event handler functions
518
+ ├── logging.py # Logging-related helpers
519
+ └── reflection.py # Reflection helpers
520
+ ```
521
+
522
+ ### Example: `events/logging.py`
523
+
524
+ ```python
525
+ """Logging helpers - each function does one thing"""
526
+
527
+ def log_llm_call(agent):
528
+ """Log LLM call timing"""
529
+ trace = agent.current_session['trace'][-1]
530
+ if trace['type'] == 'llm_call':
531
+ duration = trace['duration_ms']
532
+ model = trace['model']
533
+ print(f"💬 {model}: {duration:.0f}ms")
534
+
535
+ def log_tool_execution(agent):
536
+ """Log tool execution details"""
537
+ trace = agent.current_session['trace'][-1]
538
+ if trace['type'] == 'tool_execution':
539
+ tool_name = trace['tool_name']
540
+ status = trace['status']
541
+ timing = trace['timing']
542
+ print(f"🔧 {tool_name}: {status} ({timing:.0f}ms)")
543
+
544
+ def log_errors(agent):
545
+ """Log tool errors"""
546
+ trace = agent.current_session['trace'][-1]
547
+ if trace['type'] == 'tool_execution' and trace['status'] == 'error':
548
+ tool_name = trace['tool_name']
549
+ error = trace['error']
550
+ print(f"❌ {tool_name}: {error}")
551
+ ```
552
+
553
+ ### Example: `events/reflection.py`
554
+
555
+ ```python
556
+ """Reflection helpers - add thinking between steps"""
557
+ from connectonion import llm_do
558
+
559
+ def add_tool_reflection(agent):
560
+ """Add reflection after each tool use"""
561
+ trace = agent.current_session['trace'][-1]
562
+
563
+ if trace['type'] == 'tool_execution' and trace['status'] == 'success':
564
+ tool_name = trace['tool_name']
565
+ result = trace['result']
566
+
567
+ # Use llm_do for quick reflection
568
+ reflection = llm_do(
569
+ f"Tool: {tool_name}\nResult: {result[:200]}\n\nWhat did we learn? What's next?",
570
+ system_prompt="You are concise and strategic.",
571
+ temperature=0.3
572
+ )
573
+
574
+ # Add to conversation
575
+ agent.current_session['messages'].append({
576
+ 'role': 'assistant',
577
+ 'content': f"💭 {reflection}"
578
+ })
579
+
580
+ def suggest_next_action(agent):
581
+ """Suggest what to do next"""
582
+ trace = agent.current_session['trace'][-1]
583
+
584
+ if trace['type'] == 'tool_execution':
585
+ available_tools = agent.list_tools()
586
+
587
+ suggestion = llm_do(
588
+ f"We just used {trace['tool_name']}. Available tools: {available_tools}. What next?",
589
+ system_prompt="Be strategic and brief.",
590
+ temperature=0.2
591
+ )
592
+
593
+ print(f"💡 Suggestion: {suggestion}")
594
+ ```
595
+
596
+ ### Example: `events/handlers.py`
597
+
598
+ ```python
599
+ """Main event handlers - compose helpers here"""
600
+ from .logging import log_llm_call, log_tool_execution, log_errors
601
+ from .reflection import add_tool_reflection
602
+
603
+ def handle_after_llm(agent):
604
+ """Handle all after_llm concerns"""
605
+ log_llm_call(agent) # 1. Log LLM calls
606
+ # Order is explicit and easy to modify
607
+
608
+ def handle_after_each_tool(agent):
609
+ """Handle per-tool concerns (no message injection)"""
610
+ log_tool_execution(agent) # Log execution timing
611
+ # Clear execution order
612
+
613
+ def handle_after_tools(agent):
614
+ """Handle batch concerns (safe for message injection)"""
615
+ add_tool_reflection(agent) # Add reflection after all tools
616
+ # Safe to add messages here
617
+
618
+ def handle_on_error(agent):
619
+ """Handle all error concerns"""
620
+ log_errors(agent) # 1. Log the error
621
+ # Could add: send_alert(agent), retry_logic(agent), etc.
622
+ ```
623
+
624
+ ### Example: `events/__init__.py`
625
+
626
+ ```python
627
+ """Export event handlers for easy import"""
628
+ from .handlers import handle_after_llm, handle_after_each_tool, handle_after_tools, handle_on_error
629
+
630
+ __all__ = ['handle_after_llm', 'handle_after_each_tool', 'handle_after_tools', 'handle_on_error']
631
+ ```
632
+
633
+ ### Example: `main.py`
634
+
635
+ ```python
636
+ """Main agent - clean and focused"""
637
+ from connectonion import Agent, after_llm, after_each_tool, after_tools, on_error
638
+ from tools import search, calculate
639
+ from events import handle_after_llm, handle_after_each_tool, handle_after_tools, handle_on_error
640
+
641
+ agent = Agent(
642
+ "assistant",
643
+ tools=[search, calculate],
644
+ on_events=[
645
+ after_llm(handle_after_llm),
646
+ after_each_tool(handle_after_each_tool), # per-tool
647
+ after_tools(handle_after_tools), # batch
648
+ on_error(handle_on_error)
649
+ ]
650
+ )
651
+
652
+ result = agent.input("Search for Python and calculate 2+2")
653
+ print(result)
654
+ ```
655
+
656
+ **Benefits of this structure:**
657
+ - 🎯 **Clear separation** - tools, events, and main logic are separate
658
+ - 🔧 **Single responsibility** - each file/function has one job
659
+ - 🧪 **Easy to test** - test each helper independently
660
+ - 📖 **Easy to read** - anyone can understand the flow
661
+ - 🔄 **Reusable** - helpers can be used across different agents
662
+ - 🏗️ **Scalable** - easy to add new event helpers
663
+
664
+ ---
665
+
666
+ ## Simple vs Complex Projects
667
+
668
+ ### For Simple Projects
669
+
670
+ Just put everything in one file:
671
+
672
+ ```python
673
+ # simple_agent.py
674
+ from connectonion import Agent, after_llm
675
+
676
+ def log_llm(agent):
677
+ trace = agent.current_session['trace'][-1]
678
+ if trace['type'] == 'llm_call':
679
+ print(f"LLM: {trace['duration_ms']:.0f}ms")
680
+
681
+ agent = Agent("assistant", tools=[search], on_events=[after_llm(log_llm)])
682
+ ```
683
+
684
+ ### For Complex Projects
685
+
686
+ Use the folder structure above when you have:
687
+ - Multiple event handlers
688
+ - Multiple concerns (logging, reflection, analytics, etc.)
689
+ - Multiple agents sharing event logic
690
+ - Need for testing and maintenance
691
+
692
+ ---
693
+
694
+ ## Error Handling
695
+
696
+ **Events fail fast.** If your event raises an exception, the agent stops immediately:
697
+
698
+ ```python
699
+ def strict_validator(agent):
700
+ trace = agent.current_session['trace'][-1]
701
+ if trace.get('status') == 'error':
702
+ raise ValueError("Tool execution failed - stopping agent")
703
+ # ☝️ This stops the entire agent
704
+
705
+ agent = Agent(
706
+ "assistant",
707
+ tools=[search],
708
+ on_events=[after_each_tool(strict_validator)] # per-tool validation
709
+ )
710
+ ```
711
+
712
+ This ensures events are reliable and bugs don't get silently ignored.
713
+
714
+ ---
715
+
716
+ ## Reusable Events
717
+
718
+ Create event factories for common patterns:
719
+
720
+ ```python
721
+ # my_events.py
722
+ from connectonion import after_llm
723
+
724
+ def llm_timer(threshold_ms=1000):
725
+ """Factory function for LLM timing alerts"""
726
+
727
+ def check_timing(agent):
728
+ trace = agent.current_session['trace'][-1]
729
+ if trace['type'] == 'llm_call':
730
+ duration = trace['duration_ms']
731
+ if duration > threshold_ms:
732
+ print(f"⚠️ Slow LLM call: {duration:.0f}ms (threshold: {threshold_ms}ms)")
733
+
734
+ return check_timing # Return the function, will be wrapped by after_llm()
735
+
736
+ # Use it:
737
+ from my_events import llm_timer
738
+ from connectonion import after_llm
739
+
740
+ agent = Agent(
741
+ "assistant",
742
+ tools=[search],
743
+ on_events=[
744
+ after_llm(llm_timer(threshold_ms=2000))
745
+ ]
746
+ )
747
+ ```
748
+
749
+ ---
750
+
751
+ ## Testing Your Events
752
+
753
+ With single-responsibility functions, testing is easy:
754
+
755
+ ```python
756
+ # tests/test_events.py
757
+ from unittest.mock import Mock
758
+ from events.logging import log_llm_call
759
+ from events.reflection import add_tool_reflection
760
+
761
+ def test_log_llm_call(capsys):
762
+ """Test LLM logging"""
763
+ mock_agent = Mock()
764
+ mock_agent.current_session = {
765
+ 'trace': [{'type': 'llm_call', 'model': 'gpt-4o-mini', 'duration_ms': 234.5}]
766
+ }
767
+
768
+ log_llm_call(mock_agent)
769
+
770
+ captured = capsys.readouterr()
771
+ assert "234ms" in captured.out
772
+
773
+ def test_add_tool_reflection():
774
+ """Test reflection adding"""
775
+ mock_agent = Mock()
776
+ mock_agent.current_session = {
777
+ 'trace': [{
778
+ 'type': 'tool_execution',
779
+ 'status': 'success',
780
+ 'tool_name': 'search',
781
+ 'result': 'Python is a programming language'
782
+ }],
783
+ 'messages': []
784
+ }
785
+
786
+ add_tool_reflection(mock_agent)
787
+
788
+ # Check that a message was added
789
+ assert len(mock_agent.current_session['messages']) == 1
790
+ assert 'assistant' in mock_agent.current_session['messages'][0]['role']
791
+ ```
792
+
793
+ ---
794
+
795
+ ## Common Use Cases
796
+
797
+ - **🧠 Reflection**: Add thinking steps between tool uses with `llm_do`
798
+ - **📝 Logging**: Custom logging to files, databases, or external services
799
+ - **🔍 Debugging**: Print detailed trace information
800
+ - **⚡ Performance**: Measure and optimize execution time
801
+ - **🛡️ Validation**: Enforce constraints on tool arguments or results
802
+ - **🔄 Retry Logic**: Automatically retry failed operations
803
+ - **📊 Analytics**: Send metrics to monitoring systems
804
+ - **🎯 Context Injection**: Add dynamic context once per turn with `after_user_input`
805
+ - **⏰ Timeouts**: Monitor and enforce time limits
806
+ - **🚨 Alerting**: Send notifications on errors or slow operations
807
+ - **💡 Strategy**: Suggest next tools or actions using `llm_do`
808
+
809
+ ---
810
+
811
+ ## What's Next?
812
+
813
+ - [llm_do](/llm_do) - Learn how to use `llm_do` for one-shot LLM calls in events
814
+ - [Examples](/examples) - See real-world event implementations
815
+ - [API Reference](/api/events) - Detailed API documentation
816
+ - [Trust System](/trust) - Learn about combining events with trust