connectonion 0.6.2__py3-none-any.whl → 0.6.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +13 -3
- connectonion/cli/browser_agent/element_finder.py +8 -0
- connectonion/cli/browser_agent/highlight_screenshot.py +9 -1
- connectonion/cli/browser_agent/scroll.py +8 -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 +5 -0
- connectonion/cli/co_ai/plugins/system_reminder.py +154 -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/summarization.md +55 -0
- connectonion/cli/co_ai/prompts/system-reminders/agent.md +23 -0
- connectonion/cli/co_ai/prompts/system-reminders/plan_mode.md +13 -0
- connectonion/cli/co_ai/prompts/system-reminders/security.md +14 -0
- connectonion/cli/co_ai/prompts/system-reminders/simplicity.md +14 -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/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 +169 -0
- connectonion/cli/co_ai/tools/read.py +61 -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 +101 -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_plugins/tool_approval.md +139 -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 +3 -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/tool_approval.py +233 -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.2.dist-info → connectonion-0.6.4.dist-info}/METADATA +10 -3
- connectonion-0.6.4.dist-info/RECORD +472 -0
- connectonion/network/asgi.py +0 -407
- connectonion/network/host.py +0 -616
- connectonion/network/trust.py +0 -166
- connectonion-0.6.2.dist-info/RECORD +0 -129
- /connectonion/cli/{docs → co_ai/prompts/connectonion}/connectonion.md +0 -0
- {connectonion-0.6.2.dist-info → connectonion-0.6.4.dist-info}/WHEEL +0 -0
- {connectonion-0.6.2.dist-info → connectonion-0.6.4.dist-info}/entry_points.txt +0 -0
connectonion/tui/footer.py
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
"""
|
|
2
|
+
Purpose: Simple footer tips display for terminal UI
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [rich.text.Text] | imported by [tui/chat.py, tui/input.py] | tested by [tests/tui/test_footer.py]
|
|
5
|
+
Data flow: Footer(tips) → render() → formats tips as dimmed text with separators
|
|
6
|
+
State/Effects: no state (pure function)
|
|
7
|
+
Integration: exposes Footer(tips: list[str]) with render() → Text | displays help hints at bottom of TUI
|
|
8
|
+
Performance: trivial (string join)
|
|
9
|
+
Errors: none
|
|
2
10
|
Footer - Simple tips display.
|
|
3
11
|
|
|
4
12
|
Usage:
|
connectonion/tui/fuzzy.py
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Purpose: Fuzzy string matching for autocomplete with scoring and highlight positions
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [rich.text.Text] | imported by [tui/dropdown.py, tui/providers.py, tui/input.py] | tested by [tests/tui/test_fuzzy.py]
|
|
5
|
+
Data flow: fuzzy_match(query, text) → finds characters from query in text → calculates score based on sequential matches → returns (matched, score, positions) | highlight_match(text, positions) → creates Rich Text with highlighted characters
|
|
6
|
+
State/Effects: no state (pure functions)
|
|
7
|
+
Integration: exposes fuzzy_match(query, text) → (bool, int, list[int]), highlight_match(text, positions, highlight_style) → Text | used by autocomplete providers for filtering and highlighting
|
|
8
|
+
Performance: O(n*m) matching (acceptable for short strings) | early exit if no match
|
|
9
|
+
Errors: none (handles empty query)
|
|
10
|
+
Fuzzy matching utilities.
|
|
11
|
+
"""
|
|
2
12
|
|
|
3
13
|
from rich.text import Text
|
|
4
14
|
|
connectonion/tui/input.py
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Purpose: Smart terminal input component with trigger-based autocomplete and bracketed paste support
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [rich.console/live, tui/keys.py, tui/dropdown.py, tui/providers.py, tui/status_bar.py] | imported by [tui/chat.py, cli/commands/] | tested by [tests/tui/test_input.py]
|
|
5
|
+
Data flow: Input(prompt, triggers, on_submit) → read_input() enables bracketed paste → keys.read_key() captures input → handles triggers (/, @) → providers.search() filters items → Dropdown renders matches → arrow keys navigate → Enter selects/submits → returns final value
|
|
6
|
+
State/Effects: modifies terminal (enables bracketed paste, raw mode) | restores terminal on exit | maintains buffer state during input session
|
|
7
|
+
Integration: exposes Input(prompt, placeholder, triggers, status_segments, on_submit) with read_input() → str | triggers dict maps trigger char to Provider | uses keys.py for raw input, dropdown.py for rendering, providers.py for search
|
|
8
|
+
Performance: live terminal updates via Rich Live | efficient re-render only on buffer/dropdown changes | bracketed paste handles large pastes atomically
|
|
9
|
+
Errors: restores terminal mode on exception | handles paste detection failures gracefully
|
|
10
|
+
Input - smart input component with triggers and autocomplete.
|
|
2
11
|
|
|
3
12
|
Clean, minimal design that works on light and dark terminals.
|
|
4
13
|
Inspired by powerlevel10k terminal prompts.
|
|
14
|
+
|
|
15
|
+
Features:
|
|
16
|
+
- Trigger-based autocomplete (e.g., @ for files, / for commands)
|
|
17
|
+
- Arrow key navigation in dropdown
|
|
18
|
+
- Bracketed paste mode for reliable paste handling
|
|
19
|
+
- Keyboard shortcuts (Shift+Tab, Escape, etc.)
|
|
20
|
+
|
|
21
|
+
Paste Handling:
|
|
22
|
+
Uses bracketed paste mode to detect and handle pasted text atomically.
|
|
23
|
+
This prevents display glitches when pasting (multiple prompt lines,
|
|
24
|
+
truncated text). The entire paste is received as one event and
|
|
25
|
+
added to the buffer in a single operation.
|
|
5
26
|
"""
|
|
6
27
|
|
|
7
28
|
import random
|
|
@@ -10,7 +31,7 @@ from rich.console import Console, Group
|
|
|
10
31
|
from rich.text import Text
|
|
11
32
|
from rich.live import Live
|
|
12
33
|
|
|
13
|
-
from .keys import read_key
|
|
34
|
+
from .keys import read_key, enable_bracketed_paste, disable_bracketed_paste
|
|
14
35
|
from .dropdown import Dropdown
|
|
15
36
|
from .providers import FileProvider
|
|
16
37
|
|
|
@@ -59,6 +80,7 @@ class Input:
|
|
|
59
80
|
max_visible: int = 8,
|
|
60
81
|
console: Console = None,
|
|
61
82
|
style: str = "modern",
|
|
83
|
+
on_special_key: callable = None,
|
|
62
84
|
):
|
|
63
85
|
"""
|
|
64
86
|
Args:
|
|
@@ -70,6 +92,7 @@ class Input:
|
|
|
70
92
|
max_visible: Max dropdown items
|
|
71
93
|
console: Rich console
|
|
72
94
|
style: "modern", "minimal", or "classic"
|
|
95
|
+
on_special_key: Callback for special keys (shift+tab, etc). Return True to consume.
|
|
73
96
|
"""
|
|
74
97
|
self.prompt = prompt
|
|
75
98
|
self.triggers = triggers or {}
|
|
@@ -79,6 +102,7 @@ class Input:
|
|
|
79
102
|
self.max_visible = max_visible
|
|
80
103
|
self.console = console or Console()
|
|
81
104
|
self.style = style
|
|
105
|
+
self.on_special_key = on_special_key
|
|
82
106
|
|
|
83
107
|
# State
|
|
84
108
|
self.buffer = ""
|
|
@@ -192,87 +216,111 @@ class Input:
|
|
|
192
216
|
global _input_count
|
|
193
217
|
_input_count += 1
|
|
194
218
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
219
|
+
# Enable bracketed paste mode for proper paste detection
|
|
220
|
+
enable_bracketed_paste()
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
with Live(self._render(), console=self.console, auto_refresh=False) as live:
|
|
224
|
+
while True:
|
|
225
|
+
key = read_key()
|
|
226
|
+
|
|
227
|
+
# Handle pasted text (from bracketed paste mode)
|
|
228
|
+
if key.startswith('paste:'):
|
|
229
|
+
pasted_text = key[6:] # Remove 'paste:' prefix
|
|
230
|
+
if self.active_trigger:
|
|
231
|
+
self.filter_text += pasted_text
|
|
232
|
+
self._update_dropdown()
|
|
233
|
+
else:
|
|
234
|
+
self.buffer += pasted_text
|
|
235
|
+
live.update(self._render(), refresh=True)
|
|
236
|
+
continue
|
|
237
|
+
|
|
238
|
+
# Special key callback (shift+tab, etc)
|
|
239
|
+
if self.on_special_key and key in ('shift+tab',):
|
|
240
|
+
if self.on_special_key(key):
|
|
241
|
+
live.update(self._render(), refresh=True)
|
|
242
|
+
continue
|
|
243
|
+
|
|
244
|
+
# Enter - submit or accept selection
|
|
245
|
+
if key in ('\r', '\n'):
|
|
246
|
+
if self.active_trigger:
|
|
247
|
+
if not self.dropdown.is_empty:
|
|
248
|
+
if self._accept_selection():
|
|
249
|
+
live.update(self._render(), refresh=True)
|
|
250
|
+
continue
|
|
251
|
+
live.update(self._render(), refresh=True)
|
|
252
|
+
else:
|
|
253
|
+
self._exit_autocomplete()
|
|
254
|
+
live.update(self._render(), refresh=True)
|
|
255
|
+
else:
|
|
256
|
+
return self.buffer
|
|
198
257
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if not self.dropdown.is_empty:
|
|
258
|
+
# Tab - accept selection
|
|
259
|
+
elif key == '\t':
|
|
260
|
+
if self.active_trigger and not self.dropdown.is_empty:
|
|
203
261
|
if self._accept_selection():
|
|
204
262
|
live.update(self._render(), refresh=True)
|
|
205
263
|
continue
|
|
206
264
|
live.update(self._render(), refresh=True)
|
|
207
|
-
|
|
265
|
+
|
|
266
|
+
# Escape - cancel autocomplete
|
|
267
|
+
elif key == 'esc':
|
|
268
|
+
if self.active_trigger:
|
|
269
|
+
if self.buffer.endswith(self.active_trigger):
|
|
270
|
+
self.buffer = self.buffer[:-1]
|
|
208
271
|
self._exit_autocomplete()
|
|
209
272
|
live.update(self._render(), refresh=True)
|
|
210
|
-
else:
|
|
211
|
-
return self.buffer
|
|
212
273
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
274
|
+
# Ctrl+C / Ctrl+D
|
|
275
|
+
elif key == '\x03':
|
|
276
|
+
raise KeyboardInterrupt()
|
|
277
|
+
elif key == '\x04':
|
|
278
|
+
raise EOFError()
|
|
279
|
+
|
|
280
|
+
# Backspace
|
|
281
|
+
elif key in ('\x7f', '\x08'):
|
|
282
|
+
if self.active_trigger:
|
|
283
|
+
if self.filter_text:
|
|
284
|
+
self.filter_text = self.filter_text[:-1]
|
|
285
|
+
self._update_dropdown()
|
|
286
|
+
else:
|
|
287
|
+
provider = self.triggers.get(self.active_trigger)
|
|
288
|
+
if isinstance(provider, FileProvider) and provider.context:
|
|
289
|
+
provider.back()
|
|
290
|
+
self._update_dropdown()
|
|
291
|
+
else:
|
|
292
|
+
if self.buffer.endswith(self.active_trigger):
|
|
293
|
+
self.buffer = self.buffer[:-1]
|
|
294
|
+
self._exit_autocomplete()
|
|
217
295
|
live.update(self._render(), refresh=True)
|
|
218
|
-
|
|
296
|
+
elif self.buffer:
|
|
297
|
+
self.buffer = self.buffer[:-1]
|
|
298
|
+
live.update(self._render(), refresh=True)
|
|
299
|
+
|
|
300
|
+
# Arrow keys
|
|
301
|
+
elif key == 'up' and self.active_trigger:
|
|
302
|
+
self.dropdown.up()
|
|
303
|
+
live.update(self._render(), refresh=True)
|
|
304
|
+
elif key == 'down' and self.active_trigger:
|
|
305
|
+
self.dropdown.down()
|
|
219
306
|
live.update(self._render(), refresh=True)
|
|
220
307
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
self.
|
|
308
|
+
# Trigger char
|
|
309
|
+
elif key in self.triggers:
|
|
310
|
+
self.active_trigger = key
|
|
311
|
+
self.filter_text = ""
|
|
312
|
+
self.buffer += key
|
|
313
|
+
self._update_dropdown()
|
|
227
314
|
live.update(self._render(), refresh=True)
|
|
228
315
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
raise EOFError()
|
|
234
|
-
|
|
235
|
-
# Backspace
|
|
236
|
-
elif key in ('\x7f', '\x08'):
|
|
237
|
-
if self.active_trigger:
|
|
238
|
-
if self.filter_text:
|
|
239
|
-
self.filter_text = self.filter_text[:-1]
|
|
316
|
+
# Regular input (single char)
|
|
317
|
+
elif len(key) == 1 and key.isprintable():
|
|
318
|
+
if self.active_trigger:
|
|
319
|
+
self.filter_text += key
|
|
240
320
|
self._update_dropdown()
|
|
241
321
|
else:
|
|
242
|
-
|
|
243
|
-
if isinstance(provider, FileProvider) and provider.context:
|
|
244
|
-
provider.back()
|
|
245
|
-
self._update_dropdown()
|
|
246
|
-
else:
|
|
247
|
-
if self.buffer.endswith(self.active_trigger):
|
|
248
|
-
self.buffer = self.buffer[:-1]
|
|
249
|
-
self._exit_autocomplete()
|
|
322
|
+
self.buffer += key
|
|
250
323
|
live.update(self._render(), refresh=True)
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
# Arrow keys
|
|
256
|
-
elif key == 'up' and self.active_trigger:
|
|
257
|
-
self.dropdown.up()
|
|
258
|
-
live.update(self._render(), refresh=True)
|
|
259
|
-
elif key == 'down' and self.active_trigger:
|
|
260
|
-
self.dropdown.down()
|
|
261
|
-
live.update(self._render(), refresh=True)
|
|
262
|
-
|
|
263
|
-
# Trigger char
|
|
264
|
-
elif key in self.triggers:
|
|
265
|
-
self.active_trigger = key
|
|
266
|
-
self.filter_text = ""
|
|
267
|
-
self.buffer += key
|
|
268
|
-
self._update_dropdown()
|
|
269
|
-
live.update(self._render(), refresh=True)
|
|
270
|
-
|
|
271
|
-
# Regular input
|
|
272
|
-
elif key.isprintable():
|
|
273
|
-
if self.active_trigger:
|
|
274
|
-
self.filter_text += key
|
|
275
|
-
self._update_dropdown()
|
|
276
|
-
else:
|
|
277
|
-
self.buffer += key
|
|
278
|
-
live.update(self._render(), refresh=True)
|
|
324
|
+
finally:
|
|
325
|
+
# Always disable bracketed paste mode
|
|
326
|
+
disable_bracketed_paste()
|
connectonion/tui/keys.py
CHANGED
|
@@ -1,10 +1,72 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Purpose: Low-level keyboard input primitives with bracketed paste and arrow key support
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [sys, tty, termios, select] | imported by [tui/input.py] | tested by [tests/tui/test_keys.py]
|
|
5
|
+
Data flow: enable_bracketed_paste() sends ESC[?2004h → read_key() reads from sys.stdin.buffer → detects paste markers (ESC[200~/ESC[201~) → returns Key enum or paste string | disable_bracketed_paste() sends ESC[?2004l → restore_terminal() resets termios
|
|
6
|
+
State/Effects: modifies terminal mode (raw mode via tty.setraw) | enables/disables bracketed paste mode | stores original termios settings | reads from stdin (blocking)
|
|
7
|
+
Integration: exposes enable_bracketed_paste(), disable_bracketed_paste(), restore_terminal(), read_key() → Key|str | Key enum for special keys (UP, DOWN, ENTER, BACKSPACE, etc.) | used by Input widget for character-by-character input
|
|
8
|
+
Performance: blocking read with select() for responsiveness | minimal overhead (direct termios)
|
|
9
|
+
Errors: restores terminal on exception | paste detection falls back to raw characters if markers missing
|
|
10
|
+
Low-level keyboard input primitives with bracketed paste support.
|
|
11
|
+
|
|
12
|
+
This module provides raw keyboard input handling for terminal applications,
|
|
13
|
+
including support for:
|
|
14
|
+
- Single character input without Enter
|
|
15
|
+
- Arrow keys and special keys (Shift+Tab, Escape)
|
|
16
|
+
- Bracketed paste mode for reliable paste detection
|
|
17
|
+
|
|
18
|
+
Bracketed Paste Mode:
|
|
19
|
+
Modern terminals support bracketed paste mode where pasted text is
|
|
20
|
+
wrapped in special escape sequences:
|
|
21
|
+
- ESC[?2004h - Enable bracketed paste
|
|
22
|
+
- ESC[200~ - Paste start marker
|
|
23
|
+
- ESC[201~ - Paste end marker
|
|
24
|
+
- ESC[?2004l - Disable bracketed paste
|
|
25
|
+
|
|
26
|
+
This allows us to detect paste operations and handle all pasted text
|
|
27
|
+
atomically, preventing display glitches during paste.
|
|
28
|
+
"""
|
|
2
29
|
|
|
3
30
|
import sys
|
|
4
31
|
|
|
5
32
|
|
|
33
|
+
# Bracketed paste mode sequences
|
|
34
|
+
PASTE_START = '\x1b[200~' # Sent by terminal when paste begins
|
|
35
|
+
PASTE_END = '\x1b[201~' # Sent by terminal when paste ends
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def enable_bracketed_paste():
|
|
39
|
+
"""Enable bracketed paste mode.
|
|
40
|
+
|
|
41
|
+
When enabled, the terminal wraps pasted text in special sequences:
|
|
42
|
+
ESC[200~ ... pasted text ... ESC[201~
|
|
43
|
+
|
|
44
|
+
This allows detection of paste operations vs typed input.
|
|
45
|
+
Must call disable_bracketed_paste() when done to restore terminal.
|
|
46
|
+
"""
|
|
47
|
+
sys.stdout.write('\x1b[?2004h')
|
|
48
|
+
sys.stdout.flush()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def disable_bracketed_paste():
|
|
52
|
+
"""Disable bracketed paste mode.
|
|
53
|
+
|
|
54
|
+
Always call this when done with input to restore normal terminal behavior.
|
|
55
|
+
Should be called in a finally block to ensure cleanup on errors.
|
|
56
|
+
"""
|
|
57
|
+
sys.stdout.write('\x1b[?2004l')
|
|
58
|
+
sys.stdout.flush()
|
|
59
|
+
|
|
60
|
+
|
|
6
61
|
def getch() -> str:
|
|
7
|
-
"""Read single character without waiting for Enter.
|
|
62
|
+
"""Read single character without waiting for Enter.
|
|
63
|
+
|
|
64
|
+
Uses raw terminal mode to read one character immediately.
|
|
65
|
+
Works on Unix (termios) and Windows (msvcrt).
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Single character string
|
|
69
|
+
"""
|
|
8
70
|
try:
|
|
9
71
|
import termios
|
|
10
72
|
import tty
|
|
@@ -12,24 +74,89 @@ def getch() -> str:
|
|
|
12
74
|
old = termios.tcgetattr(fd)
|
|
13
75
|
tty.setraw(fd)
|
|
14
76
|
ch = sys.stdin.read(1)
|
|
15
|
-
|
|
77
|
+
# Use TCSANOW for immediate restore (prevents paste data loss)
|
|
78
|
+
termios.tcsetattr(fd, termios.TCSANOW, old)
|
|
16
79
|
return ch
|
|
17
80
|
except ImportError:
|
|
18
81
|
import msvcrt
|
|
19
82
|
return msvcrt.getch().decode('utf-8', errors='ignore')
|
|
20
83
|
|
|
21
84
|
|
|
85
|
+
def _read_until_paste_end() -> str:
|
|
86
|
+
"""Read all characters until paste end sequence (ESC[201~).
|
|
87
|
+
|
|
88
|
+
Called after paste start (ESC[200~) is detected.
|
|
89
|
+
Collects all pasted characters until the end marker.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
The pasted text without the escape sequences
|
|
93
|
+
"""
|
|
94
|
+
chars = []
|
|
95
|
+
buffer = ""
|
|
96
|
+
|
|
97
|
+
while True:
|
|
98
|
+
ch = getch()
|
|
99
|
+
buffer += ch
|
|
100
|
+
|
|
101
|
+
# Check for paste end sequence
|
|
102
|
+
if buffer.endswith(PASTE_END[1:]): # Already got ESC, check for [201~
|
|
103
|
+
# Remove the end sequence from collected chars
|
|
104
|
+
if chars and len(chars) >= 4:
|
|
105
|
+
# Remove [201~ (4 chars after ESC)
|
|
106
|
+
return ''.join(chars[:-4])
|
|
107
|
+
return ''.join(chars)
|
|
108
|
+
|
|
109
|
+
# Keep building buffer for sequence detection
|
|
110
|
+
if ch == '\x1b':
|
|
111
|
+
buffer = ch
|
|
112
|
+
chars.append(ch)
|
|
113
|
+
elif len(buffer) <= len(PASTE_END):
|
|
114
|
+
chars.append(ch)
|
|
115
|
+
else:
|
|
116
|
+
# Not a sequence, add buffer to chars and reset
|
|
117
|
+
chars.append(ch)
|
|
118
|
+
buffer = ""
|
|
119
|
+
|
|
120
|
+
return ''.join(chars)
|
|
121
|
+
|
|
122
|
+
|
|
22
123
|
def read_key() -> str:
|
|
23
|
-
"""Read key with arrow/escape sequence handling.
|
|
124
|
+
"""Read key with arrow/escape sequence and bracketed paste handling.
|
|
24
125
|
|
|
25
126
|
Returns:
|
|
26
|
-
Single char, or
|
|
127
|
+
Single char, or special key names:
|
|
128
|
+
- 'up'/'down'/'left'/'right' for arrows
|
|
129
|
+
- 'shift+tab' for Shift+Tab
|
|
130
|
+
- 'esc' for escape
|
|
131
|
+
- Multi-char string for pasted text (with 'paste:' prefix)
|
|
27
132
|
"""
|
|
28
133
|
ch = getch()
|
|
134
|
+
|
|
135
|
+
# Handle escape sequences
|
|
29
136
|
if ch == '\x1b':
|
|
30
137
|
ch2 = getch()
|
|
31
138
|
if ch2 == '[':
|
|
32
139
|
ch3 = getch()
|
|
33
|
-
|
|
140
|
+
|
|
141
|
+
# Shift+Tab is ESC [ Z
|
|
142
|
+
if ch3 == 'Z':
|
|
143
|
+
return 'shift+tab'
|
|
144
|
+
|
|
145
|
+
# Arrow keys
|
|
146
|
+
if ch3 in 'ABCD':
|
|
147
|
+
return {'A': 'up', 'B': 'down', 'C': 'right', 'D': 'left'}[ch3]
|
|
148
|
+
|
|
149
|
+
# Bracketed paste start: ESC [ 2 0 0 ~
|
|
150
|
+
if ch3 == '2':
|
|
151
|
+
ch4 = getch()
|
|
152
|
+
ch5 = getch()
|
|
153
|
+
ch6 = getch()
|
|
154
|
+
if ch4 == '0' and ch5 == '0' and ch6 == '~':
|
|
155
|
+
# Paste start detected - read until paste end
|
|
156
|
+
pasted = _read_until_paste_end()
|
|
157
|
+
return 'paste:' + pasted
|
|
158
|
+
|
|
159
|
+
return 'esc'
|
|
34
160
|
return 'esc'
|
|
161
|
+
|
|
35
162
|
return ch
|
connectonion/tui/providers.py
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Purpose: Autocomplete providers for Input widget with fuzzy search and file/command completion
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [pathlib, typing.Protocol, tui/fuzzy.py, tui/dropdown.py] | imported by [tui/input.py, tui/chat.py] | tested by [tests/tui/test_providers.py]
|
|
5
|
+
Data flow: Provider.search(query) → fuzzy_match() filters items → returns list[DropdownItem] sorted by score | StaticProvider for fixed lists | FileProvider for filesystem completion | CommandProvider for slash commands
|
|
6
|
+
State/Effects: FileProvider reads filesystem via Path.glob() | no persistent state
|
|
7
|
+
Integration: exposes Provider protocol with search(query) → list[DropdownItem|tuple], StaticProvider(items), FileProvider(base_path), CommandProvider(commands) | used by Input triggers dict (e.g., {"/": CommandProvider, "@": FileProvider})
|
|
8
|
+
Performance: fuzzy matching is fast for typical item counts (<1000) | file provider lazy-loads on search | sorted by score for relevance
|
|
9
|
+
Errors: FileProvider handles missing directories gracefully | returns empty list if no matches
|
|
10
|
+
Providers for CommandPalette and Input autocomplete.
|
|
11
|
+
"""
|
|
2
12
|
|
|
3
13
|
from pathlib import Path
|
|
4
14
|
from typing import Protocol, runtime_checkable, Union
|
connectonion/tui/status_bar.py
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Purpose: Powerline-style status bar with colored segments for terminal UI
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [rich.text.Text, dataclasses] | imported by [tui/chat.py, tui/input.py] | tested by [tests/tui/test_status_bar.py]
|
|
5
|
+
Data flow: StatusBar(segments) → render() → formats segments with powerline arrows → colored backgrounds → returns Rich Text
|
|
6
|
+
State/Effects: no state (pure function)
|
|
7
|
+
Integration: exposes StatusBar(segments: list[tuple[icon, label, color]]) with render() → Text | uses powerline characters (requires powerline fonts) | fallback to simple arrows if fonts unavailable
|
|
8
|
+
Performance: trivial (string formatting)
|
|
9
|
+
Errors: none (handles missing fonts with fallback)
|
|
10
|
+
StatusBar - Powerline-style info bar with segments.
|
|
2
11
|
|
|
3
12
|
Creates a professional terminal prompt bar like powerlevel10k.
|
|
4
13
|
"""
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
"""
|
|
2
|
+
Purpose: Event handlers package re-exporting reflect and other lifecycle event handlers
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [reflect.py] | imported by [__init__.py main package, user code] | tested via handler tests
|
|
5
|
+
Data flow: re-exports event handler functions/lists
|
|
6
|
+
State/Effects: no state
|
|
7
|
+
Integration: exposes reflect event handler (fires after_tools) | used via Agent(on_events=[reflect])
|
|
8
|
+
Performance: trivial
|
|
9
|
+
Errors: none
|
|
2
10
|
Useful event handlers for ConnectOnion agents.
|
|
3
11
|
|
|
4
12
|
Event handlers fire at specific points in the agent lifecycle.
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
"""
|
|
2
|
+
Purpose: Reflection event handler for generating reasoning after tool execution
|
|
3
|
+
LLM-Note:
|
|
4
|
+
Dependencies: imports from [core/events.py after_tools, llm_do.py, pathlib, typing] | imported by [useful_events_handlers/__init__.py, user code] | tested by [tests/events/test_reflect.py]
|
|
5
|
+
Data flow: fires after_tools event → _compress_messages() truncates tool results to 150 chars → llm_do generates reflection using reflect.md prompt → adds reflection as user message to session → LLM sees reflection in next iteration
|
|
6
|
+
State/Effects: modifies agent.current_session['messages'] by appending user reflection message | calls llm_do (costs tokens) | no persistent state
|
|
7
|
+
Integration: exposes reflect event handler (use via on_events=[reflect]) | uses after_tools (not after_each_tool) to fire ONCE after ALL tools | loads prompt from prompt_files/reflect.md | compresses messages to reduce context size
|
|
8
|
+
Performance: one LLM call per tool batch (not per tool) | message compression limits token usage | truncates tool results to 150 chars
|
|
9
|
+
Errors: none (fails silently if llm_do errors to avoid breaking agent execution)
|
|
2
10
|
Reflect event handler - Adds reflection after tool execution.
|
|
3
11
|
|
|
4
12
|
Fires ONCE after ALL tools in a batch complete (when LLM returns multiple tool_calls).
|
|
@@ -16,6 +24,7 @@ Usage:
|
|
|
16
24
|
agent = Agent("assistant", tools=[search], on_events=[reflect])
|
|
17
25
|
"""
|
|
18
26
|
|
|
27
|
+
import time
|
|
19
28
|
from pathlib import Path
|
|
20
29
|
from typing import TYPE_CHECKING, List, Dict
|
|
21
30
|
from ..core.events import after_tools
|
|
@@ -72,12 +81,12 @@ def reflect(agent: 'Agent') -> None:
|
|
|
72
81
|
"""
|
|
73
82
|
trace = agent.current_session['trace'][-1]
|
|
74
83
|
|
|
75
|
-
if trace['type'] != '
|
|
84
|
+
if trace['type'] != 'tool_result':
|
|
76
85
|
return
|
|
77
86
|
|
|
78
87
|
user_prompt = agent.current_session.get('user_prompt', '')
|
|
79
|
-
tool_name = trace['
|
|
80
|
-
tool_args = trace['
|
|
88
|
+
tool_name = trace['name']
|
|
89
|
+
tool_args = trace['args']
|
|
81
90
|
status = trace['status']
|
|
82
91
|
|
|
83
92
|
conversation = _compress_messages(agent.current_session['messages'])
|
|
@@ -110,7 +119,13 @@ Error: {error}"""
|
|
|
110
119
|
|
|
111
120
|
agent.logger.print("[dim]/reflecting...[/dim]")
|
|
112
121
|
|
|
122
|
+
agent._record_trace({
|
|
123
|
+
'type': 'thinking',
|
|
124
|
+
'kind': 'reflect',
|
|
125
|
+
'content': reasoning,
|
|
126
|
+
})
|
|
127
|
+
|
|
113
128
|
agent.current_session['messages'].append({
|
|
114
129
|
'role': 'assistant',
|
|
115
|
-
'content':
|
|
130
|
+
'content': reasoning
|
|
116
131
|
})
|
|
@@ -17,5 +17,7 @@ from .shell_approval import shell_approval
|
|
|
17
17
|
from .gmail_plugin import gmail_plugin
|
|
18
18
|
from .calendar_plugin import calendar_plugin
|
|
19
19
|
from .ui_stream import ui_stream
|
|
20
|
+
from .system_reminder import system_reminder
|
|
21
|
+
from .tool_approval import tool_approval
|
|
20
22
|
|
|
21
|
-
__all__ = ['re_act', 'eval', 'image_result_formatter', 'shell_approval', 'gmail_plugin', 'calendar_plugin', 'ui_stream']
|
|
23
|
+
__all__ = ['re_act', 'eval', 'image_result_formatter', 'shell_approval', 'gmail_plugin', 'calendar_plugin', 'ui_stream', 'system_reminder', 'tool_approval']
|
|
@@ -75,9 +75,9 @@ def _summarize_trace(trace: List[Dict]) -> str:
|
|
|
75
75
|
"""Summarize what actions were taken."""
|
|
76
76
|
actions = []
|
|
77
77
|
for entry in trace:
|
|
78
|
-
if entry['type'] == '
|
|
78
|
+
if entry['type'] == 'tool_result':
|
|
79
79
|
status = entry['status']
|
|
80
|
-
tool = entry['
|
|
80
|
+
tool = entry['name']
|
|
81
81
|
if status == 'success':
|
|
82
82
|
result = str(entry.get('result', ''))[:100]
|
|
83
83
|
actions.append(f"- {tool}: {result}")
|
|
@@ -135,14 +135,14 @@ def check_email_approval(agent: 'Agent') -> None:
|
|
|
135
135
|
def sync_crm_after_send(agent: 'Agent') -> None:
|
|
136
136
|
"""Update CRM data after each email send - last_contact, clear next_contact_date."""
|
|
137
137
|
trace = agent.current_session['trace'][-1]
|
|
138
|
-
if trace['type'] != '
|
|
138
|
+
if trace['type'] != 'tool_result':
|
|
139
139
|
return
|
|
140
|
-
if trace['
|
|
140
|
+
if trace['name'] not in SEND_METHODS:
|
|
141
141
|
return
|
|
142
142
|
if trace['status'] != 'success':
|
|
143
143
|
return
|
|
144
144
|
|
|
145
|
-
to = trace['
|
|
145
|
+
to = trace['args'].get('to', '')
|
|
146
146
|
if not to:
|
|
147
147
|
return
|
|
148
148
|
|
|
@@ -74,12 +74,12 @@ def _format_image_result(agent: 'Agent') -> None:
|
|
|
74
74
|
"""
|
|
75
75
|
trace = agent.current_session['trace'][-1]
|
|
76
76
|
|
|
77
|
-
if trace['type'] != '
|
|
77
|
+
if trace['type'] != 'tool_result' or trace['status'] != 'success':
|
|
78
78
|
return
|
|
79
79
|
|
|
80
80
|
result = trace['result']
|
|
81
|
-
tool_call_id = trace.get('call_id')
|
|
82
|
-
tool_name = trace.get('
|
|
81
|
+
tool_call_id = trace.get('call_id')
|
|
82
|
+
tool_name = trace.get('name', 'unknown')
|
|
83
83
|
|
|
84
84
|
# Check if result contains base64 image
|
|
85
85
|
is_image, mime_type, base64_data = _is_base64_image(result)
|