echo-agent 0.1.0__tar.gz → 0.2.1__tar.gz
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.
- echo_agent-0.2.1/LICENSE +21 -0
- echo_agent-0.2.1/PKG-INFO +233 -0
- echo_agent-0.2.1/README.md +150 -0
- echo_agent-0.2.1/echo_agent/__main__.py +252 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/a2a/protocol.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/a2a/server.py +12 -12
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/approval_gate.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/compression/compressor.py +8 -0
- echo_agent-0.2.1/echo_agent/agent/consolidation.py +143 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/context.py +158 -13
- echo_agent-0.2.1/echo_agent/agent/context_cache.py +60 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/loop.py +30 -172
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/multi_agent/runtime.py +13 -10
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/pipeline/context_stage.py +51 -12
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/pipeline/inference_stage.py +14 -13
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/pipeline/response_stage.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/pipeline/types.py +5 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/planning/planner.py +6 -3
- echo_agent-0.2.1/echo_agent/agent/streaming.py +206 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/__init__.py +90 -12
- echo_agent-0.2.1/echo_agent/agent/tools/base.py +20 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/circuit_breaker.py +15 -3
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/delegate.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/process.py +11 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/registry.py +30 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/tts.py +9 -5
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/web.py +43 -2
- echo_agent-0.2.1/echo_agent/app.py +357 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/bus/queue.py +54 -5
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/bus/rate_limiter.py +5 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/base.py +55 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/cli.py +38 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/cron.py +3 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/feishu.py +23 -3
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/matrix.py +29 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/qqbot.py +22 -4
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/slack.py +24 -4
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/telegram.py +28 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/webhook.py +5 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/weixin.py +41 -9
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/whatsapp.py +29 -4
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/evolution_cmd.py +6 -6
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/plugins_cmd.py +3 -5
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/setup.py +0 -1
- echo_agent-0.2.1/echo_agent/config/default.yaml +62 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/config/loader.py +24 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/config/schema.py +16 -1
- echo_agent-0.2.1/echo_agent/dependencies/__init__.py +37 -0
- echo_agent-0.2.1/echo_agent/dependencies/cli.py +167 -0
- echo_agent-0.2.1/echo_agent/dependencies/lazy_deps.py +488 -0
- echo_agent-0.2.1/echo_agent/dependencies/skill_require.py +133 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evolution/engine.py +45 -6
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evolution/gate.py +122 -6
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evolution/recorder.py +24 -3
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evolution/scheduler.py +21 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evolution/tools.py +1 -1
- echo_agent-0.2.1/echo_agent/evolution/validation.py +94 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/auth.py +15 -12
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/editor.py +1 -3
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/media.py +0 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/router.py +2 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/server.py +18 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/session_context.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/mcp/client.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/mcp/manager.py +1 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/mcp/oauth.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/mcp/tool_adapter.py +1 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/consolidator.py +31 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/contradiction.py +135 -9
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/forgetting.py +14 -7
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/retrieval.py +26 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/store.py +233 -12
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/tiers.py +21 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/types.py +8 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/vectors.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/credential_pool.py +1 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/inference.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/provider.py +95 -32
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/providers/__init__.py +6 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/providers/anthropic_provider.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/providers/bedrock_provider.py +28 -3
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/providers/format_utils.py +34 -4
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/providers/gemini_provider.py +24 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/providers/openai_provider.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/router.py +68 -18
- echo_agent-0.2.1/echo_agent/models/stub.py +42 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/observability/spans.py +0 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/permissions/allowlist.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/plugins/context.py +4 -4
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/plugins/hooks.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/plugins/loader.py +1 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/plugins/manager.py +17 -2
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/plugins/manifest.py +1 -0
- echo_agent-0.2.1/echo_agent/plugins/sandbox.py +99 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/scheduler/delivery.py +5 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/scheduler/service.py +42 -7
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/security/guards.py +86 -15
- echo_agent-0.2.1/echo_agent/security/normalizer.py +103 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/security/path_policy.py +75 -5
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/security/smart_approval.py +21 -9
- echo_agent-0.2.1/echo_agent/security/tokenizer.py +129 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/security/tool_policy.py +1 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/session/manager.py +34 -12
- echo_agent-0.2.1/echo_agent/session/media_ref.py +42 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/skills/reviewer.py +0 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/skills/store.py +37 -1
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/storage/sqlite.py +25 -15
- echo_agent-0.2.1/echo_agent/tools/__init__.py +22 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/pyproject.toml +23 -3
- echo_agent-0.2.1/skills/creative/excel-author/SKILL.md +88 -0
- echo_agent-0.2.1/skills/creative/excel-author/scripts/create_xlsx.py +97 -0
- echo_agent-0.2.1/skills/creative/image-gen/SKILL.md +74 -0
- echo_agent-0.2.1/skills/creative/image-gen/scripts/generate_image.py +73 -0
- echo_agent-0.2.1/skills/creative/meme-gen/SKILL.md +66 -0
- echo_agent-0.2.1/skills/creative/meme-gen/scripts/make_meme.py +121 -0
- echo_agent-0.2.1/skills/creative/ppt-author/SKILL.md +87 -0
- echo_agent-0.2.1/skills/creative/ppt-author/scripts/create_pptx.py +89 -0
- echo_agent-0.2.1/skills/development/code-runner/SKILL.md +71 -0
- echo_agent-0.2.1/skills/development/code-runner/scripts/safe_exec.py +133 -0
- echo_agent-0.2.1/skills/development/github-ops/SKILL.md +81 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/skills/development/skill-creator/scripts/init_skill.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/skills/development/skill-creator/scripts/package_skill.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/skills/development/skill-creator/scripts/quick_validate.py +0 -0
- echo_agent-0.2.1/skills/development/workflow-chain/SKILL.md +103 -0
- echo_agent-0.2.1/skills/development/workflow-chain/scripts/workflow_engine.py +100 -0
- echo_agent-0.2.1/skills/devops/docker-manage/SKILL.md +85 -0
- echo_agent-0.2.1/skills/devops/system-monitor/SKILL.md +77 -0
- echo_agent-0.2.1/skills/devops/system-monitor/scripts/system_check.py +110 -0
- echo_agent-0.2.1/skills/finance/finance-tracker/SKILL.md +66 -0
- echo_agent-0.2.1/skills/finance/finance-tracker/scripts/finance_manager.py +141 -0
- echo_agent-0.2.1/skills/finance/stocks/SKILL.md +75 -0
- echo_agent-0.2.1/skills/finance/stocks/scripts/market_query.py +99 -0
- echo_agent-0.2.1/skills/health/fitness-nutrition/SKILL.md +68 -0
- echo_agent-0.2.1/skills/health/fitness-nutrition/scripts/health_query.py +83 -0
- echo_agent-0.2.1/skills/learning/flashcards/SKILL.md +80 -0
- echo_agent-0.2.1/skills/learning/flashcards/scripts/flashcard_engine.py +170 -0
- echo_agent-0.2.1/skills/media/tts-voice/SKILL.md +82 -0
- echo_agent-0.2.1/skills/media/tts-voice/scripts/text_to_speech.py +55 -0
- echo_agent-0.2.1/skills/media/voice-note/SKILL.md +87 -0
- echo_agent-0.2.1/skills/media/voice-note/scripts/voice_process.py +68 -0
- echo_agent-0.2.1/skills/productivity/calendar/SKILL.md +64 -0
- echo_agent-0.2.1/skills/productivity/calendar/scripts/calendar_client.py +96 -0
- echo_agent-0.2.1/skills/productivity/daily-briefing/SKILL.md +69 -0
- echo_agent-0.2.1/skills/productivity/daily-briefing/scripts/generate_briefing.py +57 -0
- echo_agent-0.2.1/skills/productivity/email-assistant/SKILL.md +80 -0
- echo_agent-0.2.1/skills/productivity/email-assistant/scripts/email_client.py +99 -0
- echo_agent-0.2.1/skills/productivity/note-taking/SKILL.md +60 -0
- echo_agent-0.2.1/skills/productivity/note-taking/scripts/notes_manager.py +126 -0
- echo_agent-0.2.1/skills/productivity/notion-sync/SKILL.md +80 -0
- echo_agent-0.2.1/skills/productivity/notion-sync/scripts/notion_client.py +81 -0
- echo_agent-0.2.1/skills/productivity/ocr-document/SKILL.md +86 -0
- echo_agent-0.2.1/skills/productivity/ocr-document/scripts/extract_document.py +75 -0
- echo_agent-0.2.1/skills/productivity/reminder/SKILL.md +65 -0
- echo_agent-0.2.1/skills/productivity/reminder/scripts/reminder_store.py +112 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/skills/research/arxiv/scripts/search_arxiv.py +12 -6
- echo_agent-0.2.1/skills/research/deep-research/SKILL.md +74 -0
- echo_agent-0.2.1/skills/research/deep-research/scripts/research_report.py +95 -0
- echo_agent-0.2.1/skills/research/rss-watcher/SKILL.md +70 -0
- echo_agent-0.2.1/skills/research/rss-watcher/scripts/feed_monitor.py +100 -0
- echo_agent-0.2.1/skills/research/web-extract/SKILL.md +82 -0
- echo_agent-0.2.1/skills/research/web-extract/scripts/extract_url.py +38 -0
- echo_agent-0.2.1/skills/research/web-search/SKILL.md +80 -0
- echo_agent-0.2.1/skills/research/web-search/scripts/web_search.py +54 -0
- echo_agent-0.2.1/skills/utility/calculator/SKILL.md +91 -0
- echo_agent-0.2.1/skills/utility/calculator/scripts/calc.py +103 -0
- echo_agent-0.2.1/skills/utility/file-convert/SKILL.md +59 -0
- echo_agent-0.2.1/skills/utility/file-convert/scripts/convert.py +83 -0
- echo_agent-0.2.1/skills/utility/maps-poi/SKILL.md +77 -0
- echo_agent-0.2.1/skills/utility/maps-poi/scripts/geo_query.py +86 -0
- echo_agent-0.2.1/skills/utility/text-tools/SKILL.md +86 -0
- echo_agent-0.2.1/skills/utility/text-tools/scripts/text_process.py +94 -0
- echo_agent-0.1.0/PKG-INFO +0 -286
- echo_agent-0.1.0/README.md +0 -219
- echo_agent-0.1.0/echo_agent/__main__.py +0 -538
- echo_agent-0.1.0/echo_agent/agent/consolidation.py +0 -96
- echo_agent-0.1.0/echo_agent/config/default.yaml +0 -199
- {echo_agent-0.1.0 → echo_agent-0.2.1}/.gitignore +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/a2a/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/a2a/client.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/a2a/models.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/compression/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/compression/assembler.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/compression/boundary.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/compression/engine.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/compression/pruner.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/compression/summarizer.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/compression/types.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/compression/validator.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/executors/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/executors/base.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/executors/factory.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/executors/remote.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/multi_agent/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/multi_agent/audit.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/multi_agent/error_messages.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/multi_agent/error_types.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/multi_agent/models.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/multi_agent/registry.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/pipeline/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/planning/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/planning/models.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/planning/reflection.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/planning/strategies.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/clarify.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/code_exec.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/cronjob.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/filesystem.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/image_gen.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/knowledge.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/memory.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/message.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/notify.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/patch.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/search.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/session_search.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/shell.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/skill_install.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/skills.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/task.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/todo.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/vision.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/agent/tools/workflow.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/bus/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/bus/events.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/dingtalk.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/discord.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/email.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/manager.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/qqbot_media.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/channels/wecom.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/colors.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/i18n/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/i18n/en.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/i18n/zh.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/prompt.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/service.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/cli/status.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/config/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evaluation/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evaluation/dataset.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evaluation/metrics.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evaluation/reporter.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evaluation/runner.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evolution/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evolution/evolver.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evolution/store.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/evolution/types.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/health.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/hooks.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/rate_limiter.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/session_policy.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/gateway/static/index.html +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/knowledge/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/knowledge/index.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/mcp/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/mcp/security.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/mcp/transport.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/memory/reviewer.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/providers/openrouter_provider.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/rate_limiter.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/models/tokenizer.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/observability/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/observability/monitor.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/observability/telemetry.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/permissions/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/permissions/manager.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/plugins/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/plugins/errors.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/runtime_paths.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/scheduler/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/security/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/security/capabilities.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/security/risk_classifier.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/session/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/skills/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/skills/manager.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/storage/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/storage/backend.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/tasks/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/tasks/manager.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/tasks/models.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/tasks/workflow.py +0 -0
- {echo_agent-0.1.0/echo_agent/agent → echo_agent-0.2.1/echo_agent}/tools/base.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/utils/__init__.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/utils/async_io.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/echo_agent/utils/text.py +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/scripts/install.sh +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/skills/development/plan/SKILL.md +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/skills/development/skill-creator/SKILL.md +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/skills/productivity/summarize/SKILL.md +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/skills/productivity/weather/SKILL.md +0 -0
- {echo_agent-0.1.0 → echo_agent-0.2.1}/skills/research/arxiv/SKILL.md +0 -0
echo_agent-0.2.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Echo Agent contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: echo-agent
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: A modular AI agent framework with multi-channel support
|
|
5
|
+
Author: Echo Agent contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: agent,ai,assistant,chatbot,runtime
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Requires-Dist: aiohttp>=3.9
|
|
16
|
+
Requires-Dist: aiosqlite>=0.20
|
|
17
|
+
Requires-Dist: croniter>=1.4
|
|
18
|
+
Requires-Dist: loguru>=0.7
|
|
19
|
+
Requires-Dist: numpy>=1.24
|
|
20
|
+
Requires-Dist: pydantic-settings>=2.0
|
|
21
|
+
Requires-Dist: pydantic>=2.0
|
|
22
|
+
Requires-Dist: pyyaml>=6.0
|
|
23
|
+
Provides-Extra: all
|
|
24
|
+
Requires-Dist: anthropic>=0.40; extra == 'all'
|
|
25
|
+
Requires-Dist: boto3>=1.34; extra == 'all'
|
|
26
|
+
Requires-Dist: cryptography>=41.0; extra == 'all'
|
|
27
|
+
Requires-Dist: faiss-cpu>=1.7; extra == 'all'
|
|
28
|
+
Requires-Dist: google-generativeai>=0.8; extra == 'all'
|
|
29
|
+
Requires-Dist: openai>=1.30; extra == 'all'
|
|
30
|
+
Requires-Dist: psutil>=5.9; extra == 'all'
|
|
31
|
+
Requires-Dist: tiktoken>=0.7; extra == 'all'
|
|
32
|
+
Provides-Extra: allproviders
|
|
33
|
+
Requires-Dist: anthropic>=0.40; extra == 'allproviders'
|
|
34
|
+
Requires-Dist: boto3>=1.34; extra == 'allproviders'
|
|
35
|
+
Requires-Dist: google-generativeai>=0.8; extra == 'allproviders'
|
|
36
|
+
Requires-Dist: openai>=1.30; extra == 'allproviders'
|
|
37
|
+
Provides-Extra: anthropic
|
|
38
|
+
Requires-Dist: anthropic>=0.40; extra == 'anthropic'
|
|
39
|
+
Provides-Extra: bedrock
|
|
40
|
+
Requires-Dist: anthropic>=0.40; extra == 'bedrock'
|
|
41
|
+
Requires-Dist: boto3>=1.34; extra == 'bedrock'
|
|
42
|
+
Provides-Extra: container
|
|
43
|
+
Requires-Dist: docker>=7.0; extra == 'container'
|
|
44
|
+
Provides-Extra: dev
|
|
45
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
46
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
47
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
48
|
+
Provides-Extra: gemini
|
|
49
|
+
Requires-Dist: google-generativeai>=0.8; extra == 'gemini'
|
|
50
|
+
Provides-Extra: openai
|
|
51
|
+
Requires-Dist: openai>=1.30; extra == 'openai'
|
|
52
|
+
Provides-Extra: otel
|
|
53
|
+
Requires-Dist: opentelemetry-api>=1.20; extra == 'otel'
|
|
54
|
+
Requires-Dist: opentelemetry-exporter-otlp>=1.20; extra == 'otel'
|
|
55
|
+
Requires-Dist: opentelemetry-sdk>=1.20; extra == 'otel'
|
|
56
|
+
Provides-Extra: process
|
|
57
|
+
Requires-Dist: psutil>=5.9; extra == 'process'
|
|
58
|
+
Provides-Extra: skills
|
|
59
|
+
Requires-Dist: caldav>=1.3; extra == 'skills'
|
|
60
|
+
Requires-Dist: croniter>=1.4; extra == 'skills'
|
|
61
|
+
Requires-Dist: duckduckgo-search>=7.0; extra == 'skills'
|
|
62
|
+
Requires-Dist: edge-tts>=7.0; extra == 'skills'
|
|
63
|
+
Requires-Dist: faster-whisper>=1.0; extra == 'skills'
|
|
64
|
+
Requires-Dist: feedparser>=6.0; extra == 'skills'
|
|
65
|
+
Requires-Dist: icalendar>=5.0; extra == 'skills'
|
|
66
|
+
Requires-Dist: markdown>=3.6; extra == 'skills'
|
|
67
|
+
Requires-Dist: openpyxl>=3.1; extra == 'skills'
|
|
68
|
+
Requires-Dist: pillow>=10.0; extra == 'skills'
|
|
69
|
+
Requires-Dist: psutil>=5.9; extra == 'skills'
|
|
70
|
+
Requires-Dist: pymupdf>=1.24; extra == 'skills'
|
|
71
|
+
Requires-Dist: pytesseract>=0.3; extra == 'skills'
|
|
72
|
+
Requires-Dist: python-docx>=1.1; extra == 'skills'
|
|
73
|
+
Requires-Dist: python-pptx>=1.0; extra == 'skills'
|
|
74
|
+
Requires-Dist: pyyaml>=6.0; extra == 'skills'
|
|
75
|
+
Requires-Dist: trafilatura>=2.0; extra == 'skills'
|
|
76
|
+
Provides-Extra: tokenizers
|
|
77
|
+
Requires-Dist: tiktoken>=0.7; extra == 'tokenizers'
|
|
78
|
+
Provides-Extra: vector
|
|
79
|
+
Requires-Dist: faiss-cpu>=1.7; extra == 'vector'
|
|
80
|
+
Provides-Extra: weixin
|
|
81
|
+
Requires-Dist: cryptography>=41.0; extra == 'weixin'
|
|
82
|
+
Description-Content-Type: text/markdown
|
|
83
|
+
|
|
84
|
+
<div align="center">
|
|
85
|
+
|
|
86
|
+
# Echo Agent
|
|
87
|
+
|
|
88
|
+
**记得住过去,学得会未来的开源 AI Agent**
|
|
89
|
+
|
|
90
|
+
<a href="https://github.com/fuyuxiang/echo-agent">
|
|
91
|
+
<img src="docs/assets/echo-agent.png" alt="Echo Agent" width="720" />
|
|
92
|
+
</a>
|
|
93
|
+
|
|
94
|
+
<br/>
|
|
95
|
+
|
|
96
|
+
[](https://pypi.org/project/echo-agent/)
|
|
97
|
+
[](https://pepy.tech/project/echo-agent)
|
|
98
|
+
[](https://github.com/fuyuxiang/echo-agent)
|
|
99
|
+
|
|
100
|
+
[中文](README.md) · [English](README.en.md)
|
|
101
|
+
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 什么是 Echo Agent
|
|
107
|
+
|
|
108
|
+
Echo Agent 是一个可自托管的长期运行 AI Agent。与一次性问答不同,它能:
|
|
109
|
+
|
|
110
|
+
- **跨会话记忆** — 四层认知记忆结构,自动衰减与矛盾检测,解决长期运行下的记忆膨胀问题,对话不再从零开始
|
|
111
|
+
- **自进化技能** — 从真实执行轨迹中生成候选改进,经评测验证后才生效,支持回滚
|
|
112
|
+
- **多入口归一** — CLI、Gateway、Webhook、Cron 及 Telegram / Discord / Slack / 微信 / 飞书 / 钉钉等 12 个通道共享同一份状态
|
|
113
|
+
- **安全可控** — 高风险工具调用经统一审批,凭证加密存储,执行日志可审计
|
|
114
|
+
|
|
115
|
+
一句话:**让 Agent 带着记忆和不断进化的技能,长期为你工作。**
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 快速开始
|
|
120
|
+
|
|
121
|
+
环境要求:Python 3.11+,至少一个模型 API Key。
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# 安装
|
|
125
|
+
pip install "echo-agent[all]"
|
|
126
|
+
|
|
127
|
+
# 配置模型 API Key(任选其一)
|
|
128
|
+
export OPENAI_API_KEY="sk-..."
|
|
129
|
+
# 也支持 ANTHROPIC_API_KEY / GOOGLE_API_KEY / OPENROUTER_API_KEY,
|
|
130
|
+
# 以及 AWS Bedrock(使用标准 AWS 凭证)
|
|
131
|
+
|
|
132
|
+
# 交互式配置向导(数据默认存放在 ~/.echo-agent)
|
|
133
|
+
echo-agent setup
|
|
134
|
+
|
|
135
|
+
# 启动
|
|
136
|
+
echo-agent run
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
<details>
|
|
140
|
+
<summary>国内镜像 / Windows / 一键脚本</summary>
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# 阿里云镜像加速
|
|
144
|
+
pip install "echo-agent[all]" -i https://mirrors.aliyun.com/pypi/simple/
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```powershell
|
|
148
|
+
# Windows(PowerShell)
|
|
149
|
+
pip install "echo-agent[all]"
|
|
150
|
+
$env:OPENAI_API_KEY = "sk-..."
|
|
151
|
+
echo-agent setup
|
|
152
|
+
echo-agent run
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# 一键安装脚本(仅支持 Linux / macOS / WSL2,会从源码安装到 ~/.echo-agent
|
|
157
|
+
# 并可注册 systemd 服务;建议先审查脚本内容再执行)
|
|
158
|
+
curl -fsSL -o install.sh https://raw.githubusercontent.com/fuyuxiang/echo-agent/master/scripts/install.sh
|
|
159
|
+
less install.sh && bash install.sh
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
</details>
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 架构总览
|
|
167
|
+
|
|
168
|
+
<div align="center">
|
|
169
|
+
<img src="docs/assets/architecture.png" alt="Echo Agent 架构图" width="820" />
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## 核心能力
|
|
175
|
+
|
|
176
|
+
| 模块 | 说明 |
|
|
177
|
+
|------|------|
|
|
178
|
+
| **Agent Loop** | 接收事件 → 构建上下文 → 调用模型 → 执行工具,跨入口共享同一条执行路径 |
|
|
179
|
+
| **认知记忆** | Working / Episodic / Semantic / Archival 四层,配合衰减、矛盾检测与重要性重排 |
|
|
180
|
+
| **混合检索** | BM25 + FAISS 向量融合召回,按查询特征自适应权重,FAISS 缺失时自动降级 |
|
|
181
|
+
| **自进化引擎** | 轨迹记录 → 候选生成 → 评测对照 → 晋升/驳回,支持冷却期与一键回滚 |
|
|
182
|
+
| **模型路由** | 主推理、上下文压缩、向量嵌入、风险审批可独立配置 provider 与模型 |
|
|
183
|
+
| **工具审批** | 三档策略 `manual` / `smart` / `off`,无人值守通道默认拒绝高风险调用 |
|
|
184
|
+
| **跨进程互操作** | A2A JSON-RPC + MCP 客户端(含 OAuth),支持动态工具注册 |
|
|
185
|
+
| **本地优先** | 会话、记忆、轨迹、凭证默认存放工作区,凭证加密落盘 |
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## 适用场景
|
|
190
|
+
|
|
191
|
+
- Agent 跑在本机或自有服务器,需要完整审计与可追溯
|
|
192
|
+
- 对话、偏好与任务经验需要跨会话长期沉淀
|
|
193
|
+
- 希望 Agent 技能从真实使用中持续改进,而非出厂定型
|
|
194
|
+
- 多入口(CLI、Webhook、消息机器人)需共享同一份记忆与权限
|
|
195
|
+
- 高风险工具需要强制审批,避免误操作
|
|
196
|
+
- 需同时接入多家模型 provider,按任务类型分配
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 开发与贡献
|
|
201
|
+
|
|
202
|
+
从源码安装(开发模式):
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
git clone https://github.com/fuyuxiang/echo-agent.git # 国内可用 https://gitee.com/fuyuxiang/echo-agent.git
|
|
206
|
+
cd echo-agent
|
|
207
|
+
uv venv venv --python 3.11 && source venv/bin/activate
|
|
208
|
+
uv pip install -e ".[all,dev]"
|
|
209
|
+
|
|
210
|
+
# 提交前检查
|
|
211
|
+
ruff check .
|
|
212
|
+
pytest
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
PR 前请确保 lint 和测试通过(CI 会在 PR 上自动运行同样的检查),并同步更新中英文 README。
|
|
216
|
+
|
|
217
|
+
**参与方向:** 通道适配器 · 内置工具 · MCP 集成 · 技能示例 · 评测数据集 · 文档完善 · 部署模板
|
|
218
|
+
|
|
219
|
+
**社区:**
|
|
220
|
+
- QQ群:[47572014](https://qm.qq.com/q/JWOPDBNssw)
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 协议
|
|
225
|
+
|
|
226
|
+
[MIT License](LICENSE)
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
## Star History
|
|
232
|
+
|
|
233
|
+
[](https://star-history.com/#fuyuxiang/echo-agent&Date)
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# Echo Agent
|
|
4
|
+
|
|
5
|
+
**记得住过去,学得会未来的开源 AI Agent**
|
|
6
|
+
|
|
7
|
+
<a href="https://github.com/fuyuxiang/echo-agent">
|
|
8
|
+
<img src="docs/assets/echo-agent.png" alt="Echo Agent" width="720" />
|
|
9
|
+
</a>
|
|
10
|
+
|
|
11
|
+
<br/>
|
|
12
|
+
|
|
13
|
+
[](https://pypi.org/project/echo-agent/)
|
|
14
|
+
[](https://pepy.tech/project/echo-agent)
|
|
15
|
+
[](https://github.com/fuyuxiang/echo-agent)
|
|
16
|
+
|
|
17
|
+
[中文](README.md) · [English](README.en.md)
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 什么是 Echo Agent
|
|
24
|
+
|
|
25
|
+
Echo Agent 是一个可自托管的长期运行 AI Agent。与一次性问答不同,它能:
|
|
26
|
+
|
|
27
|
+
- **跨会话记忆** — 四层认知记忆结构,自动衰减与矛盾检测,解决长期运行下的记忆膨胀问题,对话不再从零开始
|
|
28
|
+
- **自进化技能** — 从真实执行轨迹中生成候选改进,经评测验证后才生效,支持回滚
|
|
29
|
+
- **多入口归一** — CLI、Gateway、Webhook、Cron 及 Telegram / Discord / Slack / 微信 / 飞书 / 钉钉等 12 个通道共享同一份状态
|
|
30
|
+
- **安全可控** — 高风险工具调用经统一审批,凭证加密存储,执行日志可审计
|
|
31
|
+
|
|
32
|
+
一句话:**让 Agent 带着记忆和不断进化的技能,长期为你工作。**
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 快速开始
|
|
37
|
+
|
|
38
|
+
环境要求:Python 3.11+,至少一个模型 API Key。
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# 安装
|
|
42
|
+
pip install "echo-agent[all]"
|
|
43
|
+
|
|
44
|
+
# 配置模型 API Key(任选其一)
|
|
45
|
+
export OPENAI_API_KEY="sk-..."
|
|
46
|
+
# 也支持 ANTHROPIC_API_KEY / GOOGLE_API_KEY / OPENROUTER_API_KEY,
|
|
47
|
+
# 以及 AWS Bedrock(使用标准 AWS 凭证)
|
|
48
|
+
|
|
49
|
+
# 交互式配置向导(数据默认存放在 ~/.echo-agent)
|
|
50
|
+
echo-agent setup
|
|
51
|
+
|
|
52
|
+
# 启动
|
|
53
|
+
echo-agent run
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
<details>
|
|
57
|
+
<summary>国内镜像 / Windows / 一键脚本</summary>
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# 阿里云镜像加速
|
|
61
|
+
pip install "echo-agent[all]" -i https://mirrors.aliyun.com/pypi/simple/
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```powershell
|
|
65
|
+
# Windows(PowerShell)
|
|
66
|
+
pip install "echo-agent[all]"
|
|
67
|
+
$env:OPENAI_API_KEY = "sk-..."
|
|
68
|
+
echo-agent setup
|
|
69
|
+
echo-agent run
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# 一键安装脚本(仅支持 Linux / macOS / WSL2,会从源码安装到 ~/.echo-agent
|
|
74
|
+
# 并可注册 systemd 服务;建议先审查脚本内容再执行)
|
|
75
|
+
curl -fsSL -o install.sh https://raw.githubusercontent.com/fuyuxiang/echo-agent/master/scripts/install.sh
|
|
76
|
+
less install.sh && bash install.sh
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
</details>
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 架构总览
|
|
84
|
+
|
|
85
|
+
<div align="center">
|
|
86
|
+
<img src="docs/assets/architecture.png" alt="Echo Agent 架构图" width="820" />
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 核心能力
|
|
92
|
+
|
|
93
|
+
| 模块 | 说明 |
|
|
94
|
+
|------|------|
|
|
95
|
+
| **Agent Loop** | 接收事件 → 构建上下文 → 调用模型 → 执行工具,跨入口共享同一条执行路径 |
|
|
96
|
+
| **认知记忆** | Working / Episodic / Semantic / Archival 四层,配合衰减、矛盾检测与重要性重排 |
|
|
97
|
+
| **混合检索** | BM25 + FAISS 向量融合召回,按查询特征自适应权重,FAISS 缺失时自动降级 |
|
|
98
|
+
| **自进化引擎** | 轨迹记录 → 候选生成 → 评测对照 → 晋升/驳回,支持冷却期与一键回滚 |
|
|
99
|
+
| **模型路由** | 主推理、上下文压缩、向量嵌入、风险审批可独立配置 provider 与模型 |
|
|
100
|
+
| **工具审批** | 三档策略 `manual` / `smart` / `off`,无人值守通道默认拒绝高风险调用 |
|
|
101
|
+
| **跨进程互操作** | A2A JSON-RPC + MCP 客户端(含 OAuth),支持动态工具注册 |
|
|
102
|
+
| **本地优先** | 会话、记忆、轨迹、凭证默认存放工作区,凭证加密落盘 |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 适用场景
|
|
107
|
+
|
|
108
|
+
- Agent 跑在本机或自有服务器,需要完整审计与可追溯
|
|
109
|
+
- 对话、偏好与任务经验需要跨会话长期沉淀
|
|
110
|
+
- 希望 Agent 技能从真实使用中持续改进,而非出厂定型
|
|
111
|
+
- 多入口(CLI、Webhook、消息机器人)需共享同一份记忆与权限
|
|
112
|
+
- 高风险工具需要强制审批,避免误操作
|
|
113
|
+
- 需同时接入多家模型 provider,按任务类型分配
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 开发与贡献
|
|
118
|
+
|
|
119
|
+
从源码安装(开发模式):
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
git clone https://github.com/fuyuxiang/echo-agent.git # 国内可用 https://gitee.com/fuyuxiang/echo-agent.git
|
|
123
|
+
cd echo-agent
|
|
124
|
+
uv venv venv --python 3.11 && source venv/bin/activate
|
|
125
|
+
uv pip install -e ".[all,dev]"
|
|
126
|
+
|
|
127
|
+
# 提交前检查
|
|
128
|
+
ruff check .
|
|
129
|
+
pytest
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
PR 前请确保 lint 和测试通过(CI 会在 PR 上自动运行同样的检查),并同步更新中英文 README。
|
|
133
|
+
|
|
134
|
+
**参与方向:** 通道适配器 · 内置工具 · MCP 集成 · 技能示例 · 评测数据集 · 文档完善 · 部署模板
|
|
135
|
+
|
|
136
|
+
**社区:**
|
|
137
|
+
- QQ群:[47572014](https://qm.qq.com/q/JWOPDBNssw)
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 协议
|
|
142
|
+
|
|
143
|
+
[MIT License](LICENSE)
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
## Star History
|
|
149
|
+
|
|
150
|
+
[](https://star-history.com/#fuyuxiang/echo-agent&Date)
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"""Echo Agent CLI entry point — argument parsing and command dispatch.
|
|
2
|
+
|
|
3
|
+
All bootstrap and lifecycle logic lives in :mod:`echo_agent.app`.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
import asyncio
|
|
10
|
+
|
|
11
|
+
# Backward-compat re-exports: external code and older docs referenced these
|
|
12
|
+
# names on the script module before the composition root moved to app.py.
|
|
13
|
+
from echo_agent.app import ( # noqa: F401
|
|
14
|
+
BootstrapResult as _BootstrapResult,
|
|
15
|
+
bootstrap as _bootstrap,
|
|
16
|
+
run as _run,
|
|
17
|
+
run_gateway as _run_gateway,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _run_eval(args) -> None:
|
|
22
|
+
from pathlib import Path as _Path
|
|
23
|
+
|
|
24
|
+
config_path = args.config or getattr(args, "top_config", None)
|
|
25
|
+
workspace = args.workspace or getattr(args, "top_workspace", None)
|
|
26
|
+
|
|
27
|
+
from echo_agent.config.loader import load_config, resolve_config_file
|
|
28
|
+
config_file = resolve_config_file(config_path)
|
|
29
|
+
config = load_config(config_path=config_file)
|
|
30
|
+
|
|
31
|
+
dataset_path = args.dataset or config.evaluation.dataset_path
|
|
32
|
+
path = _Path(dataset_path)
|
|
33
|
+
if not path.exists():
|
|
34
|
+
print(f"Dataset not found: {path}")
|
|
35
|
+
print("Create a YAML file with test cases. Example:")
|
|
36
|
+
print(" - id: test_001")
|
|
37
|
+
print(" input: 'Hello'")
|
|
38
|
+
print(" expected_contains: ['hello', 'hi']")
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
from echo_agent.evaluation import EvalRunner, EvalDataset
|
|
42
|
+
|
|
43
|
+
dataset = EvalDataset.from_path(path)
|
|
44
|
+
if args.tag:
|
|
45
|
+
cases = dataset.filter_by_tag(args.tag)
|
|
46
|
+
dataset = EvalDataset(cases)
|
|
47
|
+
|
|
48
|
+
if not dataset.cases:
|
|
49
|
+
print("No test cases found.")
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
async def run():
|
|
53
|
+
from echo_agent.app import bootstrap
|
|
54
|
+
|
|
55
|
+
overrides = {"workspace": workspace} if workspace else None
|
|
56
|
+
ctx = await bootstrap(config_path=config_path, overrides=overrides)
|
|
57
|
+
await ctx.bus.start()
|
|
58
|
+
await ctx.agent.start()
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
runner = EvalRunner(ctx.agent, parallel=args.parallel, timeout=config.evaluation.timeout_per_case)
|
|
62
|
+
report = await runner.run_dataset(dataset)
|
|
63
|
+
|
|
64
|
+
from echo_agent.evaluation.reporter import EvalReporter
|
|
65
|
+
reporter = EvalReporter()
|
|
66
|
+
print(reporter.to_table(report))
|
|
67
|
+
|
|
68
|
+
if args.output:
|
|
69
|
+
_Path(args.output).write_text(reporter.to_json(report), encoding="utf-8")
|
|
70
|
+
print(f"\nResults saved to {args.output}")
|
|
71
|
+
finally:
|
|
72
|
+
from echo_agent.app import AppRuntime
|
|
73
|
+
await AppRuntime._stop_step("agent", ctx.agent.stop())
|
|
74
|
+
await AppRuntime._stop_step("bus", ctx.bus.stop())
|
|
75
|
+
await AppRuntime._stop_step("storage", ctx.storage.close())
|
|
76
|
+
|
|
77
|
+
asyncio.run(run())
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def main() -> None:
|
|
81
|
+
try:
|
|
82
|
+
_dispatch()
|
|
83
|
+
except Exception as e:
|
|
84
|
+
from echo_agent.config.loader import ConfigError
|
|
85
|
+
if isinstance(e, ConfigError):
|
|
86
|
+
import sys
|
|
87
|
+
print(f"配置错误 / Configuration error:\n{e}", file=sys.stderr)
|
|
88
|
+
sys.exit(1)
|
|
89
|
+
raise
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _dispatch() -> None:
|
|
93
|
+
parser = argparse.ArgumentParser(prog="echo-agent", description="Echo Agent — modular AI agent framework")
|
|
94
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
95
|
+
|
|
96
|
+
# run
|
|
97
|
+
run_parser = subparsers.add_parser("run", help="Start the agent")
|
|
98
|
+
run_parser.add_argument("-c", "--config", help="Path to config file")
|
|
99
|
+
run_parser.add_argument("-w", "--workspace", help="Workspace directory")
|
|
100
|
+
|
|
101
|
+
# setup
|
|
102
|
+
setup_parser = subparsers.add_parser("setup", help="Run the setup wizard")
|
|
103
|
+
setup_parser.add_argument(
|
|
104
|
+
"section", nargs="?", default=None,
|
|
105
|
+
help="Setup section: language, model, permissions, terminal, agent, tools, channel, gateway, observability, evolution, doctor",
|
|
106
|
+
)
|
|
107
|
+
setup_parser.add_argument("-c", "--config", help="Path to config file")
|
|
108
|
+
setup_parser.add_argument("-w", "--workspace", help="Workspace directory")
|
|
109
|
+
setup_parser.add_argument("--lang", choices=["en", "zh", "auto"], default=None,
|
|
110
|
+
help="Override interface language (default: auto-detect from OS)")
|
|
111
|
+
setup_parser.add_argument("--flow", choices=["quickstart", "full"], default=None,
|
|
112
|
+
help="Skip the menu and run a specific flow")
|
|
113
|
+
|
|
114
|
+
# status
|
|
115
|
+
status_parser = subparsers.add_parser("status", help="Show current configuration status")
|
|
116
|
+
status_parser.add_argument("-c", "--config", help="Path to config file")
|
|
117
|
+
status_parser.add_argument("-w", "--workspace", help="Workspace directory")
|
|
118
|
+
|
|
119
|
+
# gateway
|
|
120
|
+
gw_parser = subparsers.add_parser("gateway", help="Start the gateway server")
|
|
121
|
+
gw_parser.add_argument("-c", "--config", help="Path to config file")
|
|
122
|
+
gw_parser.add_argument("-w", "--workspace", help="Workspace directory")
|
|
123
|
+
gw_parser.add_argument("--host", help="Gateway host")
|
|
124
|
+
gw_parser.add_argument("--port", type=int, help="Gateway port")
|
|
125
|
+
|
|
126
|
+
# eval
|
|
127
|
+
eval_parser = subparsers.add_parser("eval", help="Run evaluation test suite")
|
|
128
|
+
eval_parser.add_argument("--dataset", "-d", default="", help="Path to eval dataset (YAML/JSON)")
|
|
129
|
+
eval_parser.add_argument("--tag", "-t", default="", help="Filter cases by tag")
|
|
130
|
+
eval_parser.add_argument("--parallel", "-p", type=int, default=3, help="Parallel cases")
|
|
131
|
+
eval_parser.add_argument("--output", "-o", default="", help="Output file for results")
|
|
132
|
+
eval_parser.add_argument("-c", "--config", help="Path to config file")
|
|
133
|
+
eval_parser.add_argument("-w", "--workspace", help="Workspace directory")
|
|
134
|
+
|
|
135
|
+
# service
|
|
136
|
+
svc_parser = subparsers.add_parser("service", help="Manage systemd service (Linux)")
|
|
137
|
+
svc_parser.add_argument("action", choices=["install", "uninstall", "start", "stop", "restart", "status", "logs"], help="Service action")
|
|
138
|
+
svc_parser.add_argument("-w", "--workspace", help="Workspace directory (used by install)")
|
|
139
|
+
|
|
140
|
+
# plugin
|
|
141
|
+
plugin_parser = subparsers.add_parser("plugin", help="Manage plugins")
|
|
142
|
+
plugin_parser.add_argument("action", choices=["list", "info", "enable", "disable", "check"], help="Plugin action")
|
|
143
|
+
plugin_parser.add_argument("name", nargs="?", default="", help="Plugin name (for info/enable/disable)")
|
|
144
|
+
plugin_parser.add_argument("-c", "--config", help="Path to config file")
|
|
145
|
+
plugin_parser.add_argument("-w", "--workspace", help="Workspace directory")
|
|
146
|
+
|
|
147
|
+
# evolution
|
|
148
|
+
evo_parser = subparsers.add_parser("evolution", help="Manage the self-evolving skill harness")
|
|
149
|
+
evo_parser.add_argument(
|
|
150
|
+
"action",
|
|
151
|
+
choices=[
|
|
152
|
+
"status", "run", "list-candidates", "show-candidate",
|
|
153
|
+
"promote", "rollback", "init-dataset",
|
|
154
|
+
],
|
|
155
|
+
help="Evolution action",
|
|
156
|
+
)
|
|
157
|
+
evo_parser.add_argument("target", nargs="?", default="", help="Skill name (rollback) or candidate id (show-candidate/promote)")
|
|
158
|
+
evo_parser.add_argument("--status", dest="status_filter", default="", help="Filter list-candidates by status")
|
|
159
|
+
evo_parser.add_argument("-c", "--config", help="Path to config file")
|
|
160
|
+
evo_parser.add_argument("-w", "--workspace", help="Workspace directory")
|
|
161
|
+
|
|
162
|
+
# top-level flags for backward compat
|
|
163
|
+
parser.add_argument("-c", "--config", help="Path to config file", dest="top_config")
|
|
164
|
+
parser.add_argument("-w", "--workspace", help="Workspace directory", dest="top_workspace")
|
|
165
|
+
|
|
166
|
+
args = parser.parse_args()
|
|
167
|
+
|
|
168
|
+
if args.command == "setup":
|
|
169
|
+
from echo_agent.cli.setup import run_setup_wizard
|
|
170
|
+
lang_arg = getattr(args, "lang", None)
|
|
171
|
+
if lang_arg == "auto":
|
|
172
|
+
lang_arg = None
|
|
173
|
+
run_setup_wizard(
|
|
174
|
+
section=args.section,
|
|
175
|
+
config_path=args.config or args.top_config,
|
|
176
|
+
workspace=args.workspace or args.top_workspace,
|
|
177
|
+
lang=lang_arg,
|
|
178
|
+
flow=getattr(args, "flow", None),
|
|
179
|
+
)
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
if args.command == "status":
|
|
183
|
+
from echo_agent.cli.status import show_status
|
|
184
|
+
show_status(config_path=args.config or args.top_config, workspace=args.workspace or args.top_workspace)
|
|
185
|
+
return
|
|
186
|
+
|
|
187
|
+
if args.command == "gateway":
|
|
188
|
+
from echo_agent.app import run_gateway
|
|
189
|
+
try:
|
|
190
|
+
asyncio.run(run_gateway(config_path=args.config or args.top_config, host=args.host, port=args.port, workspace=args.workspace or args.top_workspace))
|
|
191
|
+
except KeyboardInterrupt:
|
|
192
|
+
pass
|
|
193
|
+
return
|
|
194
|
+
|
|
195
|
+
if args.command == "eval":
|
|
196
|
+
_run_eval(args)
|
|
197
|
+
return
|
|
198
|
+
|
|
199
|
+
if args.command == "service":
|
|
200
|
+
from echo_agent.cli.service import run_action
|
|
201
|
+
run_action(args.action, workspace=args.workspace or args.top_workspace)
|
|
202
|
+
return
|
|
203
|
+
|
|
204
|
+
if args.command == "plugin":
|
|
205
|
+
from echo_agent.cli.plugins_cmd import run_plugin_command
|
|
206
|
+
run_plugin_command(
|
|
207
|
+
action=args.action,
|
|
208
|
+
name=args.name,
|
|
209
|
+
config_path=args.config or args.top_config,
|
|
210
|
+
workspace=args.workspace or args.top_workspace,
|
|
211
|
+
)
|
|
212
|
+
return
|
|
213
|
+
|
|
214
|
+
if args.command == "evolution":
|
|
215
|
+
from echo_agent.cli.evolution_cmd import run_evolution_command
|
|
216
|
+
target = getattr(args, "target", "") or ""
|
|
217
|
+
skill = ""
|
|
218
|
+
candidate_id = ""
|
|
219
|
+
if args.action == "rollback":
|
|
220
|
+
skill = target
|
|
221
|
+
elif args.action in ("show-candidate", "promote"):
|
|
222
|
+
candidate_id = target
|
|
223
|
+
try:
|
|
224
|
+
run_evolution_command(
|
|
225
|
+
action=args.action,
|
|
226
|
+
skill=skill,
|
|
227
|
+
status_filter=getattr(args, "status_filter", "") or "",
|
|
228
|
+
candidate_id=candidate_id,
|
|
229
|
+
config_path=args.config or args.top_config,
|
|
230
|
+
workspace=args.workspace or args.top_workspace,
|
|
231
|
+
)
|
|
232
|
+
except KeyboardInterrupt:
|
|
233
|
+
pass
|
|
234
|
+
return
|
|
235
|
+
|
|
236
|
+
# "run" command or no command (backward compat)
|
|
237
|
+
config_path = getattr(args, "config", None) or args.top_config
|
|
238
|
+
workspace = getattr(args, "workspace", None) or args.top_workspace
|
|
239
|
+
|
|
240
|
+
from echo_agent.cli.setup import prompt_first_run_setup
|
|
241
|
+
if prompt_first_run_setup(config_path=config_path, workspace=workspace):
|
|
242
|
+
return
|
|
243
|
+
|
|
244
|
+
from echo_agent.app import run
|
|
245
|
+
try:
|
|
246
|
+
asyncio.run(run(config_path=config_path, workspace=workspace))
|
|
247
|
+
except KeyboardInterrupt:
|
|
248
|
+
pass
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
if __name__ == "__main__":
|
|
252
|
+
main()
|