connectonion 0.6.2__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 +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 +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.2.dist-info → connectonion-0.6.3.dist-info}/METADATA +10 -3
- connectonion-0.6.3.dist-info/RECORD +469 -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.3.dist-info}/WHEEL +0 -0
- {connectonion-0.6.2.dist-info → connectonion-0.6.3.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# HTTP Layer: Why Raw ASGI Instead of Starlette/FastAPI
|
|
2
|
+
|
|
3
|
+
*December 2025*
|
|
4
|
+
|
|
5
|
+
When implementing `host()`, we needed to choose how to handle HTTP and WebSocket requests. This document explains why we chose raw ASGI over established frameworks like Starlette or FastAPI.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## The Problem
|
|
10
|
+
|
|
11
|
+
The `host()` function needs to expose an agent over HTTP/WebSocket:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Client Agent
|
|
15
|
+
│ │
|
|
16
|
+
│── POST /input ────────────────────────▶│
|
|
17
|
+
│── GET /tasks/{id} ────────────────────▶│
|
|
18
|
+
│── GET /health ────────────────────────▶│
|
|
19
|
+
│── WS /ws ─────────────────────────────▶│
|
|
20
|
+
│ │
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Requirements:
|
|
24
|
+
1. **Simple for users** - Just `host(agent)`, no config
|
|
25
|
+
2. **Flexible for future** - Streaming, custom protocols, P2P
|
|
26
|
+
3. **Minimal dependencies** - Only uvicorn needed
|
|
27
|
+
4. **Transparent** - Easy to understand what happens
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Part I: What Others Do
|
|
32
|
+
|
|
33
|
+
### Option A: Build on Starlette
|
|
34
|
+
|
|
35
|
+
Most Python frameworks build on Starlette (FastAPI's foundation):
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from starlette.applications import Starlette
|
|
39
|
+
from starlette.routing import Route
|
|
40
|
+
from starlette.responses import JSONResponse
|
|
41
|
+
|
|
42
|
+
async def post_input(request):
|
|
43
|
+
data = await request.json()
|
|
44
|
+
result = agent.input(data["prompt"])
|
|
45
|
+
return JSONResponse(result)
|
|
46
|
+
|
|
47
|
+
app = Starlette(routes=[
|
|
48
|
+
Route("/input", post_input, methods=["POST"]),
|
|
49
|
+
Route("/tasks/{task_id}", get_task),
|
|
50
|
+
# ...
|
|
51
|
+
])
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Pros:**
|
|
55
|
+
- Clean routing syntax
|
|
56
|
+
- Request/Response objects
|
|
57
|
+
- Built-in test client (httpx)
|
|
58
|
+
- Middleware support (CORS, GZip)
|
|
59
|
+
- Industry standard
|
|
60
|
+
|
|
61
|
+
**Cons:**
|
|
62
|
+
- Additional dependency
|
|
63
|
+
- Framework lock-in
|
|
64
|
+
- Less control over protocol details
|
|
65
|
+
|
|
66
|
+
### Option B: Own Implementation (Sanic, BlackSheep)
|
|
67
|
+
|
|
68
|
+
Some frameworks implement their own HTTP layer:
|
|
69
|
+
|
|
70
|
+
| Framework | Approach | Why |
|
|
71
|
+
|-----------|----------|-----|
|
|
72
|
+
| **Sanic** | Own server + ASGI | Predates Starlette (2016), needed control |
|
|
73
|
+
| **BlackSheep** | Cython-optimized ASGI | Performance, ASP.NET-style patterns |
|
|
74
|
+
| **Litestar** | Custom (Starlette-inspired) | Different design philosophy |
|
|
75
|
+
|
|
76
|
+
### Option C: Rust Runtime (Robyn)
|
|
77
|
+
|
|
78
|
+
Robyn bypasses Python ASGI entirely - HTTP is handled in Rust:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
# Robyn: Python handlers, Rust HTTP server
|
|
82
|
+
@app.post("/input")
|
|
83
|
+
async def input(request):
|
|
84
|
+
return agent.input(request.json()["prompt"])
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Pros:** Maximum performance (15-20% faster)
|
|
88
|
+
**Cons:** Not standard ASGI, different deployment model
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Part II: Our Analysis
|
|
93
|
+
|
|
94
|
+
### Performance Reality
|
|
95
|
+
|
|
96
|
+
From TechEmpower benchmarks:
|
|
97
|
+
```
|
|
98
|
+
Performance ranking:
|
|
99
|
+
1. Uvicorn (raw server)
|
|
100
|
+
2. Starlette (~same as uvicorn)
|
|
101
|
+
3. FastAPI (Starlette + Pydantic)
|
|
102
|
+
4. ...everything else
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Key insight:** Starlette adds essentially zero overhead.
|
|
106
|
+
|
|
107
|
+
### What Raw ASGI Gives Us
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
async def app(scope, receive, send):
|
|
111
|
+
# scope = method, path, headers, query_string
|
|
112
|
+
# receive = get body chunks
|
|
113
|
+
# send = send response chunks
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Full control for:
|
|
117
|
+
- **Streaming responses** - Send chunks as agent thinks
|
|
118
|
+
- **Protocol hijacking** - Custom binary protocols
|
|
119
|
+
- **Server-Sent Events** - Real-time without WebSocket
|
|
120
|
+
- **P2P relay** - Custom agent-to-agent protocol
|
|
121
|
+
- **Early response** - Send headers before body ready
|
|
122
|
+
|
|
123
|
+
### What Starlette Would Save
|
|
124
|
+
|
|
125
|
+
Our raw ASGI code (~70 lines):
|
|
126
|
+
```python
|
|
127
|
+
async def handle_http(scope, receive, send, ...):
|
|
128
|
+
method, path = scope["method"], scope["path"]
|
|
129
|
+
if method == "POST" and path == "/input":
|
|
130
|
+
body = await read_body(receive)
|
|
131
|
+
data = json.loads(body)
|
|
132
|
+
# ...
|
|
133
|
+
await send_json(send, result)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
With Starlette (~30 lines):
|
|
137
|
+
```python
|
|
138
|
+
async def post_input(request):
|
|
139
|
+
data = await request.json()
|
|
140
|
+
# ...
|
|
141
|
+
return JSONResponse(result)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Savings:** ~40 lines, cleaner syntax.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Part III: Decision
|
|
149
|
+
|
|
150
|
+
**Use Raw ASGI**
|
|
151
|
+
|
|
152
|
+
### Reasons
|
|
153
|
+
|
|
154
|
+
1. **Full Control for Agent Protocols**
|
|
155
|
+
- Future: streaming agent responses as they generate
|
|
156
|
+
- Future: P2P relay connections
|
|
157
|
+
- Future: agent-to-agent communication
|
|
158
|
+
- Future: Server-Sent Events
|
|
159
|
+
|
|
160
|
+
2. **Zero Dependencies**
|
|
161
|
+
- Only uvicorn (already needed)
|
|
162
|
+
- Simpler dependency tree
|
|
163
|
+
- No version conflicts
|
|
164
|
+
|
|
165
|
+
3. **Precedent**
|
|
166
|
+
- Sanic chose own implementation
|
|
167
|
+
- BlackSheep chose own implementation
|
|
168
|
+
- Both prioritized control over convenience
|
|
169
|
+
|
|
170
|
+
4. **Transparency**
|
|
171
|
+
- Code shows exactly what happens
|
|
172
|
+
- Educational value for agent framework
|
|
173
|
+
- Easy to debug
|
|
174
|
+
|
|
175
|
+
5. **Performance Equivalent**
|
|
176
|
+
- Starlette adds ~zero overhead
|
|
177
|
+
- No benefit to switching
|
|
178
|
+
|
|
179
|
+
### Trade-offs Accepted
|
|
180
|
+
|
|
181
|
+
We give up:
|
|
182
|
+
- Clean `Route("/path", handler)` syntax
|
|
183
|
+
- Built-in test client
|
|
184
|
+
- ~~Middleware helpers (CORS, GZip)~~ (we implemented CORS manually)
|
|
185
|
+
- ~40 lines of code
|
|
186
|
+
|
|
187
|
+
We gain:
|
|
188
|
+
- Full protocol control
|
|
189
|
+
- No framework lock-in
|
|
190
|
+
- Ability to implement custom protocols
|
|
191
|
+
- Clear understanding of what happens
|
|
192
|
+
|
|
193
|
+
### CORS Implementation (Added Dec 2025)
|
|
194
|
+
|
|
195
|
+
We implemented CORS manually in `asgi.py` with ~15 lines:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
CORS_HEADERS = [
|
|
199
|
+
[b"access-control-allow-origin", b"*"],
|
|
200
|
+
[b"access-control-allow-methods", b"GET, POST, OPTIONS"],
|
|
201
|
+
[b"access-control-allow-headers", b"authorization, content-type"],
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
# Handle OPTIONS preflight
|
|
205
|
+
if method == "OPTIONS":
|
|
206
|
+
headers = CORS_HEADERS + [[b"content-length", b"0"]]
|
|
207
|
+
await send({"type": "http.response.start", "status": 204, "headers": headers})
|
|
208
|
+
await send({"type": "http.response.body", "body": b""})
|
|
209
|
+
return
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
This enables cross-origin requests from frontend (o.openonion.ai) to deployed agents (*.agents.openonion.ai).
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Part IV: Current Implementation
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
host.py (~360 lines)
|
|
220
|
+
├── Types # Task dataclass
|
|
221
|
+
├── Storage # JSONL persistence
|
|
222
|
+
├── Handlers # Pure functions (input, task, tasks, health, info)
|
|
223
|
+
├── ASGI App # create_app, handle_http, handle_websocket
|
|
224
|
+
├── Entry Point # host()
|
|
225
|
+
└── Helpers # read_body, send_json, extract_and_authenticate
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Key functions:
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
async def read_body(receive) -> bytes:
|
|
232
|
+
"""Read complete request body."""
|
|
233
|
+
body = b""
|
|
234
|
+
while True:
|
|
235
|
+
m = await receive()
|
|
236
|
+
body += m.get("body", b"")
|
|
237
|
+
if not m.get("more_body"):
|
|
238
|
+
break
|
|
239
|
+
return body
|
|
240
|
+
|
|
241
|
+
async def send_json(send, data: dict, status: int = 200):
|
|
242
|
+
"""Send JSON response."""
|
|
243
|
+
body = json.dumps(data).encode()
|
|
244
|
+
await send({"type": "http.response.start", "status": status,
|
|
245
|
+
"headers": [[b"content-type", b"application/json"]]})
|
|
246
|
+
await send({"type": "http.response.body", "body": body})
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Part V: When We Might Reconsider
|
|
252
|
+
|
|
253
|
+
| Need | Consider |
|
|
254
|
+
|------|----------|
|
|
255
|
+
| Auto OpenAPI docs | Litestar |
|
|
256
|
+
| Complex middleware | Starlette |
|
|
257
|
+
| Maximum performance | Rust (Robyn/Granian) |
|
|
258
|
+
| Production-grade CORS | Starlette middleware |
|
|
259
|
+
|
|
260
|
+
But for agent hosting with custom protocols: **Raw ASGI is correct**.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Summary
|
|
265
|
+
|
|
266
|
+
We chose raw ASGI because:
|
|
267
|
+
|
|
268
|
+
1. **Control** - Future streaming, P2P, custom protocols
|
|
269
|
+
2. **Simplicity** - One less dependency
|
|
270
|
+
3. **Transparency** - Clear what happens
|
|
271
|
+
4. **Precedent** - Sanic and BlackSheep did the same
|
|
272
|
+
|
|
273
|
+
The ~70 lines of HTTP/WS handling is a fair trade for full protocol control and zero framework dependencies.
|
|
Binary file
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# Hook System Design Options
|
|
2
|
+
|
|
3
|
+
Four different API styles for hooks in ConnectOnion.
|
|
4
|
+
|
|
5
|
+
> **Note:** This document is historical. The final API uses event wrappers (Option 2 style) with updated naming:
|
|
6
|
+
> - `before_each_tool` / `after_each_tool` - per-tool events
|
|
7
|
+
> - `before_tools` / `after_tools` - batch events (fire once per round)
|
|
8
|
+
>
|
|
9
|
+
> See [014-event-api-naming.md](./design-decisions/014-event-api-naming.md) for the rationale.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Option 1: TypedDict Hooks
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from connectonion import Agent, HookEvents
|
|
17
|
+
|
|
18
|
+
def log_tokens(data):
|
|
19
|
+
print(f"Tokens: {data['usage']['total_tokens']}")
|
|
20
|
+
|
|
21
|
+
def add_timestamp(data):
|
|
22
|
+
from datetime import datetime
|
|
23
|
+
data['messages'].append({
|
|
24
|
+
'role': 'system',
|
|
25
|
+
'content': f'Current time: {datetime.now()}'
|
|
26
|
+
})
|
|
27
|
+
return data
|
|
28
|
+
|
|
29
|
+
def cache_results(data):
|
|
30
|
+
cache[data['tool_name']] = data['result']
|
|
31
|
+
return data
|
|
32
|
+
|
|
33
|
+
agent = Agent(
|
|
34
|
+
"assistant",
|
|
35
|
+
tools=[search, analyze],
|
|
36
|
+
|
|
37
|
+
# ✨ TypedDict provides IDE autocomplete + type checking
|
|
38
|
+
on_event=dict(
|
|
39
|
+
before_llm=[add_timestamp],
|
|
40
|
+
after_llm=[log_tokens],
|
|
41
|
+
after_tool=[cache_results],
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
agent.input("Find Python info")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Type Definition (in connectonion):**
|
|
49
|
+
```python
|
|
50
|
+
from typing import TypedDict, List, Callable
|
|
51
|
+
|
|
52
|
+
class HookEvents(TypedDict, total=False):
|
|
53
|
+
"""Type-safe hook event configuration.
|
|
54
|
+
|
|
55
|
+
IDE will autocomplete event names and type checker will validate.
|
|
56
|
+
All fields are optional - only specify the events you need.
|
|
57
|
+
"""
|
|
58
|
+
before_llm: List[Callable]
|
|
59
|
+
after_llm: List[Callable]
|
|
60
|
+
before_tool: List[Callable]
|
|
61
|
+
after_tool: List[Callable]
|
|
62
|
+
on_error: List[Callable]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**With Type Annotation (for IDE hints):**
|
|
66
|
+
```python
|
|
67
|
+
# Option A: Inline annotation
|
|
68
|
+
on_event: HookEvents = dict(
|
|
69
|
+
before_llm=[add_timestamp],
|
|
70
|
+
after_llm=[log_tokens] # ← IDE autocompletes event names!
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Option B: Without annotation (still works, less IDE help)
|
|
74
|
+
on_event=dict(
|
|
75
|
+
before_llm=[add_timestamp],
|
|
76
|
+
after_llm=[log_tokens]
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
agent = Agent("assistant", tools=[search], on_event=on_event)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Reusable across agents:**
|
|
83
|
+
```python
|
|
84
|
+
from connectonion import HookEvents
|
|
85
|
+
|
|
86
|
+
common_hooks: HookEvents = dict(
|
|
87
|
+
after_llm=[log_tokens],
|
|
88
|
+
after_tool=[cache_results],
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
agent1 = Agent("assistant", tools=[search], on_event=common_hooks)
|
|
92
|
+
agent2 = Agent("analyst", tools=[analyze], on_event=common_hooks)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Option 2: Event Wrappers
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from connectonion import Agent, before_llm, after_llm, after_tool
|
|
101
|
+
|
|
102
|
+
def log_tokens(data):
|
|
103
|
+
print(f"Tokens: {data['usage']['total_tokens']}")
|
|
104
|
+
|
|
105
|
+
def add_timestamp(agent):
|
|
106
|
+
from datetime import datetime
|
|
107
|
+
agent.messages
|
|
108
|
+
data['messages'].append({
|
|
109
|
+
'role': 'system',
|
|
110
|
+
'content': f'Current time: {datetime.now()}'
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def cache_results(data):
|
|
115
|
+
cache[data['tool_name']] = data['result']
|
|
116
|
+
return data
|
|
117
|
+
|
|
118
|
+
agent = Agent(
|
|
119
|
+
"assistant",
|
|
120
|
+
tools=[search, analyze],
|
|
121
|
+
hooks=[
|
|
122
|
+
before_llm(add_timestamp),
|
|
123
|
+
after_llm(log_tokens),
|
|
124
|
+
after_tool(cache_results),
|
|
125
|
+
]
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
agent.input("Find Python info")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**With lambdas:**
|
|
132
|
+
```python
|
|
133
|
+
from connectonion import Agent, after_llm, after_tool
|
|
134
|
+
|
|
135
|
+
agent = Agent(
|
|
136
|
+
"assistant",
|
|
137
|
+
tools=[search],
|
|
138
|
+
on_event=[
|
|
139
|
+
after_llm(lambda d: print(f"Tokens: {d['usage']['total_tokens']}")),
|
|
140
|
+
after_tool(lambda d: cache.set(d['tool_name'], d['result'])),
|
|
141
|
+
]
|
|
142
|
+
)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Import and use patterns:**
|
|
146
|
+
```python
|
|
147
|
+
# connectonion/thinking.py
|
|
148
|
+
from connectonion import after_tool
|
|
149
|
+
|
|
150
|
+
def chain_of_thought():
|
|
151
|
+
def hook(data, agent):
|
|
152
|
+
thinking = agent.llm.complete([...])
|
|
153
|
+
agent.current_session['messages'].append({'role': 'assistant', 'content': thinking})
|
|
154
|
+
return after_tool(hook)
|
|
155
|
+
|
|
156
|
+
# User code
|
|
157
|
+
from connectonion import Agent
|
|
158
|
+
from connectonion.thinking import chain_of_thought
|
|
159
|
+
|
|
160
|
+
agent = Agent("assistant", tools=[search], on_event=[
|
|
161
|
+
chain_of_thought() # Just import and use!
|
|
162
|
+
])
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Option 3: Decorator Pattern
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from connectonion import Agent, hook
|
|
171
|
+
|
|
172
|
+
@hook('before_llm')
|
|
173
|
+
def add_timestamp(data):
|
|
174
|
+
from datetime import datetime
|
|
175
|
+
data['messages'].append({
|
|
176
|
+
'role': 'system',
|
|
177
|
+
'content': f'Current time: {datetime.now()}'
|
|
178
|
+
})
|
|
179
|
+
return data
|
|
180
|
+
|
|
181
|
+
@hook('after_llm')
|
|
182
|
+
def log_tokens(data):
|
|
183
|
+
print(f"Tokens: {data['usage']['total_tokens']}")
|
|
184
|
+
|
|
185
|
+
@hook('after_tool')
|
|
186
|
+
def cache_results(data):
|
|
187
|
+
cache[data['tool_name']] = data['result']
|
|
188
|
+
return data
|
|
189
|
+
|
|
190
|
+
# Pass decorated hooks to agent
|
|
191
|
+
agent = Agent(
|
|
192
|
+
"assistant",
|
|
193
|
+
tools=[search, analyze],
|
|
194
|
+
hooks=[add_timestamp, log_tokens, cache_results] # Decorated functions
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
agent.input("Find Python info")
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Reusable module:**
|
|
201
|
+
```python
|
|
202
|
+
# hooks.py
|
|
203
|
+
from connectonion import hook
|
|
204
|
+
|
|
205
|
+
@hook('before_llm')
|
|
206
|
+
def add_timestamp(data):
|
|
207
|
+
from datetime import datetime
|
|
208
|
+
data['messages'].append({'role': 'system', 'content': f'{datetime.now()}'})
|
|
209
|
+
return data
|
|
210
|
+
|
|
211
|
+
@hook('after_llm')
|
|
212
|
+
def log_tokens(data):
|
|
213
|
+
print(f"Tokens: {data['usage']['total_tokens']}")
|
|
214
|
+
|
|
215
|
+
# main.py
|
|
216
|
+
from connectonion import Agent
|
|
217
|
+
from .hooks import add_timestamp, log_tokens
|
|
218
|
+
|
|
219
|
+
agent = Agent(
|
|
220
|
+
"assistant",
|
|
221
|
+
tools=[search],
|
|
222
|
+
hooks=[add_timestamp, log_tokens] # Import and pass decorated hooks
|
|
223
|
+
)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Option 4: Event Emitter
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from connectonion import Agent
|
|
232
|
+
|
|
233
|
+
agent = Agent("assistant", tools=[search])
|
|
234
|
+
|
|
235
|
+
# Simple lambda
|
|
236
|
+
agent.on('after_llm', lambda d: print(f"Tokens: {d['usage']['total_tokens']}"))
|
|
237
|
+
|
|
238
|
+
# Decorator syntax
|
|
239
|
+
@agent.on('before_llm')
|
|
240
|
+
def add_timestamp(data):
|
|
241
|
+
from datetime import datetime
|
|
242
|
+
data['messages'].append({
|
|
243
|
+
'role': 'system',
|
|
244
|
+
'content': f'Current time: {datetime.now()}'
|
|
245
|
+
})
|
|
246
|
+
return data
|
|
247
|
+
|
|
248
|
+
@agent.on('after_tool')
|
|
249
|
+
def cache_results(data):
|
|
250
|
+
cache[data['tool_name']] = data['result']
|
|
251
|
+
return data
|
|
252
|
+
|
|
253
|
+
agent.input("Find Python info")
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Dynamic add/remove:**
|
|
257
|
+
```python
|
|
258
|
+
agent = Agent("assistant", tools=[search])
|
|
259
|
+
|
|
260
|
+
# Add hook
|
|
261
|
+
agent.on('after_llm', log_tokens)
|
|
262
|
+
|
|
263
|
+
# Later... remove hook
|
|
264
|
+
agent.off('after_llm', log_tokens)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Common Use Cases
|
|
270
|
+
|
|
271
|
+
### Cost Tracking
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
# Option 1: TypedDict
|
|
275
|
+
from connectonion import Agent, HookEvents
|
|
276
|
+
|
|
277
|
+
agent = Agent(
|
|
278
|
+
"assistant",
|
|
279
|
+
tools=[search],
|
|
280
|
+
on_event=dict(
|
|
281
|
+
after_llm=[lambda d: print(f"Cost: ${d['usage']['total_tokens'] * 0.00001:.4f}")]
|
|
282
|
+
)
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# Option 2: Event Wrappers
|
|
286
|
+
from connectonion import after_llm
|
|
287
|
+
agent = Agent("assistant", tools=[search], on_event=[
|
|
288
|
+
after_llm(lambda d: print(f"Cost: ${d['usage']['total_tokens'] * 0.00001:.4f}"))
|
|
289
|
+
])
|
|
290
|
+
|
|
291
|
+
# Option 3: Decorator
|
|
292
|
+
@hook('after_llm')
|
|
293
|
+
def track_cost(data):
|
|
294
|
+
print(f"Cost: ${data['usage']['total_tokens'] * 0.00001:.4f}")
|
|
295
|
+
|
|
296
|
+
# Option 4: Event Emitter
|
|
297
|
+
agent.on('after_llm', lambda d: print(f"Cost: ${d['usage']['total_tokens'] * 0.00001:.4f}"))
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Smart Caching
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
cache = {}
|
|
304
|
+
|
|
305
|
+
def cache_tool(data):
|
|
306
|
+
key = f"{data['tool_name']}:{hash(str(data['tool_args']))}"
|
|
307
|
+
cache[key] = data['result']
|
|
308
|
+
return data
|
|
309
|
+
|
|
310
|
+
# Option 1: TypedDict
|
|
311
|
+
agent = Agent("assistant", tools=[search], on_event=dict(after_tool=[cache_tool]))
|
|
312
|
+
|
|
313
|
+
# Option 2: Event Wrappers
|
|
314
|
+
agent = Agent("assistant", tools=[search], on_event=[after_tool(cache_tool)])
|
|
315
|
+
|
|
316
|
+
# Option 3: Decorator
|
|
317
|
+
@hook('after_tool')
|
|
318
|
+
def cache_tool(data): ...
|
|
319
|
+
|
|
320
|
+
# Option 4: Event Emitter
|
|
321
|
+
agent.on('after_tool', cache_tool)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Custom Logging
|
|
325
|
+
|
|
326
|
+
```python
|
|
327
|
+
# Option 1: TypedDict
|
|
328
|
+
agent = Agent(
|
|
329
|
+
"assistant",
|
|
330
|
+
tools=[search],
|
|
331
|
+
on_event=dict(
|
|
332
|
+
before_tool=[lambda d: logger.info(f"Tool: {d['tool_name']}")],
|
|
333
|
+
on_error=[lambda d: logger.error(f"Error: {d['error']}")]
|
|
334
|
+
)
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
# Option 2: Event Wrappers
|
|
338
|
+
from connectonion import before_tool, on_error
|
|
339
|
+
agent = Agent("assistant", tools=[search], on_event=[
|
|
340
|
+
before_tool(lambda d: logger.info(f"Tool: {d['tool_name']}")),
|
|
341
|
+
on_error(lambda d: logger.error(f"Error: {d['error']}"))
|
|
342
|
+
])
|
|
343
|
+
|
|
344
|
+
# Option 3: Decorator
|
|
345
|
+
@hook('before_tool')
|
|
346
|
+
def log_tool(data):
|
|
347
|
+
logger.info(f"Tool: {data['tool_name']}")
|
|
348
|
+
|
|
349
|
+
@hook('on_error')
|
|
350
|
+
def log_error(data):
|
|
351
|
+
logger.error(f"Error: {data['error']}")
|
|
352
|
+
|
|
353
|
+
# Option 4: Event Emitter
|
|
354
|
+
agent.on('before_tool', lambda d: logger.info(f"Tool: {d['tool_name']}"))
|
|
355
|
+
agent.on('on_error', lambda d: logger.error(f"Error: {d['error']}"))
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Vote
|
|
361
|
+
|
|
362
|
+
Which option do you prefer?
|
|
363
|
+
|
|
364
|
+
👉 https://github.com/openonion/connectonion/issues/31
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Integrations
|
|
2
|
+
|
|
3
|
+
Connect ConnectOnion to external services.
|
|
4
|
+
|
|
5
|
+
## Authentication
|
|
6
|
+
|
|
7
|
+
- [auth.md](auth.md) - Authentication with managed keys (`co auth`)
|
|
8
|
+
|
|
9
|
+
## OAuth Integrations
|
|
10
|
+
|
|
11
|
+
- [google.md](google.md) - Google OAuth (Gmail, Calendar)
|
|
12
|
+
- [microsoft.md](microsoft.md) - Microsoft OAuth (Outlook, Calendar)
|