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.
- connectonion/__init__.py +46 -9
- connectonion/cli/__init__.py +11 -1
- connectonion/cli/browser_agent/__init__.py +11 -1
- connectonion/cli/browser_agent/browser.py +95 -142
- connectonion/cli/browser_agent/element_finder.py +147 -0
- connectonion/cli/browser_agent/highlight_screenshot.py +182 -0
- connectonion/cli/browser_agent/prompt.md +188 -105
- connectonion/cli/browser_agent/prompts/element_matcher.md +59 -0
- connectonion/cli/browser_agent/prompts/form_filler.md +19 -0
- connectonion/cli/browser_agent/prompts/scroll_strategy.md +36 -0
- connectonion/cli/browser_agent/scripts/extract_elements.js +126 -0
- connectonion/cli/browser_agent/scroll.py +145 -0
- connectonion/cli/co_ai/__init__.py +6 -0
- connectonion/cli/co_ai/agent.py +87 -0
- connectonion/cli/co_ai/agents/__init__.py +5 -0
- connectonion/cli/co_ai/agents/registry.py +57 -0
- connectonion/cli/co_ai/commands/__init__.py +45 -0
- connectonion/cli/co_ai/commands/compact.py +173 -0
- connectonion/cli/co_ai/commands/cost.py +77 -0
- connectonion/cli/co_ai/commands/export.py +60 -0
- connectonion/cli/co_ai/commands/help.py +80 -0
- connectonion/cli/co_ai/commands/init.py +101 -0
- connectonion/cli/co_ai/commands/sessions.py +55 -0
- connectonion/cli/co_ai/commands/tasks.py +63 -0
- connectonion/cli/co_ai/commands/undo.py +103 -0
- connectonion/cli/co_ai/context.py +127 -0
- connectonion/cli/co_ai/main.py +52 -0
- connectonion/cli/co_ai/plugins/__init__.py +6 -0
- connectonion/cli/co_ai/plugins/reminder.py +76 -0
- connectonion/cli/co_ai/plugins/shell_approval.py +105 -0
- connectonion/cli/co_ai/prompts/agents/explore.md +79 -0
- connectonion/cli/co_ai/prompts/agents/plan.md +60 -0
- connectonion/cli/co_ai/prompts/assembler.py +303 -0
- connectonion/cli/{docs/co-vibecoding-principles-docs-contexts-all-in-one.md → co_ai/prompts/connectonion/README.md} +26 -0
- connectonion/cli/co_ai/prompts/connectonion/api.md +457 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/README.md +805 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/auth.md +46 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/browser.md +235 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/copy.md +184 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/create.md +335 -0
- connectonion/cli/co_ai/prompts/connectonion/cli/init.md +431 -0
- connectonion/cli/co_ai/prompts/connectonion/co-directory-structure.md +214 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/agent.md +1078 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/events.md +816 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/llm_do.md +256 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/max_iterations.md +362 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/models.md +641 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/plugins.md +100 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/prompts.md +122 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/tools.md +512 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/transcribe.md +156 -0
- connectonion/cli/co_ai/prompts/connectonion/concepts/trust.md +291 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/README.md +18 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/auto_debug.md +1026 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/console.md +129 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/eval-format.md +178 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/eval.md +230 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/exceptions.md +307 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/log.md +117 -0
- connectonion/cli/co_ai/prompts/connectonion/debug/xray.md +215 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/001-choosing-input-method.md +202 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/002-choosing-llm-function-name.md +202 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/003-choosing-trust-keyword.md +141 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/004-cli-create-flow.md +117 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/005-designing-agent-network-protocol.md +503 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/006-agent-address-format.md +305 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/007-authentication-backend-design.md +240 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/008-naming-is-hard.md +228 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/009-why-connect-function.md +167 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/010-cli-ux-progressive-disclosure.md +176 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/011-global-config-identity-management.md +357 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/012-tool-execution-separation.md +259 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/013-debug-and-logging-design.md +253 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/014-hook-system-design.md +510 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/015-interactive-auto-debug-design.md +837 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/016-why-no-zero-knowledge-proofs.md +358 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/017-session-logging-and-eval-format.md +120 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/018-event-api-naming.md +274 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/019-agent-lifecycle-design.md +655 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/020-trust-system-and-network-architecture.md +503 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/021-task-storage-jsonl-design.md +496 -0
- connectonion/cli/co_ai/prompts/connectonion/design-decisions/022-raw-asgi-implementation.md +273 -0
- connectonion/cli/co_ai/prompts/connectonion/examples/agent_reasoning.md +62 -0
- connectonion/cli/co_ai/prompts/connectonion/examples/atomic_tools.md +24 -0
- connectonion/cli/co_ai/prompts/connectonion/examples/load_guide.md +18 -0
- connectonion/cli/co_ai/prompts/connectonion/examples.md +0 -0
- connectonion/cli/co_ai/prompts/connectonion/hook-system-options.md +364 -0
- connectonion/cli/co_ai/prompts/connectonion/index.md +162 -0
- connectonion/cli/co_ai/prompts/connectonion/integrations/README.md +12 -0
- connectonion/cli/co_ai/prompts/connectonion/integrations/auth.md +450 -0
- connectonion/cli/co_ai/prompts/connectonion/integrations/google.md +431 -0
- connectonion/cli/co_ai/prompts/connectonion/integrations/microsoft.md +370 -0
- connectonion/cli/co_ai/prompts/connectonion/network/README.md +14 -0
- connectonion/cli/co_ai/prompts/connectonion/network/connect.md +543 -0
- connectonion/cli/co_ai/prompts/connectonion/network/connection.md +538 -0
- connectonion/cli/co_ai/prompts/connectonion/network/deploy.md +123 -0
- connectonion/cli/co_ai/prompts/connectonion/network/host.md +1049 -0
- connectonion/cli/co_ai/prompts/connectonion/network/protocol/agent-relay-protocol.md +495 -0
- connectonion/cli/co_ai/prompts/connectonion/network/protocol/announce-message.md +115 -0
- connectonion/cli/co_ai/prompts/connectonion/principles.md +124 -0
- connectonion/cli/co_ai/prompts/connectonion/quickstart.md +261 -0
- connectonion/cli/co_ai/prompts/connectonion/roadmap.md +81 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/README.md +77 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/meta-agent.md +152 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/minimal.md +105 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/playwright.md +130 -0
- connectonion/cli/co_ai/prompts/connectonion/templates/web-research.md +144 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/README.md +95 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/chat.md +181 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/divider.md +63 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/dropdown.md +83 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/footer.md +44 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/fuzzy.md +68 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/input.md +84 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/keys.md +77 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/pick.md +71 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/providers.md +89 -0
- connectonion/cli/co_ai/prompts/connectonion/tui/status_bar.md +67 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/README.md +156 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/calendar_plugin.md +68 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/eval.md +89 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/gmail_plugin.md +68 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/image_result_formatter.md +74 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/re_act.md +86 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_plugins/shell_approval.md +69 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/README.md +81 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/diff_writer.md +138 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/get_emails.md +499 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/gmail.md +135 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/google_calendar.md +106 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/memory.md +486 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/microsoft_calendar.md +106 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/outlook.md +120 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/send_email.md +403 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/shell.md +95 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/slash_command.md +96 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/terminal.md +97 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/todo_list.md +252 -0
- connectonion/cli/co_ai/prompts/connectonion/useful_tools/web_fetch.md +130 -0
- connectonion/cli/co_ai/prompts/connectonion/vibe-coding-guide.md +97 -0
- connectonion/cli/co_ai/prompts/connectonion/windows-support.md +258 -0
- connectonion/cli/co_ai/prompts/main.md +247 -0
- connectonion/cli/co_ai/prompts/reminders/plan_mode.md +34 -0
- connectonion/cli/co_ai/prompts/summarization.md +55 -0
- connectonion/cli/co_ai/prompts/tools/ask_user.md +61 -0
- connectonion/cli/co_ai/prompts/tools/background.md +57 -0
- connectonion/cli/co_ai/prompts/tools/edit.md +90 -0
- connectonion/cli/co_ai/prompts/tools/glob.md +52 -0
- connectonion/cli/co_ai/prompts/tools/grep.md +55 -0
- connectonion/cli/co_ai/prompts/tools/plan_mode.md +80 -0
- connectonion/cli/co_ai/prompts/tools/read.md +40 -0
- connectonion/cli/co_ai/prompts/tools/shell.md +67 -0
- connectonion/cli/co_ai/prompts/tools/task.md +51 -0
- connectonion/cli/co_ai/prompts/tools/todo.md +139 -0
- connectonion/cli/co_ai/prompts/tools/write.md +47 -0
- connectonion/cli/co_ai/prompts/workflow.md +89 -0
- connectonion/cli/co_ai/reminders.py +159 -0
- connectonion/cli/co_ai/sessions.py +110 -0
- connectonion/cli/co_ai/skills/__init__.py +37 -0
- connectonion/cli/co_ai/skills/builtin/commit/SKILL.md +63 -0
- connectonion/cli/co_ai/skills/builtin/review-pr/SKILL.md +76 -0
- connectonion/cli/co_ai/skills/loader.py +166 -0
- connectonion/cli/co_ai/skills/tool.py +46 -0
- connectonion/cli/co_ai/tools/__init__.py +92 -0
- connectonion/cli/co_ai/tools/ask_user.py +35 -0
- connectonion/cli/co_ai/tools/background.py +201 -0
- connectonion/cli/co_ai/tools/diff_writer.py +291 -0
- connectonion/cli/co_ai/tools/edit.py +89 -0
- connectonion/cli/co_ai/tools/glob.py +84 -0
- connectonion/cli/co_ai/tools/grep.py +158 -0
- connectonion/cli/co_ai/tools/load_guide.py +23 -0
- connectonion/cli/co_ai/tools/multi_edit.py +116 -0
- connectonion/cli/co_ai/tools/plan_mode.py +172 -0
- connectonion/cli/co_ai/tools/read.py +67 -0
- connectonion/cli/co_ai/tools/task.py +59 -0
- connectonion/cli/co_ai/tools/todo_list.py +159 -0
- connectonion/cli/co_ai/tools/write.py +126 -0
- connectonion/cli/commands/__init__.py +11 -1
- connectonion/cli/commands/ai_commands.py +34 -0
- connectonion/cli/commands/copy_commands.py +55 -6
- connectonion/cli/commands/create.py +20 -17
- connectonion/cli/commands/init.py +19 -22
- connectonion/cli/commands/project_cmd_lib.py +15 -0
- connectonion/cli/main.py +11 -0
- connectonion/console.py +15 -1
- connectonion/core/__init__.py +10 -1
- connectonion/core/agent.py +37 -16
- connectonion/core/exceptions.py +74 -0
- connectonion/core/llm.py +54 -6
- connectonion/core/tool_executor.py +32 -31
- connectonion/core/tool_factory.py +47 -10
- connectonion/debug/__init__.py +10 -1
- connectonion/debug/debug_explainer/__init__.py +10 -1
- connectonion/debug/execution_analyzer/__init__.py +10 -1
- connectonion/debug/execution_analyzer/execution_analysis.py +5 -2
- connectonion/debug/runtime_inspector/__init__.py +10 -1
- connectonion/docs/.package-ignore +6 -0
- connectonion/docs/README.md +2036 -0
- connectonion/docs/api.md +457 -0
- connectonion/docs/archive/001-ai-agent-is-just-prompt-plus-function.md +249 -0
- connectonion/docs/archive/README.md +53 -0
- connectonion/docs/archive/archive/consolidation-plan.md +72 -0
- connectonion/docs/archive/archive/core-principles-extracted.md +239 -0
- connectonion/docs/archive/archive/master-principles.md +222 -0
- connectonion/docs/archive/archive/principles.md +293 -0
- connectonion/docs/archive/archive/simplicity-principles.md +221 -0
- connectonion/docs/archive/attack-defense-insights.md +410 -0
- connectonion/docs/archive/business-model.md +305 -0
- connectonion/docs/archive/core-principles-unified.md +190 -0
- connectonion/docs/archive/discussion-journey.md +178 -0
- connectonion/docs/archive/economic-analysis.md +323 -0
- connectonion/docs/archive/features/01-share-and-find.md +256 -0
- connectonion/docs/archive/features/02-agent-authentication.md +93 -0
- connectonion/docs/archive/features/03-test-before-trust.md +71 -0
- connectonion/docs/archive/features/06-reliability-and-offline.md +197 -0
- connectonion/docs/archive/features/README.md +46 -0
- connectonion/docs/archive/features-roadmap.md +247 -0
- connectonion/docs/archive/mcp-comparison-insights.md +215 -0
- connectonion/docs/archive/migration-strategy.md +571 -0
- connectonion/docs/archive/mini-whitepaper.md +293 -0
- connectonion/docs/archive/network-protocol.md +394 -0
- connectonion/docs/archive/semantic-revolution.md +367 -0
- connectonion/docs/archive/technical-architecture.md +453 -0
- connectonion/docs/archive/the-semantic-insight.md +207 -0
- connectonion/docs/archive/threat-model.md +164 -0
- connectonion/docs/cli/README.md +805 -0
- connectonion/docs/cli/auth.md +46 -0
- connectonion/docs/cli/browser.md +235 -0
- connectonion/docs/cli/copy.md +232 -0
- connectonion/docs/cli/create.md +335 -0
- connectonion/docs/cli/init.md +431 -0
- connectonion/docs/co-directory-structure.md +214 -0
- connectonion/docs/concepts/agent.md +1078 -0
- connectonion/docs/concepts/events.md +699 -0
- connectonion/docs/concepts/llm_do.md +256 -0
- connectonion/docs/concepts/max_iterations.md +362 -0
- connectonion/docs/concepts/models.md +641 -0
- connectonion/docs/concepts/plugins.md +100 -0
- connectonion/docs/concepts/prompts.md +122 -0
- connectonion/docs/concepts/session.md +428 -0
- connectonion/docs/concepts/tools.md +512 -0
- connectonion/docs/concepts/transcribe.md +156 -0
- connectonion/docs/concepts/trust.md +291 -0
- connectonion/docs/connectonion.md +1256 -0
- connectonion/docs/debug/README.md +18 -0
- connectonion/docs/debug/auto_debug.md +1026 -0
- connectonion/docs/debug/console.md +129 -0
- connectonion/docs/debug/eval-format.md +178 -0
- connectonion/docs/debug/eval.md +230 -0
- connectonion/docs/debug/exceptions.md +307 -0
- connectonion/docs/debug/log.md +117 -0
- connectonion/docs/debug/xray.md +215 -0
- connectonion/docs/design-decisions/001-choosing-input-method.md +202 -0
- connectonion/docs/design-decisions/002-choosing-llm-function-name.md +202 -0
- connectonion/docs/design-decisions/003-choosing-trust-keyword.md +141 -0
- connectonion/docs/design-decisions/004-cli-create-flow.md +117 -0
- connectonion/docs/design-decisions/005-designing-agent-network-protocol.md +503 -0
- connectonion/docs/design-decisions/006-agent-address-format.md +305 -0
- connectonion/docs/design-decisions/007-authentication-backend-design.md +240 -0
- connectonion/docs/design-decisions/008-naming-is-hard.md +228 -0
- connectonion/docs/design-decisions/009-why-connect-function.md +167 -0
- connectonion/docs/design-decisions/010-cli-ux-progressive-disclosure.md +176 -0
- connectonion/docs/design-decisions/011-global-config-identity-management.md +357 -0
- connectonion/docs/design-decisions/012-tool-execution-separation.md +259 -0
- connectonion/docs/design-decisions/013-debug-and-logging-design.md +253 -0
- connectonion/docs/design-decisions/014-hook-system-design.md +510 -0
- connectonion/docs/design-decisions/015-interactive-auto-debug-design.md +837 -0
- connectonion/docs/design-decisions/016-why-no-zero-knowledge-proofs.md +358 -0
- connectonion/docs/design-decisions/017-session-logging-and-eval-format.md +120 -0
- connectonion/docs/design-decisions/018-event-api-naming.md +274 -0
- connectonion/docs/design-decisions/019-agent-lifecycle-design.md +655 -0
- connectonion/docs/design-decisions/020-trust-system-and-network-architecture.md +503 -0
- connectonion/docs/design-decisions/021-task-storage-jsonl-design.md +496 -0
- connectonion/docs/design-decisions/022-raw-asgi-implementation.md +273 -0
- connectonion/docs/examples.md +0 -0
- connectonion/docs/hook-system-options.md +364 -0
- connectonion/docs/integrations/README.md +12 -0
- connectonion/docs/integrations/auth.md +450 -0
- connectonion/docs/integrations/google.md +431 -0
- connectonion/docs/integrations/microsoft.md +370 -0
- connectonion/docs/network/README.md +14 -0
- connectonion/docs/network/connect.md +629 -0
- connectonion/docs/network/deploy.md +124 -0
- connectonion/docs/network/host.md +1087 -0
- connectonion/docs/network/io.md +538 -0
- connectonion/docs/network/protocol/agent-relay-protocol.md +495 -0
- connectonion/docs/network/protocol/announce-message.md +115 -0
- connectonion/docs/principles.md +124 -0
- connectonion/docs/quickstart.md +261 -0
- connectonion/docs/roadmap.md +81 -0
- connectonion/docs/templates/README.md +77 -0
- connectonion/docs/templates/meta-agent.md +152 -0
- connectonion/docs/templates/minimal.md +105 -0
- connectonion/docs/templates/playwright.md +130 -0
- connectonion/docs/templates/web-research.md +144 -0
- connectonion/docs/tui/README.md +95 -0
- connectonion/docs/tui/chat.md +181 -0
- connectonion/docs/tui/divider.md +63 -0
- connectonion/docs/tui/dropdown.md +83 -0
- connectonion/docs/tui/footer.md +44 -0
- connectonion/docs/tui/fuzzy.md +68 -0
- connectonion/docs/tui/input.md +84 -0
- connectonion/docs/tui/keys.md +77 -0
- connectonion/docs/tui/pick.md +71 -0
- connectonion/docs/tui/providers.md +89 -0
- connectonion/docs/tui/status_bar.md +67 -0
- connectonion/docs/useful_plugins/README.md +160 -0
- connectonion/docs/useful_plugins/calendar_plugin.md +68 -0
- connectonion/docs/useful_plugins/eval.md +89 -0
- connectonion/docs/useful_plugins/gmail_plugin.md +68 -0
- connectonion/docs/useful_plugins/image_result_formatter.md +74 -0
- connectonion/docs/useful_plugins/re_act.md +86 -0
- connectonion/docs/useful_plugins/shell_approval.md +69 -0
- connectonion/docs/useful_plugins/system_reminder.md +210 -0
- connectonion/docs/useful_prompts/README.md +127 -0
- connectonion/docs/useful_prompts/coding_agent.md +214 -0
- connectonion/docs/useful_tools/README.md +81 -0
- connectonion/docs/useful_tools/ask_user.md +103 -0
- connectonion/docs/useful_tools/diff_writer.md +158 -0
- connectonion/docs/useful_tools/get_emails.md +519 -0
- connectonion/docs/useful_tools/gmail.md +155 -0
- connectonion/docs/useful_tools/google_calendar.md +126 -0
- connectonion/docs/useful_tools/memory.md +506 -0
- connectonion/docs/useful_tools/microsoft_calendar.md +126 -0
- connectonion/docs/useful_tools/outlook.md +140 -0
- connectonion/docs/useful_tools/send_email.md +423 -0
- connectonion/docs/useful_tools/shell.md +115 -0
- connectonion/docs/useful_tools/slash_command.md +116 -0
- connectonion/docs/useful_tools/terminal.md +115 -0
- connectonion/docs/useful_tools/todo_list.md +272 -0
- connectonion/docs/useful_tools/web_fetch.md +150 -0
- connectonion/docs/vibe-coding-guide.md +97 -0
- connectonion/docs/windows-support.md +258 -0
- connectonion/logger.py +3 -3
- connectonion/network/__init__.py +19 -6
- connectonion/network/asgi/__init__.py +81 -0
- connectonion/network/asgi/http.py +205 -0
- connectonion/network/asgi/websocket.py +217 -0
- connectonion/network/connect.py +232 -185
- connectonion/network/host/__init__.py +59 -0
- connectonion/network/host/auth.py +191 -0
- connectonion/network/host/routes.py +135 -0
- connectonion/network/host/server.py +289 -0
- connectonion/network/host/session.py +78 -0
- connectonion/network/io/__init__.py +21 -0
- connectonion/network/{connection.py → io/base.py} +17 -42
- connectonion/network/io/websocket.py +55 -0
- connectonion/network/relay.py +37 -16
- connectonion/network/trust/__init__.py +30 -0
- connectonion/network/trust/factory.py +138 -0
- connectonion/network/{trust_agents.py → trust/prompts.py} +3 -3
- connectonion/network/{trust_functions.py → trust/tools.py} +2 -2
- connectonion/prompt_files/__init__.py +11 -1
- connectonion/prompt_files/react_acknowledge.md +26 -0
- connectonion/prompts.py +10 -1
- connectonion/tui/chat.py +10 -1
- connectonion/tui/divider.py +10 -1
- connectonion/tui/dropdown.py +10 -1
- connectonion/tui/footer.py +8 -0
- connectonion/tui/fuzzy.py +11 -1
- connectonion/tui/input.py +118 -70
- connectonion/tui/keys.py +133 -6
- connectonion/tui/providers.py +11 -1
- connectonion/tui/status_bar.py +10 -1
- connectonion/useful_events_handlers/__init__.py +8 -0
- connectonion/useful_events_handlers/reflect.py +19 -4
- connectonion/useful_plugins/__init__.py +2 -1
- connectonion/useful_plugins/eval.py +2 -2
- connectonion/useful_plugins/gmail_plugin.py +3 -3
- connectonion/useful_plugins/image_result_formatter.py +3 -3
- connectonion/useful_plugins/re_act.py +114 -28
- connectonion/useful_plugins/shell_approval.py +2 -2
- connectonion/useful_plugins/system_reminder.py +103 -0
- connectonion/useful_plugins/ui_stream.py +18 -133
- connectonion/useful_prompts/README.md +61 -0
- connectonion/useful_prompts/__init__.py +45 -0
- connectonion/useful_prompts/coding_agent/README.md +106 -0
- connectonion/useful_prompts/coding_agent/assembler.py +123 -0
- connectonion/useful_prompts/coding_agent/prompts/main.md +227 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/ask_user.md +61 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/background.md +57 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/edit.md +90 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/glob.md +52 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/grep.md +55 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/plan_mode.md +80 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/read.md +40 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/shell.md +67 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/task.md +51 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/todo.md +139 -0
- connectonion/useful_prompts/coding_agent/prompts/tools/write.md +48 -0
- connectonion/useful_prompts/system-reminders/security-warning.md +14 -0
- connectonion/useful_prompts/system-reminders/test-reminder.md +11 -0
- connectonion/useful_tools/__init__.py +31 -4
- connectonion/useful_tools/ask_user.py +35 -0
- connectonion/useful_tools/bash.py +69 -0
- connectonion/useful_tools/diff_writer.py +186 -94
- connectonion/useful_tools/edit.py +102 -0
- connectonion/useful_tools/glob_files.py +97 -0
- connectonion/useful_tools/grep_files.py +171 -0
- connectonion/useful_tools/multi_edit.py +116 -0
- connectonion/useful_tools/read_file.py +73 -0
- connectonion/useful_tools/shell.py +50 -45
- connectonion/useful_tools/write_file.py +129 -0
- {connectonion-0.6.1.dist-info → connectonion-0.6.3.dist-info}/METADATA +10 -3
- connectonion-0.6.3.dist-info/RECORD +469 -0
- connectonion/cli/browser_agent/scroll_strategies.py +0 -276
- connectonion/network/asgi.py +0 -407
- connectonion/network/host.py +0 -616
- connectonion/network/trust.py +0 -166
- connectonion-0.6.1.dist-info/RECORD +0 -123
- /connectonion/cli/{docs → co_ai/prompts/connectonion}/connectonion.md +0 -0
- {connectonion-0.6.1.dist-info → connectonion-0.6.3.dist-info}/WHEEL +0 -0
- {connectonion-0.6.1.dist-info → connectonion-0.6.3.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract interactive elements from the page with injected IDs.
|
|
3
|
+
*
|
|
4
|
+
* Inspired by browser-use (https://github.com/browser-use/browser-use).
|
|
5
|
+
*
|
|
6
|
+
* This script:
|
|
7
|
+
* 1. Finds all interactive elements (buttons, links, inputs, etc.)
|
|
8
|
+
* 2. Injects a unique `data-browser-agent-id` attribute into each
|
|
9
|
+
* 3. Returns element data with bounding boxes for LLM matching
|
|
10
|
+
*/
|
|
11
|
+
(() => {
|
|
12
|
+
const results = [];
|
|
13
|
+
let index = 0;
|
|
14
|
+
|
|
15
|
+
// Interactive element types
|
|
16
|
+
const INTERACTIVE_TAGS = new Set([
|
|
17
|
+
'a', 'button', 'input', 'select', 'textarea', 'label',
|
|
18
|
+
'details', 'summary', 'dialog'
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
const INTERACTIVE_ROLES = new Set([
|
|
22
|
+
'button', 'link', 'menuitem', 'menuitemcheckbox', 'menuitemradio',
|
|
23
|
+
'option', 'radio', 'switch', 'tab', 'checkbox', 'textbox',
|
|
24
|
+
'searchbox', 'combobox', 'listbox', 'slider', 'spinbutton'
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
// Check if element is visible
|
|
28
|
+
function isVisible(el) {
|
|
29
|
+
const style = window.getComputedStyle(el);
|
|
30
|
+
if (style.display === 'none') return false;
|
|
31
|
+
if (style.visibility === 'hidden') return false;
|
|
32
|
+
if (parseFloat(style.opacity) === 0) return false;
|
|
33
|
+
|
|
34
|
+
// Skip visually-hidden accessibility elements
|
|
35
|
+
const className = el.className || '';
|
|
36
|
+
if (typeof className === 'string' &&
|
|
37
|
+
(className.includes('visually-hidden') ||
|
|
38
|
+
className.includes('sr-only') ||
|
|
39
|
+
className.includes('screen-reader'))) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const rect = el.getBoundingClientRect();
|
|
44
|
+
if (rect.width === 0 || rect.height === 0) return false;
|
|
45
|
+
|
|
46
|
+
// Skip elements that are clipped/hidden with CSS tricks
|
|
47
|
+
if (rect.width < 2 || rect.height < 2) return false;
|
|
48
|
+
|
|
49
|
+
// Check if in viewport (with some margin)
|
|
50
|
+
const margin = 100;
|
|
51
|
+
if (rect.bottom < -margin) return false;
|
|
52
|
+
if (rect.top > window.innerHeight + margin) return false;
|
|
53
|
+
if (rect.right < -margin) return false;
|
|
54
|
+
if (rect.left > window.innerWidth + margin) return false;
|
|
55
|
+
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Get clean text content
|
|
60
|
+
function getText(el) {
|
|
61
|
+
// For inputs, get value or placeholder
|
|
62
|
+
if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {
|
|
63
|
+
return el.value || el.placeholder || '';
|
|
64
|
+
}
|
|
65
|
+
// For other elements, get inner text
|
|
66
|
+
const text = el.innerText || el.textContent || '';
|
|
67
|
+
return text.trim().replace(/\s+/g, ' ').substring(0, 80);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Process all elements
|
|
71
|
+
document.querySelectorAll('*').forEach(el => {
|
|
72
|
+
const tag = el.tagName.toLowerCase();
|
|
73
|
+
const role = el.getAttribute('role');
|
|
74
|
+
|
|
75
|
+
// Check if interactive
|
|
76
|
+
const isInteractiveTag = INTERACTIVE_TAGS.has(tag);
|
|
77
|
+
const isInteractiveRole = role && INTERACTIVE_ROLES.has(role);
|
|
78
|
+
const isClickable = window.getComputedStyle(el).cursor === 'pointer';
|
|
79
|
+
const hasTabIndex = el.hasAttribute('tabindex') && el.tabIndex >= 0;
|
|
80
|
+
const hasClickHandler = el.onclick !== null || el.hasAttribute('onclick');
|
|
81
|
+
|
|
82
|
+
if (!isInteractiveTag && !isInteractiveRole && !isClickable &&
|
|
83
|
+
!hasTabIndex && !hasClickHandler) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Skip hidden inputs
|
|
88
|
+
if (tag === 'input' && el.type === 'hidden') return;
|
|
89
|
+
|
|
90
|
+
// Skip empty elements with no text or useful attributes
|
|
91
|
+
const text = getText(el);
|
|
92
|
+
const ariaLabel = el.getAttribute('aria-label');
|
|
93
|
+
const placeholder = el.placeholder;
|
|
94
|
+
if (!text && !ariaLabel && !placeholder && tag !== 'input') return;
|
|
95
|
+
|
|
96
|
+
// Skip very small elements (likely icons)
|
|
97
|
+
const rect = el.getBoundingClientRect();
|
|
98
|
+
if (rect.width < 20 && rect.height < 20 && !text) return;
|
|
99
|
+
|
|
100
|
+
// Check visibility
|
|
101
|
+
if (!isVisible(el)) return;
|
|
102
|
+
|
|
103
|
+
// INJECT a unique ID attribute for reliable location
|
|
104
|
+
const highlightId = String(index);
|
|
105
|
+
el.setAttribute('data-browser-agent-id', highlightId);
|
|
106
|
+
|
|
107
|
+
results.push({
|
|
108
|
+
index: index++,
|
|
109
|
+
tag: tag,
|
|
110
|
+
text: text,
|
|
111
|
+
role: role,
|
|
112
|
+
aria_label: el.getAttribute('aria-label'),
|
|
113
|
+
placeholder: el.placeholder || null,
|
|
114
|
+
input_type: el.type || null,
|
|
115
|
+
href: (tag === 'a' && el.href) ? el.href.substring(0, 100) : null,
|
|
116
|
+
x: Math.round(rect.x),
|
|
117
|
+
y: Math.round(rect.y),
|
|
118
|
+
width: Math.round(rect.width),
|
|
119
|
+
height: Math.round(rect.height),
|
|
120
|
+
// Use injected attribute as locator - guaranteed to work!
|
|
121
|
+
locator: `[data-browser-agent-id="${highlightId}"]`
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return results;
|
|
126
|
+
})()
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Purpose: Intelligent page scrolling with AI strategy selection and fallback mechanisms
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [playwright Page, connectonion llm_do, pydantic, pathlib, PIL Image] | imported by [cli/browser_agent/browser.py] | tested by [tests/cli/test_scroll.py]
|
|
5
|
+
Data flow: scroll(page, take_screenshot, times, description) → takes before screenshot → tries strategies: AI-generated JS → element scroll → page scroll → takes after screenshot → compares via _screenshots_different() → returns on first successful change | _ai_scroll() extracts scrollable elements + HTML → llm_do generates ScrollStrategy → executes JS | fallbacks use simpler JS approaches
|
|
6
|
+
State/Effects: writes before/after screenshots to screenshots/ directory | executes JavaScript on page (modifies scrollTop or window.scrollY) | no persistent state
|
|
7
|
+
Integration: exposes scroll(page, take_screenshot, times, description) → str | ScrollStrategy Pydantic model with method, selector, javascript, explanation | uses scroll_strategy.md prompt for LLM | verifies success via pixel difference (>1% change threshold)
|
|
8
|
+
Performance: tries AI first (slower but accurate) → falls back to faster heuristics | 0.5-1s sleep between scrolls for content loading | PIL pixel comparison (fast for typical screenshots)
|
|
9
|
+
Errors: returns "Browser not open" if page None | returns "All scroll strategies failed" if no strategy changes content | prints strategy attempts for debugging | catches exceptions per strategy and continues
|
|
10
|
+
Unified scroll module - AI-powered with fallback strategies.
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
from scroll import scroll
|
|
14
|
+
result = scroll(page, take_screenshot, times=5, description="the email list")
|
|
15
|
+
"""
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from pydantic import BaseModel
|
|
18
|
+
from connectonion import llm_do
|
|
19
|
+
import time
|
|
20
|
+
|
|
21
|
+
_PROMPT = (Path(__file__).parent / "prompts" / "scroll_strategy.md").read_text()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ScrollStrategy(BaseModel):
|
|
25
|
+
method: str # "window", "element", "container"
|
|
26
|
+
selector: str
|
|
27
|
+
javascript: str
|
|
28
|
+
explanation: str
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def scroll(page, take_screenshot, times: int = 5, description: str = "the main content area") -> str:
|
|
32
|
+
"""Universal scroll with AI strategy and fallback.
|
|
33
|
+
|
|
34
|
+
Tries: AI-generated → Element scroll → Page scroll
|
|
35
|
+
Verifies success with screenshot comparison.
|
|
36
|
+
"""
|
|
37
|
+
if not page:
|
|
38
|
+
return "Browser not open"
|
|
39
|
+
|
|
40
|
+
timestamp = int(time.time())
|
|
41
|
+
before = f"scroll_before_{timestamp}.png"
|
|
42
|
+
take_screenshot(path=before)
|
|
43
|
+
|
|
44
|
+
strategies = [
|
|
45
|
+
("AI strategy", lambda: _ai_scroll(page, times, description)),
|
|
46
|
+
("Element scroll", lambda: _element_scroll(page, times)),
|
|
47
|
+
("Page scroll", lambda: _page_scroll(page, times)),
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
for name, execute in strategies:
|
|
51
|
+
print(f" Trying: {name}...")
|
|
52
|
+
try:
|
|
53
|
+
execute()
|
|
54
|
+
time.sleep(0.5)
|
|
55
|
+
after = f"scroll_after_{timestamp}.png"
|
|
56
|
+
take_screenshot(path=after)
|
|
57
|
+
|
|
58
|
+
if _screenshots_different(before, after):
|
|
59
|
+
print(f" ✅ {name} worked")
|
|
60
|
+
return f"Scrolled using {name}"
|
|
61
|
+
print(f" ⚠️ {name} didn't change content")
|
|
62
|
+
before = after
|
|
63
|
+
except Exception as e:
|
|
64
|
+
print(f" ❌ {name} failed: {e}")
|
|
65
|
+
|
|
66
|
+
return "All scroll strategies failed"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _ai_scroll(page, times: int, description: str):
|
|
70
|
+
"""AI-generated scroll strategy."""
|
|
71
|
+
scrollable = page.evaluate("""
|
|
72
|
+
(() => {
|
|
73
|
+
return Array.from(document.querySelectorAll('*'))
|
|
74
|
+
.filter(el => {
|
|
75
|
+
const s = window.getComputedStyle(el);
|
|
76
|
+
return (s.overflow === 'auto' || s.overflowY === 'scroll') &&
|
|
77
|
+
el.scrollHeight > el.clientHeight;
|
|
78
|
+
})
|
|
79
|
+
.slice(0, 3)
|
|
80
|
+
.map(el => ({tag: el.tagName, classes: el.className, id: el.id}));
|
|
81
|
+
})()
|
|
82
|
+
""")
|
|
83
|
+
|
|
84
|
+
html = page.evaluate("""
|
|
85
|
+
(() => {
|
|
86
|
+
const c = document.body.cloneNode(true);
|
|
87
|
+
c.querySelectorAll('script,style,img,svg').forEach(e => e.remove());
|
|
88
|
+
return c.innerHTML.substring(0, 5000);
|
|
89
|
+
})()
|
|
90
|
+
""")
|
|
91
|
+
|
|
92
|
+
strategy = llm_do(
|
|
93
|
+
_PROMPT.format(description=description, scrollable_elements=scrollable, simplified_html=html),
|
|
94
|
+
output=ScrollStrategy,
|
|
95
|
+
model="co/gemini-2.5-flash",
|
|
96
|
+
temperature=0.1
|
|
97
|
+
)
|
|
98
|
+
print(f" AI: {strategy.explanation}")
|
|
99
|
+
|
|
100
|
+
for _ in range(times):
|
|
101
|
+
page.evaluate(strategy.javascript)
|
|
102
|
+
time.sleep(1)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _element_scroll(page, times: int):
|
|
106
|
+
"""Scroll first scrollable element found."""
|
|
107
|
+
for _ in range(times):
|
|
108
|
+
page.evaluate("""
|
|
109
|
+
(() => {
|
|
110
|
+
const el = Array.from(document.querySelectorAll('*')).find(e => {
|
|
111
|
+
const s = window.getComputedStyle(e);
|
|
112
|
+
return (s.overflow === 'auto' || s.overflowY === 'scroll') &&
|
|
113
|
+
e.scrollHeight > e.clientHeight;
|
|
114
|
+
});
|
|
115
|
+
if (el) el.scrollTop += 1000;
|
|
116
|
+
})()
|
|
117
|
+
""")
|
|
118
|
+
time.sleep(0.8)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _page_scroll(page, times: int):
|
|
122
|
+
"""Scroll window."""
|
|
123
|
+
for _ in range(times):
|
|
124
|
+
page.evaluate("window.scrollBy(0, 1000)")
|
|
125
|
+
time.sleep(0.8)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _screenshots_different(file1: str, file2: str) -> bool:
|
|
129
|
+
"""Compare screenshots using PIL pixel difference."""
|
|
130
|
+
try:
|
|
131
|
+
from PIL import Image
|
|
132
|
+
import os
|
|
133
|
+
|
|
134
|
+
img1 = Image.open(os.path.join("screenshots", file1)).convert('RGB')
|
|
135
|
+
img2 = Image.open(os.path.join("screenshots", file2)).convert('RGB')
|
|
136
|
+
|
|
137
|
+
diff = sum(
|
|
138
|
+
abs(a - b)
|
|
139
|
+
for p1, p2 in zip(img1.getdata(), img2.getdata())
|
|
140
|
+
for a, b in zip(p1, p2)
|
|
141
|
+
)
|
|
142
|
+
threshold = img1.size[0] * img1.size[1] * 3 * 0.01 # 1%
|
|
143
|
+
return diff > threshold
|
|
144
|
+
except Exception:
|
|
145
|
+
return True # Assume different if comparison fails
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Main coding agent module."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from .context import load_project_context
|
|
6
|
+
from .prompts.assembler import assemble_prompt
|
|
7
|
+
from .tools import (
|
|
8
|
+
glob, grep, edit, read_file, task,
|
|
9
|
+
enter_plan_mode, exit_plan_mode, write_plan,
|
|
10
|
+
ask_user,
|
|
11
|
+
run_background, task_output, kill_task,
|
|
12
|
+
load_guide,
|
|
13
|
+
)
|
|
14
|
+
from .skills import skill
|
|
15
|
+
from .plugins import reminder_plugin
|
|
16
|
+
from connectonion import Agent, bash, after_user_input, FileWriter, MODE_AUTO, MODE_NORMAL, TodoList
|
|
17
|
+
from connectonion.useful_plugins import re_act, eval
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
PROMPTS_DIR = Path(__file__).parent / "prompts"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@after_user_input
|
|
24
|
+
def _sync_tool_io(agent) -> None:
|
|
25
|
+
io = getattr(agent, "io", None) or getattr(agent, "connection", None)
|
|
26
|
+
if not io:
|
|
27
|
+
return
|
|
28
|
+
# ToolRegistry does not expose instances publicly; use best-effort access.
|
|
29
|
+
instances = getattr(agent.tools, "_instances", {})
|
|
30
|
+
for instance in instances.values():
|
|
31
|
+
if hasattr(instance, "io"):
|
|
32
|
+
instance.io = io
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def create_coding_agent(
|
|
36
|
+
model: str = "co/claude-opus-4-5",
|
|
37
|
+
max_iterations: int = 20,
|
|
38
|
+
auto_approve: bool = False,
|
|
39
|
+
web_mode: bool = False,
|
|
40
|
+
) -> Agent:
|
|
41
|
+
writer = FileWriter(mode=MODE_AUTO if auto_approve else MODE_NORMAL)
|
|
42
|
+
todo = TodoList()
|
|
43
|
+
|
|
44
|
+
tools = [
|
|
45
|
+
glob,
|
|
46
|
+
grep,
|
|
47
|
+
read_file,
|
|
48
|
+
edit,
|
|
49
|
+
writer,
|
|
50
|
+
bash,
|
|
51
|
+
task,
|
|
52
|
+
enter_plan_mode,
|
|
53
|
+
exit_plan_mode,
|
|
54
|
+
write_plan,
|
|
55
|
+
todo,
|
|
56
|
+
skill,
|
|
57
|
+
run_background,
|
|
58
|
+
task_output,
|
|
59
|
+
kill_task,
|
|
60
|
+
load_guide,
|
|
61
|
+
ask_user,
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
base_prompt = assemble_prompt(
|
|
65
|
+
prompts_dir=str(PROMPTS_DIR),
|
|
66
|
+
tools=tools,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
project_context = load_project_context()
|
|
70
|
+
system_prompt = base_prompt
|
|
71
|
+
if project_context:
|
|
72
|
+
system_prompt += f"\n\n---\n\n{project_context}"
|
|
73
|
+
|
|
74
|
+
plugins = [re_act, eval, reminder_plugin]
|
|
75
|
+
|
|
76
|
+
agent = Agent(
|
|
77
|
+
name="oo",
|
|
78
|
+
tools=tools,
|
|
79
|
+
plugins=plugins,
|
|
80
|
+
on_events=[_sync_tool_io],
|
|
81
|
+
system_prompt=system_prompt,
|
|
82
|
+
model=model,
|
|
83
|
+
max_iterations=max_iterations,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
agent.writer = writer
|
|
87
|
+
return agent
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Sub-agent registry and factory."""
|
|
2
|
+
|
|
3
|
+
from typing import Dict, Any, Optional
|
|
4
|
+
from connectonion import Agent
|
|
5
|
+
|
|
6
|
+
from connectonion.cli.co_ai.tools import glob, grep, read_file
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Sub-agent configurations
|
|
10
|
+
SUBAGENTS: Dict[str, Dict[str, Any]] = {
|
|
11
|
+
"explore": {
|
|
12
|
+
"description": "Fast agent for exploring codebases. Find files, search code, answer questions about structure.",
|
|
13
|
+
"tools": [glob, grep, read_file],
|
|
14
|
+
"model": "co/gemini-2.5-flash", # Fast model for exploration
|
|
15
|
+
"max_iterations": 15,
|
|
16
|
+
},
|
|
17
|
+
"plan": {
|
|
18
|
+
"description": "Design implementation plans. Analyze architecture, identify files to change, plan steps.",
|
|
19
|
+
"tools": [glob, grep, read_file],
|
|
20
|
+
"model": "co/gemini-2.5-pro", # Smarter model for planning
|
|
21
|
+
"max_iterations": 10,
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_subagent(agent_type: str) -> Optional[Agent]:
|
|
27
|
+
"""
|
|
28
|
+
Create a sub-agent instance by type.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
agent_type: Type of sub-agent ("explore", "plan", etc.)
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Configured Agent instance or None if type not found
|
|
35
|
+
"""
|
|
36
|
+
if agent_type not in SUBAGENTS:
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
config = SUBAGENTS[agent_type]
|
|
40
|
+
|
|
41
|
+
# Load prompt from co_ai/prompts/agents/
|
|
42
|
+
from pathlib import Path
|
|
43
|
+
prompt_path = Path(__file__).parent.parent / "prompts" / "agents" / f"{agent_type}.md"
|
|
44
|
+
|
|
45
|
+
if prompt_path.exists():
|
|
46
|
+
system_prompt = prompt_path.read_text(encoding="utf-8")
|
|
47
|
+
else:
|
|
48
|
+
system_prompt = f"You are an {agent_type} agent. {config['description']}"
|
|
49
|
+
|
|
50
|
+
return Agent(
|
|
51
|
+
name=f"oo-{agent_type}",
|
|
52
|
+
tools=config["tools"],
|
|
53
|
+
plugins=[],
|
|
54
|
+
system_prompt=system_prompt,
|
|
55
|
+
model=config["model"],
|
|
56
|
+
max_iterations=config["max_iterations"],
|
|
57
|
+
)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Built-in commands for OO CLI."""
|
|
2
|
+
|
|
3
|
+
from connectonion.cli.co_ai.commands.init import cmd_init
|
|
4
|
+
from connectonion.cli.co_ai.commands.help import cmd_help
|
|
5
|
+
from connectonion.cli.co_ai.commands.cost import cmd_cost, set_agent as set_cost_agent
|
|
6
|
+
from connectonion.cli.co_ai.commands.compact import cmd_compact, set_agent as set_compact_agent
|
|
7
|
+
from connectonion.cli.co_ai.commands.tasks import cmd_tasks
|
|
8
|
+
from connectonion.cli.co_ai.commands.export import cmd_export, set_agent as set_export_agent
|
|
9
|
+
from connectonion.cli.co_ai.commands.sessions import cmd_sessions, cmd_new, cmd_resume, set_agent as set_sessions_agent
|
|
10
|
+
from connectonion.cli.co_ai.commands.undo import cmd_undo, cmd_redo, set_agent as set_undo_agent
|
|
11
|
+
|
|
12
|
+
BUILTIN_COMMANDS = {
|
|
13
|
+
"init": cmd_init,
|
|
14
|
+
"help": cmd_help,
|
|
15
|
+
"cost": cmd_cost,
|
|
16
|
+
"compact": cmd_compact,
|
|
17
|
+
"tasks": cmd_tasks,
|
|
18
|
+
"export": cmd_export,
|
|
19
|
+
"sessions": cmd_sessions,
|
|
20
|
+
"new": cmd_new,
|
|
21
|
+
"resume": cmd_resume,
|
|
22
|
+
"undo": cmd_undo,
|
|
23
|
+
"redo": cmd_redo,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def set_agent_for_commands(agent):
|
|
28
|
+
"""Set agent reference for commands that need it."""
|
|
29
|
+
set_cost_agent(agent)
|
|
30
|
+
set_compact_agent(agent)
|
|
31
|
+
set_export_agent(agent)
|
|
32
|
+
set_sessions_agent(agent)
|
|
33
|
+
set_undo_agent(agent)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
__all__ = [
|
|
37
|
+
"BUILTIN_COMMANDS",
|
|
38
|
+
"cmd_init",
|
|
39
|
+
"cmd_help",
|
|
40
|
+
"cmd_cost",
|
|
41
|
+
"cmd_compact",
|
|
42
|
+
"cmd_tasks",
|
|
43
|
+
"cmd_export",
|
|
44
|
+
"set_agent_for_commands",
|
|
45
|
+
]
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""Compact command for compressing conversation context using LLM summarization."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
from rich.panel import Panel
|
|
6
|
+
from connectonion import llm_do
|
|
7
|
+
|
|
8
|
+
console = Console()
|
|
9
|
+
|
|
10
|
+
# Module-level storage for agent reference
|
|
11
|
+
_current_agent = None
|
|
12
|
+
|
|
13
|
+
# Summarization prompt
|
|
14
|
+
SUMMARIZATION_PROMPT = Path(__file__).parent.parent / "prompts" / "summarization.md"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def set_agent(agent):
|
|
18
|
+
"""Set the current agent for compact operation."""
|
|
19
|
+
global _current_agent
|
|
20
|
+
_current_agent = agent
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _format_messages_for_summary(messages: list) -> str:
|
|
24
|
+
"""Format messages into a readable format for summarization."""
|
|
25
|
+
formatted = []
|
|
26
|
+
for msg in messages:
|
|
27
|
+
role = msg.get('role', 'unknown')
|
|
28
|
+
content = msg.get('content', '')
|
|
29
|
+
|
|
30
|
+
# Handle tool_calls in assistant messages
|
|
31
|
+
if role == 'assistant' and 'tool_calls' in msg:
|
|
32
|
+
tool_calls = msg.get('tool_calls', [])
|
|
33
|
+
tools_str = ", ".join(tc.get('function', {}).get('name', 'unknown') for tc in tool_calls)
|
|
34
|
+
formatted.append(f"[assistant] Called tools: {tools_str}")
|
|
35
|
+
if content:
|
|
36
|
+
formatted.append(f"[assistant] {content[:500]}...")
|
|
37
|
+
elif role == 'tool':
|
|
38
|
+
# Truncate long tool results
|
|
39
|
+
tool_name = msg.get('name', 'unknown')
|
|
40
|
+
result = content[:200] + "..." if len(content) > 200 else content
|
|
41
|
+
formatted.append(f"[tool:{tool_name}] {result}")
|
|
42
|
+
elif role == 'system':
|
|
43
|
+
# Keep system messages brief
|
|
44
|
+
formatted.append(f"[system] {content[:300]}...")
|
|
45
|
+
else:
|
|
46
|
+
formatted.append(f"[{role}] {content}")
|
|
47
|
+
|
|
48
|
+
return "\n\n".join(formatted)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _create_summary_message(summary: str) -> dict:
|
|
52
|
+
"""Create a summary message to replace old context."""
|
|
53
|
+
return {
|
|
54
|
+
'role': 'user',
|
|
55
|
+
'content': f"""## Previous Conversation Summary
|
|
56
|
+
|
|
57
|
+
{summary}
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
*The conversation continues below. Use the summary above for context.*"""
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def cmd_compact(args: str = "") -> str:
|
|
65
|
+
"""
|
|
66
|
+
Compress conversation history using LLM summarization.
|
|
67
|
+
|
|
68
|
+
This creates an intelligent summary of older messages while preserving:
|
|
69
|
+
- User's explicit requests and intents
|
|
70
|
+
- Key technical decisions and code patterns
|
|
71
|
+
- File names and important code snippets
|
|
72
|
+
- Errors encountered and how they were fixed
|
|
73
|
+
- Recent messages (last 5)
|
|
74
|
+
|
|
75
|
+
Use when context usage is high (>70%).
|
|
76
|
+
"""
|
|
77
|
+
if _current_agent is None:
|
|
78
|
+
console.print("[yellow]No agent session active.[/]")
|
|
79
|
+
return "No session"
|
|
80
|
+
|
|
81
|
+
agent = _current_agent
|
|
82
|
+
|
|
83
|
+
# Check if we have a session
|
|
84
|
+
if not hasattr(agent, 'current_session') or not agent.current_session:
|
|
85
|
+
console.print("[yellow]No conversation history to compact.[/]")
|
|
86
|
+
return "No history"
|
|
87
|
+
|
|
88
|
+
messages = agent.current_session.get('messages', [])
|
|
89
|
+
if len(messages) < 8:
|
|
90
|
+
console.print("[yellow]Conversation too short to compact (< 8 messages).[/]")
|
|
91
|
+
return "Too short"
|
|
92
|
+
|
|
93
|
+
# Get context usage before
|
|
94
|
+
context_before = getattr(agent, 'context_percent', 0)
|
|
95
|
+
|
|
96
|
+
# Separate messages
|
|
97
|
+
system_msg = messages[0] if messages and messages[0].get('role') == 'system' else None
|
|
98
|
+
recent_count = 5
|
|
99
|
+
recent_msgs = messages[-recent_count:]
|
|
100
|
+
old_msgs = messages[1:-recent_count] if system_msg else messages[:-recent_count]
|
|
101
|
+
|
|
102
|
+
if len(old_msgs) < 3:
|
|
103
|
+
console.print("[yellow]Not enough old messages to compact.[/]")
|
|
104
|
+
return "Nothing to compact"
|
|
105
|
+
|
|
106
|
+
console.print("[cyan]Summarizing conversation...[/]")
|
|
107
|
+
|
|
108
|
+
# Load summarization prompt
|
|
109
|
+
summarization_instructions = ""
|
|
110
|
+
if SUMMARIZATION_PROMPT.exists():
|
|
111
|
+
summarization_instructions = SUMMARIZATION_PROMPT.read_text(encoding="utf-8")
|
|
112
|
+
|
|
113
|
+
# Format messages for summarization
|
|
114
|
+
conversation_text = _format_messages_for_summary(old_msgs)
|
|
115
|
+
|
|
116
|
+
# Use LLM to create intelligent summary
|
|
117
|
+
summary_prompt = f"""{summarization_instructions}
|
|
118
|
+
|
|
119
|
+
## Conversation to Summarize
|
|
120
|
+
|
|
121
|
+
{conversation_text}
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
Create a concise but complete summary following the structure above. Focus on:
|
|
126
|
+
1. What the user wanted to accomplish
|
|
127
|
+
2. Key files and code that were discussed or modified
|
|
128
|
+
3. Any errors and how they were fixed
|
|
129
|
+
4. Important decisions made
|
|
130
|
+
|
|
131
|
+
Keep the summary under 1000 words but preserve all critical technical details."""
|
|
132
|
+
|
|
133
|
+
summary = llm_do(
|
|
134
|
+
summary_prompt,
|
|
135
|
+
model="co/gemini-2.5-flash", # Fast model for summarization
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Create compacted messages
|
|
139
|
+
summary_message = _create_summary_message(summary)
|
|
140
|
+
|
|
141
|
+
new_messages = []
|
|
142
|
+
if system_msg:
|
|
143
|
+
new_messages.append(system_msg)
|
|
144
|
+
new_messages.append(summary_message)
|
|
145
|
+
new_messages.extend(recent_msgs)
|
|
146
|
+
|
|
147
|
+
# Update agent session
|
|
148
|
+
agent.current_session['messages'] = new_messages
|
|
149
|
+
|
|
150
|
+
# Calculate savings
|
|
151
|
+
old_count = len(messages)
|
|
152
|
+
new_count = len(new_messages)
|
|
153
|
+
saved = old_count - new_count
|
|
154
|
+
|
|
155
|
+
# Display result
|
|
156
|
+
console.print(Panel(
|
|
157
|
+
f"[green]✓ Conversation compacted[/]\n\n"
|
|
158
|
+
f"Messages: {old_count} → {new_count} ([green]-{saved}[/])\n"
|
|
159
|
+
f"Context before: {context_before:.0f}%\n\n"
|
|
160
|
+
f"[dim]Preserved:[/]\n"
|
|
161
|
+
f" • System prompt\n"
|
|
162
|
+
f" • AI-generated summary of older context\n"
|
|
163
|
+
f" • Recent {recent_count} messages\n\n"
|
|
164
|
+
f"[dim]Summary includes:[/]\n"
|
|
165
|
+
f" • User requests and intents\n"
|
|
166
|
+
f" • Key files and code patterns\n"
|
|
167
|
+
f" • Errors and fixes\n"
|
|
168
|
+
f" • Technical decisions",
|
|
169
|
+
title="📦 Compact",
|
|
170
|
+
border_style="green"
|
|
171
|
+
))
|
|
172
|
+
|
|
173
|
+
return f"Compacted: {old_count} → {new_count} messages"
|