connectonion 0.6.1__py3-none-any.whl → 0.6.3__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 (413) 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 +95 -142
  5. connectonion/cli/browser_agent/element_finder.py +147 -0
  6. connectonion/cli/browser_agent/highlight_screenshot.py +182 -0
  7. connectonion/cli/browser_agent/prompt.md +188 -105
  8. connectonion/cli/browser_agent/prompts/element_matcher.md +59 -0
  9. connectonion/cli/browser_agent/prompts/form_filler.md +19 -0
  10. connectonion/cli/browser_agent/prompts/scroll_strategy.md +36 -0
  11. connectonion/cli/browser_agent/scripts/extract_elements.js +126 -0
  12. connectonion/cli/browser_agent/scroll.py +145 -0
  13. connectonion/cli/co_ai/__init__.py +6 -0
  14. connectonion/cli/co_ai/agent.py +87 -0
  15. connectonion/cli/co_ai/agents/__init__.py +5 -0
  16. connectonion/cli/co_ai/agents/registry.py +57 -0
  17. connectonion/cli/co_ai/commands/__init__.py +45 -0
  18. connectonion/cli/co_ai/commands/compact.py +173 -0
  19. connectonion/cli/co_ai/commands/cost.py +77 -0
  20. connectonion/cli/co_ai/commands/export.py +60 -0
  21. connectonion/cli/co_ai/commands/help.py +80 -0
  22. connectonion/cli/co_ai/commands/init.py +101 -0
  23. connectonion/cli/co_ai/commands/sessions.py +55 -0
  24. connectonion/cli/co_ai/commands/tasks.py +63 -0
  25. connectonion/cli/co_ai/commands/undo.py +103 -0
  26. connectonion/cli/co_ai/context.py +127 -0
  27. connectonion/cli/co_ai/main.py +52 -0
  28. connectonion/cli/co_ai/plugins/__init__.py +6 -0
  29. connectonion/cli/co_ai/plugins/reminder.py +76 -0
  30. connectonion/cli/co_ai/plugins/shell_approval.py +105 -0
  31. connectonion/cli/co_ai/prompts/agents/explore.md +79 -0
  32. connectonion/cli/co_ai/prompts/agents/plan.md +60 -0
  33. connectonion/cli/co_ai/prompts/assembler.py +303 -0
  34. connectonion/cli/{docs/co-vibecoding-principles-docs-contexts-all-in-one.md → co_ai/prompts/connectonion/README.md} +26 -0
  35. connectonion/cli/co_ai/prompts/connectonion/api.md +457 -0
  36. connectonion/cli/co_ai/prompts/connectonion/cli/README.md +805 -0
  37. connectonion/cli/co_ai/prompts/connectonion/cli/auth.md +46 -0
  38. connectonion/cli/co_ai/prompts/connectonion/cli/browser.md +235 -0
  39. connectonion/cli/co_ai/prompts/connectonion/cli/copy.md +184 -0
  40. connectonion/cli/co_ai/prompts/connectonion/cli/create.md +335 -0
  41. connectonion/cli/co_ai/prompts/connectonion/cli/init.md +431 -0
  42. connectonion/cli/co_ai/prompts/connectonion/co-directory-structure.md +214 -0
  43. connectonion/cli/co_ai/prompts/connectonion/concepts/agent.md +1078 -0
  44. connectonion/cli/co_ai/prompts/connectonion/concepts/events.md +816 -0
  45. connectonion/cli/co_ai/prompts/connectonion/concepts/llm_do.md +256 -0
  46. connectonion/cli/co_ai/prompts/connectonion/concepts/max_iterations.md +362 -0
  47. connectonion/cli/co_ai/prompts/connectonion/concepts/models.md +641 -0
  48. connectonion/cli/co_ai/prompts/connectonion/concepts/plugins.md +100 -0
  49. connectonion/cli/co_ai/prompts/connectonion/concepts/prompts.md +122 -0
  50. connectonion/cli/co_ai/prompts/connectonion/concepts/tools.md +512 -0
  51. connectonion/cli/co_ai/prompts/connectonion/concepts/transcribe.md +156 -0
  52. connectonion/cli/co_ai/prompts/connectonion/concepts/trust.md +291 -0
  53. connectonion/cli/co_ai/prompts/connectonion/debug/README.md +18 -0
  54. connectonion/cli/co_ai/prompts/connectonion/debug/auto_debug.md +1026 -0
  55. connectonion/cli/co_ai/prompts/connectonion/debug/console.md +129 -0
  56. connectonion/cli/co_ai/prompts/connectonion/debug/eval-format.md +178 -0
  57. connectonion/cli/co_ai/prompts/connectonion/debug/eval.md +230 -0
  58. connectonion/cli/co_ai/prompts/connectonion/debug/exceptions.md +307 -0
  59. connectonion/cli/co_ai/prompts/connectonion/debug/log.md +117 -0
  60. connectonion/cli/co_ai/prompts/connectonion/debug/xray.md +215 -0
  61. connectonion/cli/co_ai/prompts/connectonion/design-decisions/001-choosing-input-method.md +202 -0
  62. connectonion/cli/co_ai/prompts/connectonion/design-decisions/002-choosing-llm-function-name.md +202 -0
  63. connectonion/cli/co_ai/prompts/connectonion/design-decisions/003-choosing-trust-keyword.md +141 -0
  64. connectonion/cli/co_ai/prompts/connectonion/design-decisions/004-cli-create-flow.md +117 -0
  65. connectonion/cli/co_ai/prompts/connectonion/design-decisions/005-designing-agent-network-protocol.md +503 -0
  66. connectonion/cli/co_ai/prompts/connectonion/design-decisions/006-agent-address-format.md +305 -0
  67. connectonion/cli/co_ai/prompts/connectonion/design-decisions/007-authentication-backend-design.md +240 -0
  68. connectonion/cli/co_ai/prompts/connectonion/design-decisions/008-naming-is-hard.md +228 -0
  69. connectonion/cli/co_ai/prompts/connectonion/design-decisions/009-why-connect-function.md +167 -0
  70. connectonion/cli/co_ai/prompts/connectonion/design-decisions/010-cli-ux-progressive-disclosure.md +176 -0
  71. connectonion/cli/co_ai/prompts/connectonion/design-decisions/011-global-config-identity-management.md +357 -0
  72. connectonion/cli/co_ai/prompts/connectonion/design-decisions/012-tool-execution-separation.md +259 -0
  73. connectonion/cli/co_ai/prompts/connectonion/design-decisions/013-debug-and-logging-design.md +253 -0
  74. connectonion/cli/co_ai/prompts/connectonion/design-decisions/014-hook-system-design.md +510 -0
  75. connectonion/cli/co_ai/prompts/connectonion/design-decisions/015-interactive-auto-debug-design.md +837 -0
  76. connectonion/cli/co_ai/prompts/connectonion/design-decisions/016-why-no-zero-knowledge-proofs.md +358 -0
  77. connectonion/cli/co_ai/prompts/connectonion/design-decisions/017-session-logging-and-eval-format.md +120 -0
  78. connectonion/cli/co_ai/prompts/connectonion/design-decisions/018-event-api-naming.md +274 -0
  79. connectonion/cli/co_ai/prompts/connectonion/design-decisions/019-agent-lifecycle-design.md +655 -0
  80. connectonion/cli/co_ai/prompts/connectonion/design-decisions/020-trust-system-and-network-architecture.md +503 -0
  81. connectonion/cli/co_ai/prompts/connectonion/design-decisions/021-task-storage-jsonl-design.md +496 -0
  82. connectonion/cli/co_ai/prompts/connectonion/design-decisions/022-raw-asgi-implementation.md +273 -0
  83. connectonion/cli/co_ai/prompts/connectonion/examples/agent_reasoning.md +62 -0
  84. connectonion/cli/co_ai/prompts/connectonion/examples/atomic_tools.md +24 -0
  85. connectonion/cli/co_ai/prompts/connectonion/examples/load_guide.md +18 -0
  86. connectonion/cli/co_ai/prompts/connectonion/examples.md +0 -0
  87. connectonion/cli/co_ai/prompts/connectonion/hook-system-options.md +364 -0
  88. connectonion/cli/co_ai/prompts/connectonion/index.md +162 -0
  89. connectonion/cli/co_ai/prompts/connectonion/integrations/README.md +12 -0
  90. connectonion/cli/co_ai/prompts/connectonion/integrations/auth.md +450 -0
  91. connectonion/cli/co_ai/prompts/connectonion/integrations/google.md +431 -0
  92. connectonion/cli/co_ai/prompts/connectonion/integrations/microsoft.md +370 -0
  93. connectonion/cli/co_ai/prompts/connectonion/network/README.md +14 -0
  94. connectonion/cli/co_ai/prompts/connectonion/network/connect.md +543 -0
  95. connectonion/cli/co_ai/prompts/connectonion/network/connection.md +538 -0
  96. connectonion/cli/co_ai/prompts/connectonion/network/deploy.md +123 -0
  97. connectonion/cli/co_ai/prompts/connectonion/network/host.md +1049 -0
  98. connectonion/cli/co_ai/prompts/connectonion/network/protocol/agent-relay-protocol.md +495 -0
  99. connectonion/cli/co_ai/prompts/connectonion/network/protocol/announce-message.md +115 -0
  100. connectonion/cli/co_ai/prompts/connectonion/principles.md +124 -0
  101. connectonion/cli/co_ai/prompts/connectonion/quickstart.md +261 -0
  102. connectonion/cli/co_ai/prompts/connectonion/roadmap.md +81 -0
  103. connectonion/cli/co_ai/prompts/connectonion/templates/README.md +77 -0
  104. connectonion/cli/co_ai/prompts/connectonion/templates/meta-agent.md +152 -0
  105. connectonion/cli/co_ai/prompts/connectonion/templates/minimal.md +105 -0
  106. connectonion/cli/co_ai/prompts/connectonion/templates/playwright.md +130 -0
  107. connectonion/cli/co_ai/prompts/connectonion/templates/web-research.md +144 -0
  108. connectonion/cli/co_ai/prompts/connectonion/tui/README.md +95 -0
  109. connectonion/cli/co_ai/prompts/connectonion/tui/chat.md +181 -0
  110. connectonion/cli/co_ai/prompts/connectonion/tui/divider.md +63 -0
  111. connectonion/cli/co_ai/prompts/connectonion/tui/dropdown.md +83 -0
  112. connectonion/cli/co_ai/prompts/connectonion/tui/footer.md +44 -0
  113. connectonion/cli/co_ai/prompts/connectonion/tui/fuzzy.md +68 -0
  114. connectonion/cli/co_ai/prompts/connectonion/tui/input.md +84 -0
  115. connectonion/cli/co_ai/prompts/connectonion/tui/keys.md +77 -0
  116. connectonion/cli/co_ai/prompts/connectonion/tui/pick.md +71 -0
  117. connectonion/cli/co_ai/prompts/connectonion/tui/providers.md +89 -0
  118. connectonion/cli/co_ai/prompts/connectonion/tui/status_bar.md +67 -0
  119. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/README.md +156 -0
  120. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/calendar_plugin.md +68 -0
  121. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/eval.md +89 -0
  122. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/gmail_plugin.md +68 -0
  123. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/image_result_formatter.md +74 -0
  124. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/re_act.md +86 -0
  125. connectonion/cli/co_ai/prompts/connectonion/useful_plugins/shell_approval.md +69 -0
  126. connectonion/cli/co_ai/prompts/connectonion/useful_tools/README.md +81 -0
  127. connectonion/cli/co_ai/prompts/connectonion/useful_tools/diff_writer.md +138 -0
  128. connectonion/cli/co_ai/prompts/connectonion/useful_tools/get_emails.md +499 -0
  129. connectonion/cli/co_ai/prompts/connectonion/useful_tools/gmail.md +135 -0
  130. connectonion/cli/co_ai/prompts/connectonion/useful_tools/google_calendar.md +106 -0
  131. connectonion/cli/co_ai/prompts/connectonion/useful_tools/memory.md +486 -0
  132. connectonion/cli/co_ai/prompts/connectonion/useful_tools/microsoft_calendar.md +106 -0
  133. connectonion/cli/co_ai/prompts/connectonion/useful_tools/outlook.md +120 -0
  134. connectonion/cli/co_ai/prompts/connectonion/useful_tools/send_email.md +403 -0
  135. connectonion/cli/co_ai/prompts/connectonion/useful_tools/shell.md +95 -0
  136. connectonion/cli/co_ai/prompts/connectonion/useful_tools/slash_command.md +96 -0
  137. connectonion/cli/co_ai/prompts/connectonion/useful_tools/terminal.md +97 -0
  138. connectonion/cli/co_ai/prompts/connectonion/useful_tools/todo_list.md +252 -0
  139. connectonion/cli/co_ai/prompts/connectonion/useful_tools/web_fetch.md +130 -0
  140. connectonion/cli/co_ai/prompts/connectonion/vibe-coding-guide.md +97 -0
  141. connectonion/cli/co_ai/prompts/connectonion/windows-support.md +258 -0
  142. connectonion/cli/co_ai/prompts/main.md +247 -0
  143. connectonion/cli/co_ai/prompts/reminders/plan_mode.md +34 -0
  144. connectonion/cli/co_ai/prompts/summarization.md +55 -0
  145. connectonion/cli/co_ai/prompts/tools/ask_user.md +61 -0
  146. connectonion/cli/co_ai/prompts/tools/background.md +57 -0
  147. connectonion/cli/co_ai/prompts/tools/edit.md +90 -0
  148. connectonion/cli/co_ai/prompts/tools/glob.md +52 -0
  149. connectonion/cli/co_ai/prompts/tools/grep.md +55 -0
  150. connectonion/cli/co_ai/prompts/tools/plan_mode.md +80 -0
  151. connectonion/cli/co_ai/prompts/tools/read.md +40 -0
  152. connectonion/cli/co_ai/prompts/tools/shell.md +67 -0
  153. connectonion/cli/co_ai/prompts/tools/task.md +51 -0
  154. connectonion/cli/co_ai/prompts/tools/todo.md +139 -0
  155. connectonion/cli/co_ai/prompts/tools/write.md +47 -0
  156. connectonion/cli/co_ai/prompts/workflow.md +89 -0
  157. connectonion/cli/co_ai/reminders.py +159 -0
  158. connectonion/cli/co_ai/sessions.py +110 -0
  159. connectonion/cli/co_ai/skills/__init__.py +37 -0
  160. connectonion/cli/co_ai/skills/builtin/commit/SKILL.md +63 -0
  161. connectonion/cli/co_ai/skills/builtin/review-pr/SKILL.md +76 -0
  162. connectonion/cli/co_ai/skills/loader.py +166 -0
  163. connectonion/cli/co_ai/skills/tool.py +46 -0
  164. connectonion/cli/co_ai/tools/__init__.py +92 -0
  165. connectonion/cli/co_ai/tools/ask_user.py +35 -0
  166. connectonion/cli/co_ai/tools/background.py +201 -0
  167. connectonion/cli/co_ai/tools/diff_writer.py +291 -0
  168. connectonion/cli/co_ai/tools/edit.py +89 -0
  169. connectonion/cli/co_ai/tools/glob.py +84 -0
  170. connectonion/cli/co_ai/tools/grep.py +158 -0
  171. connectonion/cli/co_ai/tools/load_guide.py +23 -0
  172. connectonion/cli/co_ai/tools/multi_edit.py +116 -0
  173. connectonion/cli/co_ai/tools/plan_mode.py +172 -0
  174. connectonion/cli/co_ai/tools/read.py +67 -0
  175. connectonion/cli/co_ai/tools/task.py +59 -0
  176. connectonion/cli/co_ai/tools/todo_list.py +159 -0
  177. connectonion/cli/co_ai/tools/write.py +126 -0
  178. connectonion/cli/commands/__init__.py +11 -1
  179. connectonion/cli/commands/ai_commands.py +34 -0
  180. connectonion/cli/commands/copy_commands.py +55 -6
  181. connectonion/cli/commands/create.py +20 -17
  182. connectonion/cli/commands/init.py +19 -22
  183. connectonion/cli/commands/project_cmd_lib.py +15 -0
  184. connectonion/cli/main.py +11 -0
  185. connectonion/console.py +15 -1
  186. connectonion/core/__init__.py +10 -1
  187. connectonion/core/agent.py +37 -16
  188. connectonion/core/exceptions.py +74 -0
  189. connectonion/core/llm.py +54 -6
  190. connectonion/core/tool_executor.py +32 -31
  191. connectonion/core/tool_factory.py +47 -10
  192. connectonion/debug/__init__.py +10 -1
  193. connectonion/debug/debug_explainer/__init__.py +10 -1
  194. connectonion/debug/execution_analyzer/__init__.py +10 -1
  195. connectonion/debug/execution_analyzer/execution_analysis.py +5 -2
  196. connectonion/debug/runtime_inspector/__init__.py +10 -1
  197. connectonion/docs/.package-ignore +6 -0
  198. connectonion/docs/README.md +2036 -0
  199. connectonion/docs/api.md +457 -0
  200. connectonion/docs/archive/001-ai-agent-is-just-prompt-plus-function.md +249 -0
  201. connectonion/docs/archive/README.md +53 -0
  202. connectonion/docs/archive/archive/consolidation-plan.md +72 -0
  203. connectonion/docs/archive/archive/core-principles-extracted.md +239 -0
  204. connectonion/docs/archive/archive/master-principles.md +222 -0
  205. connectonion/docs/archive/archive/principles.md +293 -0
  206. connectonion/docs/archive/archive/simplicity-principles.md +221 -0
  207. connectonion/docs/archive/attack-defense-insights.md +410 -0
  208. connectonion/docs/archive/business-model.md +305 -0
  209. connectonion/docs/archive/core-principles-unified.md +190 -0
  210. connectonion/docs/archive/discussion-journey.md +178 -0
  211. connectonion/docs/archive/economic-analysis.md +323 -0
  212. connectonion/docs/archive/features/01-share-and-find.md +256 -0
  213. connectonion/docs/archive/features/02-agent-authentication.md +93 -0
  214. connectonion/docs/archive/features/03-test-before-trust.md +71 -0
  215. connectonion/docs/archive/features/06-reliability-and-offline.md +197 -0
  216. connectonion/docs/archive/features/README.md +46 -0
  217. connectonion/docs/archive/features-roadmap.md +247 -0
  218. connectonion/docs/archive/mcp-comparison-insights.md +215 -0
  219. connectonion/docs/archive/migration-strategy.md +571 -0
  220. connectonion/docs/archive/mini-whitepaper.md +293 -0
  221. connectonion/docs/archive/network-protocol.md +394 -0
  222. connectonion/docs/archive/semantic-revolution.md +367 -0
  223. connectonion/docs/archive/technical-architecture.md +453 -0
  224. connectonion/docs/archive/the-semantic-insight.md +207 -0
  225. connectonion/docs/archive/threat-model.md +164 -0
  226. connectonion/docs/cli/README.md +805 -0
  227. connectonion/docs/cli/auth.md +46 -0
  228. connectonion/docs/cli/browser.md +235 -0
  229. connectonion/docs/cli/copy.md +232 -0
  230. connectonion/docs/cli/create.md +335 -0
  231. connectonion/docs/cli/init.md +431 -0
  232. connectonion/docs/co-directory-structure.md +214 -0
  233. connectonion/docs/concepts/agent.md +1078 -0
  234. connectonion/docs/concepts/events.md +699 -0
  235. connectonion/docs/concepts/llm_do.md +256 -0
  236. connectonion/docs/concepts/max_iterations.md +362 -0
  237. connectonion/docs/concepts/models.md +641 -0
  238. connectonion/docs/concepts/plugins.md +100 -0
  239. connectonion/docs/concepts/prompts.md +122 -0
  240. connectonion/docs/concepts/session.md +428 -0
  241. connectonion/docs/concepts/tools.md +512 -0
  242. connectonion/docs/concepts/transcribe.md +156 -0
  243. connectonion/docs/concepts/trust.md +291 -0
  244. connectonion/docs/connectonion.md +1256 -0
  245. connectonion/docs/debug/README.md +18 -0
  246. connectonion/docs/debug/auto_debug.md +1026 -0
  247. connectonion/docs/debug/console.md +129 -0
  248. connectonion/docs/debug/eval-format.md +178 -0
  249. connectonion/docs/debug/eval.md +230 -0
  250. connectonion/docs/debug/exceptions.md +307 -0
  251. connectonion/docs/debug/log.md +117 -0
  252. connectonion/docs/debug/xray.md +215 -0
  253. connectonion/docs/design-decisions/001-choosing-input-method.md +202 -0
  254. connectonion/docs/design-decisions/002-choosing-llm-function-name.md +202 -0
  255. connectonion/docs/design-decisions/003-choosing-trust-keyword.md +141 -0
  256. connectonion/docs/design-decisions/004-cli-create-flow.md +117 -0
  257. connectonion/docs/design-decisions/005-designing-agent-network-protocol.md +503 -0
  258. connectonion/docs/design-decisions/006-agent-address-format.md +305 -0
  259. connectonion/docs/design-decisions/007-authentication-backend-design.md +240 -0
  260. connectonion/docs/design-decisions/008-naming-is-hard.md +228 -0
  261. connectonion/docs/design-decisions/009-why-connect-function.md +167 -0
  262. connectonion/docs/design-decisions/010-cli-ux-progressive-disclosure.md +176 -0
  263. connectonion/docs/design-decisions/011-global-config-identity-management.md +357 -0
  264. connectonion/docs/design-decisions/012-tool-execution-separation.md +259 -0
  265. connectonion/docs/design-decisions/013-debug-and-logging-design.md +253 -0
  266. connectonion/docs/design-decisions/014-hook-system-design.md +510 -0
  267. connectonion/docs/design-decisions/015-interactive-auto-debug-design.md +837 -0
  268. connectonion/docs/design-decisions/016-why-no-zero-knowledge-proofs.md +358 -0
  269. connectonion/docs/design-decisions/017-session-logging-and-eval-format.md +120 -0
  270. connectonion/docs/design-decisions/018-event-api-naming.md +274 -0
  271. connectonion/docs/design-decisions/019-agent-lifecycle-design.md +655 -0
  272. connectonion/docs/design-decisions/020-trust-system-and-network-architecture.md +503 -0
  273. connectonion/docs/design-decisions/021-task-storage-jsonl-design.md +496 -0
  274. connectonion/docs/design-decisions/022-raw-asgi-implementation.md +273 -0
  275. connectonion/docs/examples.md +0 -0
  276. connectonion/docs/hook-system-options.md +364 -0
  277. connectonion/docs/integrations/README.md +12 -0
  278. connectonion/docs/integrations/auth.md +450 -0
  279. connectonion/docs/integrations/google.md +431 -0
  280. connectonion/docs/integrations/microsoft.md +370 -0
  281. connectonion/docs/network/README.md +14 -0
  282. connectonion/docs/network/connect.md +629 -0
  283. connectonion/docs/network/deploy.md +124 -0
  284. connectonion/docs/network/host.md +1087 -0
  285. connectonion/docs/network/io.md +538 -0
  286. connectonion/docs/network/protocol/agent-relay-protocol.md +495 -0
  287. connectonion/docs/network/protocol/announce-message.md +115 -0
  288. connectonion/docs/principles.md +124 -0
  289. connectonion/docs/quickstart.md +261 -0
  290. connectonion/docs/roadmap.md +81 -0
  291. connectonion/docs/templates/README.md +77 -0
  292. connectonion/docs/templates/meta-agent.md +152 -0
  293. connectonion/docs/templates/minimal.md +105 -0
  294. connectonion/docs/templates/playwright.md +130 -0
  295. connectonion/docs/templates/web-research.md +144 -0
  296. connectonion/docs/tui/README.md +95 -0
  297. connectonion/docs/tui/chat.md +181 -0
  298. connectonion/docs/tui/divider.md +63 -0
  299. connectonion/docs/tui/dropdown.md +83 -0
  300. connectonion/docs/tui/footer.md +44 -0
  301. connectonion/docs/tui/fuzzy.md +68 -0
  302. connectonion/docs/tui/input.md +84 -0
  303. connectonion/docs/tui/keys.md +77 -0
  304. connectonion/docs/tui/pick.md +71 -0
  305. connectonion/docs/tui/providers.md +89 -0
  306. connectonion/docs/tui/status_bar.md +67 -0
  307. connectonion/docs/useful_plugins/README.md +160 -0
  308. connectonion/docs/useful_plugins/calendar_plugin.md +68 -0
  309. connectonion/docs/useful_plugins/eval.md +89 -0
  310. connectonion/docs/useful_plugins/gmail_plugin.md +68 -0
  311. connectonion/docs/useful_plugins/image_result_formatter.md +74 -0
  312. connectonion/docs/useful_plugins/re_act.md +86 -0
  313. connectonion/docs/useful_plugins/shell_approval.md +69 -0
  314. connectonion/docs/useful_plugins/system_reminder.md +210 -0
  315. connectonion/docs/useful_prompts/README.md +127 -0
  316. connectonion/docs/useful_prompts/coding_agent.md +214 -0
  317. connectonion/docs/useful_tools/README.md +81 -0
  318. connectonion/docs/useful_tools/ask_user.md +103 -0
  319. connectonion/docs/useful_tools/diff_writer.md +158 -0
  320. connectonion/docs/useful_tools/get_emails.md +519 -0
  321. connectonion/docs/useful_tools/gmail.md +155 -0
  322. connectonion/docs/useful_tools/google_calendar.md +126 -0
  323. connectonion/docs/useful_tools/memory.md +506 -0
  324. connectonion/docs/useful_tools/microsoft_calendar.md +126 -0
  325. connectonion/docs/useful_tools/outlook.md +140 -0
  326. connectonion/docs/useful_tools/send_email.md +423 -0
  327. connectonion/docs/useful_tools/shell.md +115 -0
  328. connectonion/docs/useful_tools/slash_command.md +116 -0
  329. connectonion/docs/useful_tools/terminal.md +115 -0
  330. connectonion/docs/useful_tools/todo_list.md +272 -0
  331. connectonion/docs/useful_tools/web_fetch.md +150 -0
  332. connectonion/docs/vibe-coding-guide.md +97 -0
  333. connectonion/docs/windows-support.md +258 -0
  334. connectonion/logger.py +3 -3
  335. connectonion/network/__init__.py +19 -6
  336. connectonion/network/asgi/__init__.py +81 -0
  337. connectonion/network/asgi/http.py +205 -0
  338. connectonion/network/asgi/websocket.py +217 -0
  339. connectonion/network/connect.py +232 -185
  340. connectonion/network/host/__init__.py +59 -0
  341. connectonion/network/host/auth.py +191 -0
  342. connectonion/network/host/routes.py +135 -0
  343. connectonion/network/host/server.py +289 -0
  344. connectonion/network/host/session.py +78 -0
  345. connectonion/network/io/__init__.py +21 -0
  346. connectonion/network/{connection.py → io/base.py} +17 -42
  347. connectonion/network/io/websocket.py +55 -0
  348. connectonion/network/relay.py +37 -16
  349. connectonion/network/trust/__init__.py +30 -0
  350. connectonion/network/trust/factory.py +138 -0
  351. connectonion/network/{trust_agents.py → trust/prompts.py} +3 -3
  352. connectonion/network/{trust_functions.py → trust/tools.py} +2 -2
  353. connectonion/prompt_files/__init__.py +11 -1
  354. connectonion/prompt_files/react_acknowledge.md +26 -0
  355. connectonion/prompts.py +10 -1
  356. connectonion/tui/chat.py +10 -1
  357. connectonion/tui/divider.py +10 -1
  358. connectonion/tui/dropdown.py +10 -1
  359. connectonion/tui/footer.py +8 -0
  360. connectonion/tui/fuzzy.py +11 -1
  361. connectonion/tui/input.py +118 -70
  362. connectonion/tui/keys.py +133 -6
  363. connectonion/tui/providers.py +11 -1
  364. connectonion/tui/status_bar.py +10 -1
  365. connectonion/useful_events_handlers/__init__.py +8 -0
  366. connectonion/useful_events_handlers/reflect.py +19 -4
  367. connectonion/useful_plugins/__init__.py +2 -1
  368. connectonion/useful_plugins/eval.py +2 -2
  369. connectonion/useful_plugins/gmail_plugin.py +3 -3
  370. connectonion/useful_plugins/image_result_formatter.py +3 -3
  371. connectonion/useful_plugins/re_act.py +114 -28
  372. connectonion/useful_plugins/shell_approval.py +2 -2
  373. connectonion/useful_plugins/system_reminder.py +103 -0
  374. connectonion/useful_plugins/ui_stream.py +18 -133
  375. connectonion/useful_prompts/README.md +61 -0
  376. connectonion/useful_prompts/__init__.py +45 -0
  377. connectonion/useful_prompts/coding_agent/README.md +106 -0
  378. connectonion/useful_prompts/coding_agent/assembler.py +123 -0
  379. connectonion/useful_prompts/coding_agent/prompts/main.md +227 -0
  380. connectonion/useful_prompts/coding_agent/prompts/tools/ask_user.md +61 -0
  381. connectonion/useful_prompts/coding_agent/prompts/tools/background.md +57 -0
  382. connectonion/useful_prompts/coding_agent/prompts/tools/edit.md +90 -0
  383. connectonion/useful_prompts/coding_agent/prompts/tools/glob.md +52 -0
  384. connectonion/useful_prompts/coding_agent/prompts/tools/grep.md +55 -0
  385. connectonion/useful_prompts/coding_agent/prompts/tools/plan_mode.md +80 -0
  386. connectonion/useful_prompts/coding_agent/prompts/tools/read.md +40 -0
  387. connectonion/useful_prompts/coding_agent/prompts/tools/shell.md +67 -0
  388. connectonion/useful_prompts/coding_agent/prompts/tools/task.md +51 -0
  389. connectonion/useful_prompts/coding_agent/prompts/tools/todo.md +139 -0
  390. connectonion/useful_prompts/coding_agent/prompts/tools/write.md +48 -0
  391. connectonion/useful_prompts/system-reminders/security-warning.md +14 -0
  392. connectonion/useful_prompts/system-reminders/test-reminder.md +11 -0
  393. connectonion/useful_tools/__init__.py +31 -4
  394. connectonion/useful_tools/ask_user.py +35 -0
  395. connectonion/useful_tools/bash.py +69 -0
  396. connectonion/useful_tools/diff_writer.py +186 -94
  397. connectonion/useful_tools/edit.py +102 -0
  398. connectonion/useful_tools/glob_files.py +97 -0
  399. connectonion/useful_tools/grep_files.py +171 -0
  400. connectonion/useful_tools/multi_edit.py +116 -0
  401. connectonion/useful_tools/read_file.py +73 -0
  402. connectonion/useful_tools/shell.py +50 -45
  403. connectonion/useful_tools/write_file.py +129 -0
  404. {connectonion-0.6.1.dist-info → connectonion-0.6.3.dist-info}/METADATA +10 -3
  405. connectonion-0.6.3.dist-info/RECORD +469 -0
  406. connectonion/cli/browser_agent/scroll_strategies.py +0 -276
  407. connectonion/network/asgi.py +0 -407
  408. connectonion/network/host.py +0 -616
  409. connectonion/network/trust.py +0 -166
  410. connectonion-0.6.1.dist-info/RECORD +0 -123
  411. /connectonion/cli/{docs → co_ai/prompts/connectonion}/connectonion.md +0 -0
  412. {connectonion-0.6.1.dist-info → connectonion-0.6.3.dist-info}/WHEEL +0 -0
  413. {connectonion-0.6.1.dist-info → connectonion-0.6.3.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,52 @@
1
+ """AI coding agent web server entry point."""
2
+
3
+ import logging
4
+ from pathlib import Path
5
+ from dotenv import load_dotenv
6
+ from connectonion import host
7
+
8
+ logging.basicConfig(
9
+ level=logging.WARNING,
10
+ format='[%(levelname)s] %(name)s: %(message)s'
11
+ )
12
+
13
+
14
+ # Load global keys.env for CLI commands (fallback for API keys)
15
+ # Priority: current directory .env > global ~/.co/keys.env
16
+ _global_keys = Path.home() / ".co" / "keys.env"
17
+ if _global_keys.exists():
18
+ # load_dotenv doesn't override existing env vars, so cwd .env takes priority
19
+ load_dotenv(_global_keys)
20
+
21
+
22
+ def start_server(
23
+ port: int = 8000,
24
+ model: str = "co/claude-opus-4-5",
25
+ max_iterations: int = 20,
26
+ ):
27
+ """Start AI coding agent web server.
28
+
29
+ Args:
30
+ port: Port to run server on
31
+ model: LLM model to use
32
+ max_iterations: Max tool iterations
33
+
34
+ The server will be accessible at:
35
+ - POST http://localhost:{port}/input
36
+ - WS ws://localhost:{port}/ws
37
+ - GET http://localhost:{port}/health
38
+ - GET http://localhost:{port}/info
39
+ """
40
+ from .agent import create_coding_agent
41
+
42
+ def agent_factory():
43
+ return create_coding_agent(
44
+ model=model,
45
+ max_iterations=max_iterations,
46
+ auto_approve=True, # Always auto-approve in web mode
47
+ web_mode=True,
48
+ )
49
+
50
+ # Start server with open trust (no auth required)
51
+ # relay_url=None disables P2P discovery
52
+ host(agent_factory, port=port, trust="open", relay_url=None)
@@ -0,0 +1,6 @@
1
+ """OO Agent plugins."""
2
+
3
+ from .shell_approval import shell_approval
4
+ from .reminder import reminder_plugin
5
+
6
+ __all__ = ['shell_approval', 'reminder_plugin']
@@ -0,0 +1,76 @@
1
+ """
2
+ Reminder plugin - injects contextual reminders into tool results.
3
+
4
+ Like Claude Code's system reminders, these are appended to tool results
5
+ (not separate messages) to guide agent behavior without extra API calls.
6
+
7
+ Usage:
8
+ from connectonion.cli.co_ai.plugins.reminder import reminder_plugin
9
+
10
+ agent = Agent("coder", plugins=[reminder_plugin])
11
+ """
12
+
13
+ from connectonion.core.events import after_each_tool
14
+ from ..reminders import REMINDERS, should_show_security_reminder
15
+
16
+
17
+ def _get_reminder_for_tool(tool_name: str, args: dict, result: str) -> str | None:
18
+ """Determine which reminder to inject based on tool and context."""
19
+
20
+ # write_file with .py extension → remind about ConnectOnion pattern
21
+ if tool_name == "write_file":
22
+ path = args.get("path", "") or args.get("file_path", "")
23
+ if path.endswith(".py"):
24
+ return "connectonion_workflow"
25
+
26
+ # read_file with sensitive path → security reminder
27
+ if tool_name in ("read_file", "read"):
28
+ path = args.get("path", "") or args.get("file_path", "")
29
+ if should_show_security_reminder(path):
30
+ return "security"
31
+
32
+ # bash/shell commands that modify code
33
+ if tool_name in ("bash", "shell", "run_command"):
34
+ cmd = args.get("command", "") or args.get("cmd", "")
35
+ # If creating/editing Python files
36
+ if any(x in cmd for x in [">.py", ">> .py", "cat >", "echo >", "sed -i"]):
37
+ return "connectonion_workflow"
38
+
39
+ return None
40
+
41
+
42
+ def inject_reminder_handler(agent):
43
+ """Inject contextual reminders into tool results.
44
+
45
+ This handler runs after each tool execution and modifies the
46
+ tool result message to include relevant reminders.
47
+ """
48
+ trace = agent.current_session.get('trace', [])
49
+ messages = agent.current_session.get('messages', [])
50
+
51
+ if not trace or not messages:
52
+ return
53
+
54
+ # Get the most recent tool execution
55
+ last_trace = trace[-1]
56
+ if last_trace.get('type') != 'tool_result':
57
+ return
58
+
59
+ tool_name = last_trace.get('name', '')
60
+ tool_args = last_trace.get('args', {})
61
+ result = last_trace.get('result', '')
62
+
63
+ # Determine which reminder to inject
64
+ reminder_key = _get_reminder_for_tool(tool_name, tool_args, result)
65
+ if not reminder_key or reminder_key not in REMINDERS:
66
+ return
67
+
68
+ # Find and modify the last tool result message
69
+ for msg in reversed(messages):
70
+ if msg.get('role') == 'tool':
71
+ msg['content'] = msg.get('content', '') + '\n\n' + REMINDERS[reminder_key]
72
+ break
73
+
74
+
75
+ # Export the plugin
76
+ reminder_plugin = [after_each_tool(inject_reminder_handler)]
@@ -0,0 +1,105 @@
1
+ """Shell Approval plugin - Asks user approval for shell commands."""
2
+
3
+ import re
4
+ from typing import TYPE_CHECKING
5
+ from connectonion.core.events import before_each_tool
6
+
7
+ if TYPE_CHECKING:
8
+ from connectonion.core.agent import Agent
9
+
10
+ SAFE_PATTERNS = [
11
+ r'^ls\b', r'^ll\b', r'^cat\b', r'^head\b', r'^tail\b', r'^less\b', r'^more\b',
12
+ r'^grep\b', r'^rg\b', r'^find\b', r'^fd\b', r'^which\b', r'^whereis\b',
13
+ r'^type\b', r'^file\b', r'^stat\b', r'^wc\b', r'^pwd\b', r'^echo\b',
14
+ r'^printf\b', r'^date\b', r'^whoami\b', r'^id\b', r'^env\b', r'^printenv\b',
15
+ r'^uname\b', r'^hostname\b', r'^df\b', r'^du\b', r'^free\b', r'^ps\b',
16
+ r'^top\b', r'^htop\b', r'^tree\b',
17
+ r'^git\s+status\b', r'^git\s+log\b', r'^git\s+diff\b', r'^git\s+show\b',
18
+ r'^git\s+branch\b', r'^git\s+remote\b', r'^git\s+tag\b',
19
+ r'^npm\s+list\b', r'^npm\s+ls\b', r'^pip\s+list\b', r'^pip\s+show\b',
20
+ r'^python\s+--version\b', r'^node\s+--version\b', r'^cargo\s+--version\b',
21
+ ]
22
+
23
+
24
+ def _is_safe(command: str) -> bool:
25
+ cmd = command.strip()
26
+ return any(re.search(pattern, cmd) for pattern in SAFE_PATTERNS)
27
+
28
+
29
+ def _check_approval(agent: 'Agent') -> None:
30
+ pending = agent.current_session.get('pending_tool') if agent.current_session else None
31
+ if not pending:
32
+ return
33
+
34
+ tool_name = pending.get('name', '')
35
+ if tool_name not in ('bash', 'shell', 'run', 'run_in_dir'):
36
+ return
37
+
38
+ args = pending.get('arguments', {})
39
+ command = args.get('command', '')
40
+ base_cmd = command.strip().split()[0] if command.strip() else ''
41
+
42
+ approved_cmds = agent.current_session.get('shell_approved_cmds', set()) if agent.current_session else set()
43
+ if base_cmd in approved_cmds:
44
+ return
45
+
46
+ if _is_safe(command):
47
+ return
48
+
49
+ from connectonion.cli.co_ai.tui.context import is_tui_active, show_choice_selector_sync, show_modal_sync
50
+
51
+ if is_tui_active():
52
+ from connectonion.cli.co_ai.tui.modals import TextInputModal
53
+
54
+ truncated = command[:60] + "..." if len(command) > 60 else command
55
+ question = f"Execute: `{truncated}`"
56
+ options = [
57
+ "Yes, execute",
58
+ f"Auto approve '{base_cmd}' for this session",
59
+ "No, tell agent what I want",
60
+ ]
61
+
62
+ choice = show_choice_selector_sync(question, options, allow_other=False)
63
+
64
+ if choice == options[0]:
65
+ return
66
+ elif choice == options[1]:
67
+ if agent.current_session is not None:
68
+ if 'shell_approved_cmds' not in agent.current_session:
69
+ agent.current_session['shell_approved_cmds'] = set()
70
+ agent.current_session['shell_approved_cmds'].add(base_cmd)
71
+ return
72
+ else:
73
+ feedback = show_modal_sync(TextInputModal("What do you want instead?"))
74
+ raise ValueError(f"User feedback: {feedback}")
75
+ else:
76
+ from rich.console import Console
77
+ from rich.panel import Panel
78
+ from rich.syntax import Syntax
79
+ from connectonion.tui import pick
80
+
81
+ console = Console()
82
+ console.print()
83
+ syntax = Syntax(command, "bash", theme="monokai", word_wrap=True)
84
+ console.print(Panel(syntax, title="[yellow]Shell Command[/yellow]", border_style="yellow"))
85
+
86
+ choice = pick("Execute this command?", [
87
+ "Yes, execute",
88
+ f"Auto approve '{base_cmd}' in this session",
89
+ "No, tell agent what I want"
90
+ ], console=console)
91
+
92
+ if choice == "Yes, execute":
93
+ return
94
+ elif choice.startswith("Auto approve"):
95
+ if agent.current_session is not None:
96
+ if 'shell_approved_cmds' not in agent.current_session:
97
+ agent.current_session['shell_approved_cmds'] = set()
98
+ agent.current_session['shell_approved_cmds'].add(base_cmd)
99
+ return
100
+ else:
101
+ feedback = input("What do you want the agent to do instead? ")
102
+ raise ValueError(f"User feedback: {feedback}")
103
+
104
+
105
+ shell_approval = [before_each_tool(_check_approval)]
@@ -0,0 +1,79 @@
1
+ # Explore Agent
2
+
3
+ You are an explore agent specialized in quickly understanding codebases.
4
+
5
+ ## CRITICAL: READ-ONLY MODE
6
+
7
+ <system-reminder>
8
+ This is a READ-ONLY exploration agent. You are PROHIBITED from:
9
+ - Creating, modifying, or deleting files
10
+ - Moving, copying, or renaming files
11
+ - Creating temporary files
12
+ - Using redirect operators (>, >>)
13
+ - Any operation that changes the filesystem
14
+
15
+ You can ONLY use: glob, grep, read_file, and read-only bash commands (ls, git status, git log, git diff, find, cat, head, tail).
16
+
17
+ This is a HARD CONSTRAINT, not a guideline.
18
+ </system-reminder>
19
+
20
+ ## Your Mission
21
+
22
+ Find files, search code, and answer questions about codebase structure. Be fast and thorough.
23
+
24
+ ## Tools (Read-Only)
25
+
26
+ - `glob(pattern)` - Find files by pattern (e.g., `**/*.py`, `src/**/*.ts`)
27
+ - `grep(pattern)` - Search file contents with regex
28
+ - `read_file(path)` - Read file contents
29
+
30
+ ## Strategy
31
+
32
+ 1. **Start broad** - Use glob to find relevant files by pattern
33
+ 2. **Narrow down** - Use grep to find specific content
34
+ 3. **Read selectively** - Only read files that are directly relevant
35
+ 4. **Summarize** - Return structured, actionable findings
36
+
37
+ ## Output Format
38
+
39
+ Return your findings in a clear structure:
40
+
41
+ ```
42
+ ## Files Found
43
+ - path/to/file1.py - Brief description
44
+ - path/to/file2.py - Brief description
45
+
46
+ ## Key Findings
47
+ - Finding 1
48
+ - Finding 2
49
+
50
+ ## Recommended Actions
51
+ - Action 1
52
+ - Action 2
53
+ ```
54
+
55
+ ## Guidelines
56
+
57
+ - Be **fast** - Don't read every file, be selective
58
+ - Be **thorough** - Cover multiple search patterns
59
+ - Be **structured** - Return organized findings
60
+ - Be **concise** - No unnecessary explanation
61
+ - Be **read-only** - NEVER modify any files
62
+
63
+ ## Examples
64
+
65
+ **Task**: "Find all API endpoints"
66
+ ```
67
+ 1. glob("**/api/**/*.py") or glob("**/routes/**/*.ts")
68
+ 2. grep("@app.route|@router|app.get|app.post")
69
+ 3. Read top matches
70
+ 4. Return list of endpoints with their handlers
71
+ ```
72
+
73
+ **Task**: "How is authentication handled?"
74
+ ```
75
+ 1. grep("auth|login|session|jwt|token")
76
+ 2. glob("**/auth*/**")
77
+ 3. Read auth-related files
78
+ 4. Summarize the auth flow
79
+ ```
@@ -0,0 +1,60 @@
1
+ # Plan Agent
2
+
3
+ You are a planning agent specialized in designing implementation strategies.
4
+
5
+ ## Your Mission
6
+
7
+ Analyze requirements, explore the codebase, and create actionable implementation plans.
8
+
9
+ ## Tools
10
+
11
+ - `glob(pattern)` - Find files by pattern
12
+ - `grep(pattern)` - Search file contents
13
+ - `read_file(path)` - Read file contents
14
+
15
+ ## Strategy
16
+
17
+ 1. **Understand the goal** - What exactly needs to be built/changed?
18
+ 2. **Explore existing code** - Find related files and patterns
19
+ 3. **Identify dependencies** - What will be affected?
20
+ 4. **Design the approach** - How should it be implemented?
21
+ 5. **Create steps** - Break into actionable tasks
22
+
23
+ ## Output Format
24
+
25
+ ```
26
+ ## Summary
27
+ One-sentence description of what will be implemented.
28
+
29
+ ## Files to Modify
30
+ - `path/to/file.py` - What changes are needed
31
+
32
+ ## Files to Create
33
+ - `path/to/new_file.py` - Purpose of new file
34
+
35
+ ## Implementation Steps
36
+ 1. Step 1 - Details
37
+ 2. Step 2 - Details
38
+ 3. Step 3 - Details
39
+
40
+ ## Considerations
41
+ - Risk or consideration 1
42
+ - Risk or consideration 2
43
+ ```
44
+
45
+ ## Guidelines
46
+
47
+ - Be **specific** - Name exact files and functions
48
+ - Be **practical** - Steps should be immediately actionable
49
+ - Be **complete** - Don't miss edge cases
50
+ - Be **minimal** - Don't over-engineer, simplest solution that works
51
+
52
+ ## Examples
53
+
54
+ **Task**: "Add user profile page"
55
+ ```
56
+ 1. Find existing page patterns: glob("**/pages/**/*.tsx")
57
+ 2. Find user-related code: grep("user|profile")
58
+ 3. Read similar pages for patterns
59
+ 4. Plan: Create ProfilePage, add route, connect to user API
60
+ ```
@@ -0,0 +1,303 @@
1
+ """Prompt Assembler - Dynamic prompt composition with variable injection.
2
+
3
+ Similar to Claude Code's approach:
4
+ - Tool descriptions are injected based on available tools
5
+ - Variables like ${TOOL_NAME} are interpolated at runtime
6
+ - Conditional sections using ${condition ? "yes" : ""}
7
+ - System reminders can be injected based on agent state
8
+
9
+ Structure:
10
+ prompts/
11
+ ├── main.md # Core agent behavior (with ${VARIABLES})
12
+ ├── tools/ # Tool-specific guidance
13
+ │ ├── shell.md
14
+ │ └── ...
15
+ ├── agents/ # Sub-agent prompts
16
+ │ └── explore.md
17
+ └── reminders/ # Runtime state reminders
18
+ └── plan_mode.md
19
+ """
20
+
21
+ import re
22
+ from pathlib import Path
23
+ from typing import Any, Dict, List, Optional
24
+
25
+
26
+ class PromptContext:
27
+ """Context object holding all variables for prompt interpolation."""
28
+
29
+ def __init__(self):
30
+ self._vars: Dict[str, Any] = {}
31
+ self._tools: Dict[str, Any] = {}
32
+ self._tool_set: set = set()
33
+
34
+ def set(self, key: str, value: Any):
35
+ """Set a variable value."""
36
+ self._vars[key] = value
37
+ return self
38
+
39
+ def get(self, key: str, default: Any = None) -> Any:
40
+ """Get a variable value."""
41
+ return self._vars.get(key, default)
42
+
43
+ def register_tool(self, tool: Any):
44
+ """Register a tool and extract its name."""
45
+ name = _get_tool_name(tool)
46
+ self._tools[name] = tool
47
+ self._tool_set.add(name)
48
+ return self
49
+
50
+ def has_tool(self, name: str) -> bool:
51
+ """Check if a tool is available."""
52
+ return name in self._tool_set
53
+
54
+ def get_tool_names(self):
55
+ """Get set of available tool names."""
56
+ return self._tool_set
57
+
58
+ def to_dict(self):
59
+ """Export context as dict for interpolation."""
60
+ result = dict(self._vars)
61
+ result["AVAILABLE_TOOLS"] = self._tool_set
62
+ result["has_tool"] = self.has_tool
63
+ for name, tool in self._tools.items():
64
+ result[f"{name.upper()}_TOOL"] = tool
65
+ return result
66
+
67
+
68
+ def interpolate(template: str, context: Dict[str, Any]) -> str:
69
+ """
70
+ Interpolate variables in template string.
71
+
72
+ Supports:
73
+ - ${VAR_NAME} - simple variable substitution
74
+ - ${has_tool("name") ? "yes" : "no"} - conditional based on tool availability
75
+ - ${VAR_NAME or "default"} - default values
76
+
77
+ Args:
78
+ template: String with ${...} placeholders
79
+ context: Dict of variable names to values
80
+
81
+ Returns:
82
+ Interpolated string
83
+ """
84
+ def replace_var(match: re.Match) -> str:
85
+ expr = match.group(1).strip()
86
+
87
+ # Handle ternary: condition ? "yes" : "no"
88
+ ternary_match = re.match(r'(.+?)\s*\?\s*"([^"]*)"\s*:\s*"([^"]*)"', expr)
89
+ if ternary_match:
90
+ condition_expr, true_val, false_val = ternary_match.groups()
91
+ condition_result = _eval_condition(condition_expr.strip(), context)
92
+ return true_val if condition_result else false_val
93
+
94
+ # Handle: VAR_NAME or "default"
95
+ or_match = re.match(r'(\w+)\s+or\s+"([^"]*)"', expr)
96
+ if or_match:
97
+ var_name, default = or_match.groups()
98
+ value = context.get(var_name)
99
+ return str(value) if value else default
100
+
101
+ # Simple variable lookup
102
+ if expr in context:
103
+ value = context[expr]
104
+ if callable(value) and not isinstance(value, type):
105
+ return str(value())
106
+ return str(value) if value is not None else ""
107
+
108
+ # Keep original if not found (for debugging)
109
+ return match.group(0)
110
+
111
+ # Match ${...} patterns, handling nested braces
112
+ pattern = r'\$\{([^}]+)\}'
113
+ return re.sub(pattern, replace_var, template)
114
+
115
+
116
+ def _eval_condition(expr: str, context: Dict[str, Any]) -> bool:
117
+ """Evaluate a simple condition expression."""
118
+ # Handle: has_tool("name")
119
+ tool_check = re.match(r'has_tool\s*\(\s*"([^"]+)"\s*\)', expr)
120
+ if tool_check:
121
+ tool_name = tool_check.group(1)
122
+ has_tool_fn = context.get("has_tool")
123
+ if callable(has_tool_fn):
124
+ return bool(has_tool_fn(tool_name))
125
+ return tool_name in context.get("AVAILABLE_TOOLS", set())
126
+
127
+ # Handle: VAR_NAME (truthy check)
128
+ if expr in context:
129
+ return bool(context[expr])
130
+
131
+ # Handle: !VAR_NAME (falsy check)
132
+ if expr.startswith("!") and expr[1:] in context:
133
+ return not bool(context[expr[1:]])
134
+
135
+ return False
136
+
137
+
138
+ def _get_tool_name(tool: Any) -> str:
139
+ """Extract tool name from function or class instance."""
140
+ if callable(tool) and hasattr(tool, "__name__"):
141
+ return getattr(tool, "__name__")
142
+ if hasattr(tool, "name"):
143
+ return getattr(tool, "name")
144
+ return tool.__class__.__name__
145
+
146
+
147
+ def assemble_prompt(
148
+ prompts_dir: str,
149
+ tools: Optional[List[Any]] = None,
150
+ context: Optional[PromptContext] = None,
151
+ extra_vars: Optional[Dict[str, Any]] = None,
152
+ ) -> str:
153
+ """
154
+ Assemble a system prompt from modular files with variable interpolation.
155
+
156
+ Args:
157
+ prompts_dir: Path to prompts directory
158
+ tools: List of tool objects/functions (loads matching .md files)
159
+ context: Optional PromptContext with pre-configured variables
160
+ extra_vars: Additional variables to inject
161
+
162
+ Returns:
163
+ Assembled and interpolated prompt string
164
+ """
165
+ prompts_path = Path(prompts_dir)
166
+ parts = []
167
+
168
+ # Build context if not provided
169
+ if context is None:
170
+ context = PromptContext()
171
+
172
+ # Register tools
173
+ if tools:
174
+ for tool in tools:
175
+ context.register_tool(tool)
176
+
177
+ # Add extra variables
178
+ if extra_vars:
179
+ for key, value in extra_vars.items():
180
+ context.set(key, value)
181
+
182
+ # Build interpolation dict
183
+ ctx_dict = context.to_dict()
184
+
185
+ # Add tool name mappings for convenience
186
+ # e.g., SHELL_TOOL_NAME = "shell", READ_TOOL_NAME = "read_file"
187
+ for name in context.get_tool_names():
188
+ ctx_dict[f"{name.upper()}_TOOL_NAME"] = name
189
+
190
+ # 1. Main prompt (required)
191
+ main_file = prompts_path / "main.md"
192
+ if main_file.exists():
193
+ content = main_file.read_text()
194
+ parts.append(interpolate(content, ctx_dict))
195
+
196
+ # 2. Workflow (agent creation workflow)
197
+ workflow_file = prompts_path / "workflow.md"
198
+ if workflow_file.exists():
199
+ content = workflow_file.read_text()
200
+ parts.append(interpolate(content, ctx_dict))
201
+
202
+ # 3. ConnectOnion framework prompt (index always included)
203
+ co_index = prompts_path / "connectonion" / "index.md"
204
+ if co_index.exists():
205
+ content = co_index.read_text()
206
+ parts.append(interpolate(content, ctx_dict))
207
+
208
+ # 4. ConnectOnion examples (all loaded for one-shot correct)
209
+ examples_dir = prompts_path / "connectonion" / "examples"
210
+ if examples_dir.exists():
211
+ for example_file in sorted(examples_dir.glob("*.md")):
212
+ content = example_file.read_text()
213
+ parts.append(interpolate(content, ctx_dict))
214
+
215
+ # 5. Tool descriptions (for each available tool)
216
+ tools_dir = prompts_path / "tools"
217
+ if tools_dir.exists() and tools:
218
+ for tool in tools:
219
+ tool_name = _get_tool_name(tool).lower()
220
+ tool_file = tools_dir / f"{tool_name}.md"
221
+ if tool_file.exists():
222
+ content = tool_file.read_text()
223
+ parts.append(interpolate(content, ctx_dict))
224
+
225
+ return "\n\n---\n\n".join(parts)
226
+
227
+
228
+ def load_reminder(
229
+ prompts_dir: str,
230
+ reminder_name: str,
231
+ context: Optional[PromptContext] = None,
232
+ extra_vars: Optional[Dict[str, Any]] = None,
233
+ ) -> Optional[str]:
234
+ """
235
+ Load a system reminder for runtime injection.
236
+
237
+ Reminders are state-specific prompts injected during conversation,
238
+ wrapped in <system-reminder> tags.
239
+
240
+ Args:
241
+ prompts_dir: Path to prompts directory
242
+ reminder_name: Name of the reminder (e.g., "plan_mode")
243
+ context: Optional PromptContext for variable interpolation
244
+ extra_vars: Additional variables to inject
245
+
246
+ Returns:
247
+ Formatted reminder string with <system-reminder> tags, or None if not found
248
+ """
249
+ reminders_dir = Path(prompts_dir) / "reminders"
250
+ reminder_file = reminders_dir / f"{reminder_name}.md"
251
+
252
+ if not reminder_file.exists():
253
+ return None
254
+
255
+ content = reminder_file.read_text()
256
+
257
+ # Build interpolation context
258
+ ctx_dict = {}
259
+ if context:
260
+ ctx_dict = context.to_dict()
261
+ if extra_vars:
262
+ ctx_dict.update(extra_vars)
263
+
264
+ # Interpolate variables
265
+ interpolated = interpolate(content, ctx_dict)
266
+
267
+ return f"<system-reminder>\n{interpolated}\n</system-reminder>"
268
+
269
+
270
+ def load_agent_prompt(
271
+ prompts_dir: str,
272
+ agent_type: str,
273
+ context: Optional[PromptContext] = None,
274
+ extra_vars: Optional[Dict[str, Any]] = None,
275
+ ) -> Optional[str]:
276
+ """
277
+ Load a sub-agent system prompt.
278
+
279
+ Args:
280
+ prompts_dir: Path to prompts directory
281
+ agent_type: Type of agent (e.g., "explore", "plan")
282
+ context: Optional PromptContext for variable interpolation
283
+ extra_vars: Additional variables to inject
284
+
285
+ Returns:
286
+ Agent prompt string, or None if not found
287
+ """
288
+ agents_dir = Path(prompts_dir) / "agents"
289
+ agent_file = agents_dir / f"{agent_type}.md"
290
+
291
+ if not agent_file.exists():
292
+ return None
293
+
294
+ content = agent_file.read_text()
295
+
296
+ # Build interpolation context
297
+ ctx_dict = {}
298
+ if context:
299
+ ctx_dict = context.to_dict()
300
+ if extra_vars:
301
+ ctx_dict.update(extra_vars)
302
+
303
+ return interpolate(content, ctx_dict)