illusion-code 0.2.9__tar.gz → 0.2.10__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.
- {illusion_code-0.2.9 → illusion_code-0.2.10}/PKG-INFO +1 -1
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/package-lock.json +2 -2
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/package.json +1 -1
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/version.ts +1 -1
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/package-lock.json +2 -2
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/package.json +1 -1
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/version.ts +1 -1
- {illusion_code-0.2.9 → illusion_code-0.2.10}/pyproject.toml +1 -1
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/__init__.py +1 -1
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/__init__.py +132 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/base_commands.py +4 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/serve.py +31 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/cli.py +82 -12
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/i18n.py +8 -1
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/web/ws_host.py +5 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/.github/workflows/publish.yml +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/.gitignore +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/.python-version +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/LICENSE +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/README.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/README.zh-CN.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/architecture.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/channels.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/commands.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/extensions.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/getting-started.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/introduction.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/project-files.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/en/settings.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/images/IllusionCode.png +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/images/image1.png +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/images/image2.png +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/architecture.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/channels.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/commands.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/extensions.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/getting-started.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/introduction.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/project-files.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/docs/zh-CN/settings.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/build.mjs +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/App.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/CommandPicker.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/Composer.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ComposerController.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ConversationView.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/Footer.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/MarkdownContent.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/MarkdownTable.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ModalHost.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/MultilineTextInput.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/PromptInput.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/QuestionNavigationBar.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/QuestionPreviewBox.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/SelectModal.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/SidePanel.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/Spinner.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/StatusBar.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/SwarmPanel.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/TodoPanel.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ToolCallDisplay.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/TranscriptPane.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/WelcomeBanner.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useAnimationFrame.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useBackendSession.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useBlink.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useQuestionState.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/hooks/useTerminalSize.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/i18n.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/index.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/theme/ThemeContext.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/theme/builtinThemes.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/ToolInterface.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/AgentTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/BashTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/CronTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/EditTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/GenericTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/LspTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/McpTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/NotebookTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/PlanTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/ReadTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/SearchTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/SkillTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/TaskTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/WebTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/WorktreeTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/implementations/WriteTool.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/tools/registry.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/types.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/utils/markdown.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/utils/thinking.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/tsconfig.json +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/index.html +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/postcss.config.js +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/App.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/ChatArea.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/ErrorBoundary.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/MessageBubble.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/ModalCard.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/PromptInput.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/RightPanel.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/Sidebar.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/TodoPanel.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/Toolbar.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/components/WelcomeScreen.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/hooks/useTheme.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/hooks/useWebSocketSession.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/i18n.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/index.css +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/main.tsx +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/remarkSuperscript.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/types/protocol.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/utils/toolDisplayName.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/src/vite-env.d.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/tailwind.config.js +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/tsconfig.json +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/tsconfig.node.json +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/web/vite.config.ts +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/scripts/build_frontend.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/scripts/hatch_build.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/scripts/publish.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/scripts/sync_version.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/__main__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/codex_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/compat.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/effort.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/errors.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/openai_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/provider.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/registry.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/api/usage.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/codex_oauth.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/copilot.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/external.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/flows.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/manager.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/auth/storage.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/manager.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/session_runner.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/bridge/work_secret.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/base.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/config.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/delivery.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/adapter.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/commands.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/messaging.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/session_map.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/streaming.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/feishu/ws_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/pid.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/adapter.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/api.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/commands.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/session_map.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/streaming.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/qq/ws_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/cross_channel.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/feishu_doc.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/feishu_drive.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/tools/media.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/adapter.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/commands.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/ilink_api.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/channels/weixin/session_map.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/auth.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/bridge.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/context.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/git.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/helpers.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/architecture.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/conventions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/dependencies.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/analysis/key_modules.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/extraction/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/extraction/lsp_symbols.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/extraction/readme.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/extraction/scanner.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/claudemd.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/illusionmd.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/memory_template.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/rules.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/generation/sections.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/orchestrator.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/init/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/mcp.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/memory.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/misc.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/model.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/plugin.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/registry.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/rules.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/sandbox.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/session.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/settings.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/commands/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/paths.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/plan_file.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/config/settings.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/coordinator/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/coordinator/agent_definitions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/coordinator/coordinator_mode.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/cost_tracker.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/messages.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/query.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/query_engine.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/engine/stream_events.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/events.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/executor.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/hot_reload.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/loader.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/register_hooks.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/schemas.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/session_hooks.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/hooks/utils.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/mcp/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/mcp/client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/mcp/config.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/mcp/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/manager.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/memdir.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/paths.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/scan.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/search.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/memory/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/output_styles/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/output_styles/loader.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/checker.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/loader.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/modes.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/permissions/schemas.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/platforms.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/installer.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/loader.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/options.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/schemas.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/plugins/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/channel_hints.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/claudemd.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/context.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/environment.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/prompts/system_prompt.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/adapter.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/base.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/linux.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/macos.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/platforms/windows.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/proxy/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/proxy/env_vars.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/runtime.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/symlink_protection.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/utils.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/sandbox/violation_store.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/auto_compact.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/compact_core.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/compact_prompt.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/constants.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/message_ops.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/microcompact.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/models.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/compact/token_utils.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/cron.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/cron_scheduler.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/file_history.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/config.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/manager.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/lsp/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/session_storage.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/services/token_estimation.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/batch.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/debug.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/loop.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/remember.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/simplify.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/skillify.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/stuck.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/update-config.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/bundled/content/verify.md +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/loader.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/registry.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/skills/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/state/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/state/app_state.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/state/store.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/agent_executor.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/in_process.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/subprocess_backend.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/team_helpers.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/swarm/worktree.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/local_agent_task.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/local_shell_task.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/manager.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/stop_task.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/todo_sync.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tasks/types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/agent_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/ask_user_question_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/base.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/bash_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/config_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/cron_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/enter_plan_mode_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/enter_worktree_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/exit_plan_mode_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/exit_worktree_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/file_edit_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/file_read_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/file_write_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/glob_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/grep_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/list_mcp_resources_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/lsp_formatters.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/lsp_schemas.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/lsp_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/mcp_auth_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/mcp_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/notebook_edit_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/powershell_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/read_mcp_resource_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/repl_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/send_message_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/shell_common.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/skill_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/sleep_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/structured_output_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_create_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_get_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_list_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_output_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_stop_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/task_update_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/team_create_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/team_delete_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/todo_write_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/tool_search_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/web_fetch_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/tools/web_search_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/app.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/backend_host.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/input.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/output.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/permission_dialog.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/permission_store.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/protocol.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/react_launcher.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/runtime.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/textual_app.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/web/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/web/server.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/ui/web/ws_web_api.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/atomic_write.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/file_state_cache.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/ripgrep.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/src/illusion/utils/shell.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_anthropic_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_codex_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_effort.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_fallback/346/217/220/347/244/272.py" +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/api/test_openai_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/feishu/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/feishu/test_adapter.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/feishu/test_commands.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/feishu/test_session_map.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_base.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_base_commands.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_config.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_pid.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/test_tool_registration.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/tools/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/tools/test_feishu_doc.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/tools/test_feishu_drive.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/test_adapter.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/test_config.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/test_ilink_api.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/channels/weixin/test_session_map.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/test_claudemd.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/test_orchestrator.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/test_scanner.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/init/test_sections.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/commands/test_effort_command.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/config/test_i18n.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/config/test_settings.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/conftest.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/engine/test_query_engine.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/fixtures/fake_mcp_server.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/integration/test_effort_integration.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/services/lsp/test_lsp_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/services/lsp/test_lsp_config.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/services/lsp/test_lsp_manager.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/services/lsp/test_lsp_types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/test_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/test_codex_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/test_compat.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_api/test_openai_client.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_auth/test_external.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_bridge/test_core.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_bridge/test_session_flow.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_commands/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_commands/test_cli.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_commands/test_command_flows.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_commands/test_registry.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_config/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_config/test_paths.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_config/test_settings.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_coordinator/test_agent_definitions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_coordinator/test_coordinator_mode.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_engine/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_engine/test_media_block.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_engine/test_query_engine.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_engine/test_tool_result_media.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_hooks/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_hooks/test_executor.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_hooks/test_loader_permissions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_hooks_skills_plugins_real.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_mcp/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_mcp/test_config_permissions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_mcp/test_integration.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_mcp/test_stdio_flow.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_memory/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_memory/test_manager_permissions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_memory/test_memdir.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_merged_prs_on_autoagent.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_permissions/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_permissions/test_checker.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_permissions/test_loader.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_permissions/test_project_permissions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_platforms.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_plugins/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_plugins/test_lifecycle_flow.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_plugins/test_loader.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_plugins/test_loader_permissions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/test_claudemd.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/test_claudemd_permissions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/test_environment.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_prompts/test_system_prompt.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_qq_channel.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_real_large_tasks.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_adapter.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_config_schema.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_platform_linux.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_platform_macos.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_platform_windows.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_proxy_env_vars.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_runtime.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_symlink_protection.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_utils.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_sandbox/test_violation_store.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_scripts/test_sync_version.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_services/test_compact.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_services/test_cron.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_services/test_cron_scheduler.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_services/test_session_storage.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_skills/test_loader.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_skills/test_loader_permissions.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_agent_executor.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_imports.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_in_process.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_types.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_swarm/test_worktree.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tasks/test_manager.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_agent_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_core_tools.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_file_read_media.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_glob_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_grep_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_integration.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_integration_flows.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_mcp_auth_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_ripgrep.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_shell_common.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_task_tools.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_team_tools.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_tools/test_web_fetch_tool.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_modes.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_permission_store.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_react_backend.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_react_launcher.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_ui/test_textual_app.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_untested_features.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/test_utils/test_shell.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/ui/test_backend_host.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/ui/test_protocol_web.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/ui/test_web_api.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/__init__.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_channel_hints.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_cross_channel.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_delivery.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_feishu_streaming.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_media_tools.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_qq_streaming.py +0 -0
- {illusion_code-0.2.9 → illusion_code-0.2.10}/tests/unit/test_session_list_active.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: illusion-code
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.10
|
|
4
4
|
Summary: Open-source Python port of Claude Code - an AI-powered CLI coding assistant
|
|
5
5
|
Project-URL: Homepage, https://github.com/YunTaiHua/illusion-code
|
|
6
6
|
Project-URL: Repository, https://github.com/YunTaiHua/illusion-code
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@illusion/terminal",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@illusion/terminal",
|
|
9
|
-
"version": "0.2.
|
|
9
|
+
"version": "0.2.10",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"chalk": "^5.6.2",
|
|
12
12
|
"ink": "^5.1.0",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@illusion/web",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@illusion/web",
|
|
9
|
-
"version": "0.2.
|
|
9
|
+
"version": "0.2.10",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"highlight.js": "^11.11.0",
|
|
12
12
|
"react": "^18.3.1",
|
|
@@ -173,6 +173,68 @@ def kill_channel_daemon(proc: "subprocess.Popen[bytes] | None") -> None:
|
|
|
173
173
|
pass
|
|
174
174
|
|
|
175
175
|
|
|
176
|
+
def is_channel_daemon_running() -> bool:
|
|
177
|
+
"""检查渠道守护进程是否正在运行(通过 PID 文件,不依赖 proc 引用)
|
|
178
|
+
|
|
179
|
+
用于退出时判断是否需要询问用户是否一同退出渠道。
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
bool: 守护进程在运行返回 True
|
|
183
|
+
"""
|
|
184
|
+
from illusion.config.paths import get_channels_data_dir
|
|
185
|
+
from illusion.channels.pid import PidFile
|
|
186
|
+
pid_file = PidFile(get_channels_data_dir() / "daemon.pid")
|
|
187
|
+
return pid_file.is_running()
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def stop_channel_daemon_by_pid() -> bool:
|
|
191
|
+
"""通过 PID 文件停止渠道守护进程(不依赖 proc 引用)
|
|
192
|
+
|
|
193
|
+
供退出时交互式确认使用:无论当前进程是否是 spawn 者,
|
|
194
|
+
都可以通过 PID 文件停止守护进程。
|
|
195
|
+
|
|
196
|
+
Windows 上用 taskkill /T /F 终止整个进程树(守护进程可能 spawn 了
|
|
197
|
+
aiohttp/WS 子线程,单独 TerminateProcess 可能留下孤儿线程)。
|
|
198
|
+
Unix 上用 SIGTERM 终止进程组。
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
bool: 成功停止返回 True,守护进程不存在或已停止返回 False
|
|
202
|
+
"""
|
|
203
|
+
from illusion.config.paths import get_channels_data_dir
|
|
204
|
+
from illusion.channels.pid import PidFile, read_pid
|
|
205
|
+
|
|
206
|
+
pid_file = PidFile(get_channels_data_dir() / "daemon.pid")
|
|
207
|
+
if not pid_file.is_running():
|
|
208
|
+
pid_file.release()
|
|
209
|
+
return False
|
|
210
|
+
|
|
211
|
+
old_pid = read_pid(pid_file.path)
|
|
212
|
+
if old_pid is not None:
|
|
213
|
+
try:
|
|
214
|
+
if os.name == "nt":
|
|
215
|
+
# Windows: 用 taskkill /T /F 终止整个进程树
|
|
216
|
+
# /T = 终止子进程,/F = 强制终止
|
|
217
|
+
import subprocess as _sp
|
|
218
|
+
_sp.run(
|
|
219
|
+
["taskkill", "/PID", str(old_pid), "/T", "/F"],
|
|
220
|
+
capture_output=True, timeout=5,
|
|
221
|
+
)
|
|
222
|
+
else:
|
|
223
|
+
# Unix: 用 SIGTERM 终止进程组
|
|
224
|
+
import signal
|
|
225
|
+
os.kill(old_pid, signal.SIGTERM)
|
|
226
|
+
except (OSError, ProcessLookupError, Exception): # noqa: BLE001
|
|
227
|
+
pass
|
|
228
|
+
# 等待进程退出,最多 3 秒
|
|
229
|
+
for _ in range(30):
|
|
230
|
+
if not pid_file.is_running():
|
|
231
|
+
break
|
|
232
|
+
import time as _time
|
|
233
|
+
_time.sleep(0.1)
|
|
234
|
+
pid_file.release()
|
|
235
|
+
return True
|
|
236
|
+
|
|
237
|
+
|
|
176
238
|
class ChannelRunner:
|
|
177
239
|
"""渠道消息接入 agent 的运行器
|
|
178
240
|
|
|
@@ -210,6 +272,8 @@ class ChannelRunner:
|
|
|
210
272
|
# 按 chat_id 串行化 agent turn,避免并行消息导致会话历史覆盖
|
|
211
273
|
# (同一会话连发多条消息时,M2/M3 排队等 M1 完成后再跑)
|
|
212
274
|
self._chat_locks: dict[str, asyncio.Lock] = {}
|
|
275
|
+
# 当前正在运行的 agent task(按 chat_id 索引),供 /stop 中断
|
|
276
|
+
self._active_agent_tasks: dict[str, asyncio.Task[None]] = {}
|
|
213
277
|
self._stop = False
|
|
214
278
|
|
|
215
279
|
def _get_chat_lock(self, chat_id: str) -> asyncio.Lock:
|
|
@@ -255,6 +319,8 @@ class ChannelRunner:
|
|
|
255
319
|
msg: 入站消息
|
|
256
320
|
"""
|
|
257
321
|
# 检查 /delete 信号:先执行 /new(清所有会话+发确认),再处理消息
|
|
322
|
+
# 信号触发后直接 return,避免继续走 try_handle 处理 /new 命令
|
|
323
|
+
# 导致"已开启新的对话"反馈消息发送两次
|
|
258
324
|
if self.session_store.check_signal():
|
|
259
325
|
for path in self.session_store.data_dir.glob("*.json"):
|
|
260
326
|
try:
|
|
@@ -267,6 +333,7 @@ class ChannelRunner:
|
|
|
267
333
|
msg.chat_id, _t("cmd_new"), reply_to=msg.message_id,
|
|
268
334
|
)
|
|
269
335
|
self.session_store.clear_signal()
|
|
336
|
+
return
|
|
270
337
|
|
|
271
338
|
# 1. 待回复的权限/询问——不加锁,让回复立即送达
|
|
272
339
|
# (agent turn 持锁等待回复时,下一条消息作为回复立即 set_result,
|
|
@@ -277,6 +344,13 @@ class ChannelRunner:
|
|
|
277
344
|
fut.set_result(msg.text)
|
|
278
345
|
return
|
|
279
346
|
|
|
347
|
+
# /stop 命令:立即中断当前 chat_id 正在运行的 agent task,不排队等锁
|
|
348
|
+
# 必须在 _chat_locks 之前处理,否则会卡在串行队列里等到 agent 完成才生效
|
|
349
|
+
text = msg.text.strip()
|
|
350
|
+
if text.lower() == "/stop":
|
|
351
|
+
await self._handle_stop(msg)
|
|
352
|
+
return
|
|
353
|
+
|
|
280
354
|
# 2/3. 斜杠命令 + agent turn:按 chat_id 串行化
|
|
281
355
|
async with self._get_chat_lock(msg.chat_id):
|
|
282
356
|
# 进入锁后再次检查 pending_replies:前一个 agent turn 可能
|
|
@@ -293,14 +367,33 @@ class ChannelRunner:
|
|
|
293
367
|
return
|
|
294
368
|
|
|
295
369
|
# 3. 跑 agent
|
|
370
|
+
# 将当前 task 注册到 _active_agent_tasks,供 /stop 中断
|
|
371
|
+
current_task = asyncio.current_task()
|
|
372
|
+
if current_task is not None:
|
|
373
|
+
self._active_agent_tasks[msg.chat_id] = current_task
|
|
296
374
|
try:
|
|
297
375
|
await self._run_agent(msg)
|
|
376
|
+
except asyncio.CancelledError:
|
|
377
|
+
# /stop 取消:agent 已中断,发提示消息
|
|
378
|
+
from illusion.config.i18n import t as _t
|
|
379
|
+
logger.info("agent 任务被 /stop 中断: chat_id=%s", msg.chat_id)
|
|
380
|
+
try:
|
|
381
|
+
await self.channel.send_text(
|
|
382
|
+
msg.chat_id, _t("cmd_stop_done"),
|
|
383
|
+
reply_to=msg.message_id,
|
|
384
|
+
)
|
|
385
|
+
except Exception: # noqa: BLE001
|
|
386
|
+
pass
|
|
387
|
+
raise
|
|
298
388
|
except Exception as exc: # noqa: BLE001
|
|
299
389
|
logger.exception("处理渠道消息异常: %s", exc)
|
|
300
390
|
try:
|
|
301
391
|
await self.channel.send_text(msg.chat_id, f"❌ 处理失败: {str(exc)[:100]}")
|
|
302
392
|
except Exception: # noqa: BLE001
|
|
303
393
|
pass
|
|
394
|
+
finally:
|
|
395
|
+
# 清理 task 注册(无论正常完成、异常还是取消)
|
|
396
|
+
self._active_agent_tasks.pop(msg.chat_id, None)
|
|
304
397
|
|
|
305
398
|
def _get_command_handler(self) -> Any:
|
|
306
399
|
"""按渠道类型返回对应的斜杠命令处理器
|
|
@@ -328,6 +421,31 @@ class ChannelRunner:
|
|
|
328
421
|
pass # QQ 模块不可用时跳过
|
|
329
422
|
return None
|
|
330
423
|
|
|
424
|
+
async def _handle_stop(self, msg: "InboundMessage") -> None:
|
|
425
|
+
"""处理 /stop 命令:中断当前 chat_id 正在运行的 agent 任务
|
|
426
|
+
|
|
427
|
+
不加 _chat_locks 锁,立即取消正在运行的 agent task。
|
|
428
|
+
如果没有正在运行的任务,回复提示"无正在执行的任务"。
|
|
429
|
+
|
|
430
|
+
Args:
|
|
431
|
+
msg: /stop 命令消息
|
|
432
|
+
"""
|
|
433
|
+
from illusion.config.i18n import t as _t
|
|
434
|
+
|
|
435
|
+
task = self._active_agent_tasks.get(msg.chat_id)
|
|
436
|
+
if task is None or task.done():
|
|
437
|
+
# 无正在运行的任务
|
|
438
|
+
await self.channel.send_text(
|
|
439
|
+
msg.chat_id, _t("cmd_stop_no_task"),
|
|
440
|
+
reply_to=msg.message_id,
|
|
441
|
+
)
|
|
442
|
+
return
|
|
443
|
+
|
|
444
|
+
# 取消任务:触发 CancelledError,_run_agent 的 except 块清理流式控制器
|
|
445
|
+
# _handle_message 的 except CancelledError 块发送"已中断"提示
|
|
446
|
+
task.cancel()
|
|
447
|
+
logger.info("/stop 已取消 agent 任务: chat_id=%s", msg.chat_id)
|
|
448
|
+
|
|
331
449
|
def _build_channel_tools(self, msg: "InboundMessage") -> list[Any]:
|
|
332
450
|
"""构造渠道内置工具列表
|
|
333
451
|
|
|
@@ -613,6 +731,20 @@ class ChannelRunner:
|
|
|
613
731
|
logger.warning("渠道会话持久化失败: %s", exc)
|
|
614
732
|
else:
|
|
615
733
|
logger.warning("无法从 bundle.engine 获取会话历史,跳过持久化")
|
|
734
|
+
except asyncio.CancelledError:
|
|
735
|
+
# /stop 中断:清理流式控制器后重新抛出,让上层 _handle_message 发提示
|
|
736
|
+
logger.info("agent 任务被取消: chat_id=%s", msg.chat_id)
|
|
737
|
+
if supports_edit and streaming_controller:
|
|
738
|
+
try:
|
|
739
|
+
await streaming_controller.error("已中断")
|
|
740
|
+
except Exception: # noqa: BLE001
|
|
741
|
+
pass
|
|
742
|
+
elif qq_streaming_controller:
|
|
743
|
+
try:
|
|
744
|
+
await qq_streaming_controller.abort("已中断")
|
|
745
|
+
except Exception: # noqa: BLE001
|
|
746
|
+
pass
|
|
747
|
+
raise
|
|
616
748
|
except Exception as exc:
|
|
617
749
|
logger.exception("agent 处理异常")
|
|
618
750
|
if supports_edit and streaming_controller:
|
|
@@ -80,6 +80,10 @@ class BaseCommandHandler:
|
|
|
80
80
|
elif cmd == "new":
|
|
81
81
|
self.session_store.clear(key)
|
|
82
82
|
await self._reply(msg, t("cmd_new"))
|
|
83
|
+
elif cmd == "stop":
|
|
84
|
+
# /stop 在 ChannelRunner._handle_message 开头已被拦截处理,
|
|
85
|
+
# 不会走到这里。此分支仅作为防御性兜底(如 PC 终端直接调用)
|
|
86
|
+
await self._reply(msg, t("cmd_stop_no_task"))
|
|
83
87
|
elif cmd == "model":
|
|
84
88
|
await self._cmd_model(msg, key, args)
|
|
85
89
|
elif cmd == "sessions":
|
|
@@ -32,6 +32,24 @@ def run_channel_serve() -> None:
|
|
|
32
32
|
Windows 下 Ctrl+C 通过 KeyboardInterrupt 捕获,关闭后用 os._exit 确保退出
|
|
33
33
|
(WS executor 线程可能无法干净终止)。
|
|
34
34
|
"""
|
|
35
|
+
# 启动前检查:若已有守护进程在运行(PID 文件指向存活进程),则拒绝启动
|
|
36
|
+
# 防止 maybe_spawn_channel_daemon 竞态条件导致两个守护进程同时运行
|
|
37
|
+
# (两个进程同时 spawn 时,PID 文件写入有竞态,可能都写入成功导致孤儿)
|
|
38
|
+
from illusion.config.paths import get_channels_data_dir
|
|
39
|
+
from illusion.channels.pid import PidFile, read_pid
|
|
40
|
+
|
|
41
|
+
data_dir = get_channels_data_dir()
|
|
42
|
+
pid_file = PidFile(data_dir / "daemon.pid")
|
|
43
|
+
if pid_file.is_running():
|
|
44
|
+
existing_pid = read_pid(pid_file.path) or 0
|
|
45
|
+
# 当前进程的 PID 与 PID 文件记录的不同 → 已有另一个守护进程在运行
|
|
46
|
+
if existing_pid and existing_pid != os.getpid():
|
|
47
|
+
print(
|
|
48
|
+
f"[channel] 守护进程已在运行 (PID={existing_pid}),拒绝重复启动。"
|
|
49
|
+
f" 若确信无进程在运行,请删除 {pid_file.path} 后重试。"
|
|
50
|
+
)
|
|
51
|
+
return
|
|
52
|
+
|
|
35
53
|
cfg = load_channels_config()
|
|
36
54
|
settings = _load_settings_safely()
|
|
37
55
|
|
|
@@ -101,6 +119,13 @@ def run_channel_serve() -> None:
|
|
|
101
119
|
root_logger.addHandler(stream_handler)
|
|
102
120
|
logger.info("渠道守护进程启动,日志文件: %s", log_path)
|
|
103
121
|
|
|
122
|
+
# 写入当前进程 PID 到 PID 文件(覆盖 maybe_spawn_channel_daemon 写入的 PID)
|
|
123
|
+
# 确保后续 maybe_spawn_channel_daemon 检查时能正确识别当前守护进程
|
|
124
|
+
try:
|
|
125
|
+
pid_file.acquire(os.getpid())
|
|
126
|
+
except Exception as exc: # noqa: BLE001
|
|
127
|
+
logger.warning("写入 daemon.pid 失败: %s", exc)
|
|
128
|
+
|
|
104
129
|
try:
|
|
105
130
|
asyncio.run(_serve_async(cfg, settings))
|
|
106
131
|
except KeyboardInterrupt:
|
|
@@ -109,6 +134,12 @@ def run_channel_serve() -> None:
|
|
|
109
134
|
print("\n收到中断信号,正在关闭...")
|
|
110
135
|
# 关闭资源后强制退出(WS executor 线程可能阻塞 os.kill 无法终止)
|
|
111
136
|
_force_shutdown()
|
|
137
|
+
finally:
|
|
138
|
+
# 退出时释放 PID 文件,避免 maybe_spawn_channel_daemon 误判为仍在运行
|
|
139
|
+
try:
|
|
140
|
+
pid_file.release()
|
|
141
|
+
except Exception: # noqa: BLE001
|
|
142
|
+
pass
|
|
112
143
|
|
|
113
144
|
|
|
114
145
|
def _load_settings_safely() -> Any:
|
|
@@ -938,7 +938,6 @@ def web_start(
|
|
|
938
938
|
typer.echo(_t("cwd_invalid", path=settings.working_directory), err=True)
|
|
939
939
|
|
|
940
940
|
# 渠道自动激活:有 enabled 渠道时 spawn 守护进程(与 illusion 主命令一致)
|
|
941
|
-
from illusion.channels import kill_channel_daemon
|
|
942
941
|
_daemon_proc = None
|
|
943
942
|
try:
|
|
944
943
|
from illusion.channels import maybe_spawn_channel_daemon
|
|
@@ -947,8 +946,42 @@ def web_start(
|
|
|
947
946
|
import logging
|
|
948
947
|
logging.getLogger(__name__).warning("渠道自动激活失败: %s", exc)
|
|
949
948
|
|
|
949
|
+
# PC 端渠道感知:与 illusion 主命令一致,注入 channel_hint + channel_tools
|
|
950
|
+
# 让 web 端 LLM 也能看到已启用渠道并用跨渠道工具发文件
|
|
951
|
+
pc_channel_hint: str | None = None
|
|
952
|
+
pc_channel_tools: list[Any] | None = None
|
|
953
|
+
try:
|
|
954
|
+
from illusion.channels.config import load_channels_config
|
|
955
|
+
from illusion.prompts.channel_hints import (
|
|
956
|
+
get_channel_hint,
|
|
957
|
+
list_active_sessions,
|
|
958
|
+
)
|
|
959
|
+
_cfg = load_channels_config()
|
|
960
|
+
if _cfg.has_enabled_channels():
|
|
961
|
+
other_names = _cfg.enabled_channel_names()
|
|
962
|
+
_active = {
|
|
963
|
+
name: list_active_sessions(name, _cfg, limit=5)
|
|
964
|
+
for name in other_names
|
|
965
|
+
}
|
|
966
|
+
pc_channel_hint = get_channel_hint(
|
|
967
|
+
current_channel=None,
|
|
968
|
+
channels_config=_cfg,
|
|
969
|
+
active_sessions=_active,
|
|
970
|
+
)
|
|
971
|
+
# 注入跨渠道工具
|
|
972
|
+
from illusion.channels.tools.cross_channel import (
|
|
973
|
+
ListChannelSessionsTool,
|
|
974
|
+
SendToChannelTool,
|
|
975
|
+
)
|
|
976
|
+
pc_channel_tools = [ListChannelSessionsTool(_cfg), SendToChannelTool(_cfg)]
|
|
977
|
+
except Exception as exc: # noqa: BLE001
|
|
978
|
+
import logging
|
|
979
|
+
logging.getLogger(__name__).warning("PC 渠道感知加载失败: %s", exc)
|
|
980
|
+
|
|
950
981
|
config = WebHostConfig(
|
|
951
982
|
model=model,
|
|
983
|
+
channel_hint=pc_channel_hint,
|
|
984
|
+
channel_tools=pc_channel_tools,
|
|
952
985
|
)
|
|
953
986
|
|
|
954
987
|
app = create_app(dev=dev, host_config=config)
|
|
@@ -959,15 +992,29 @@ def web_start(
|
|
|
959
992
|
import webbrowser
|
|
960
993
|
threading.Thread(target=webbrowser.open, args=(url,), daemon=True).start()
|
|
961
994
|
|
|
962
|
-
# ctrl+c /
|
|
995
|
+
# ctrl+c / 正常退出时询问是否终止渠道守护进程(与 illusion 主命令一致)
|
|
996
|
+
# ctrl+c 触发时 force=True 直接停止守护进程
|
|
997
|
+
# 正常退出时询问用户(y/回车默认杀灭)
|
|
998
|
+
_interrupted = False
|
|
963
999
|
try:
|
|
964
1000
|
uvicorn.run(app, host=host, port=port, log_level="warning")
|
|
1001
|
+
except KeyboardInterrupt:
|
|
1002
|
+
_interrupted = True
|
|
965
1003
|
finally:
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1004
|
+
try:
|
|
1005
|
+
from illusion.channels import is_channel_daemon_running, stop_channel_daemon_by_pid
|
|
1006
|
+
if is_channel_daemon_running():
|
|
1007
|
+
if _interrupted:
|
|
1008
|
+
# ctrl+c 触发:直接停止守护进程
|
|
1009
|
+
stop_channel_daemon_by_pid()
|
|
1010
|
+
else:
|
|
1011
|
+
# 正常退出:询问用户,y/回车默认杀灭
|
|
1012
|
+
from illusion.config.i18n import t
|
|
1013
|
+
answer = input(t("channel_daemon_exit_prompt") + " ").strip().lower()
|
|
1014
|
+
if answer in ("", "y", "yes"):
|
|
1015
|
+
stop_channel_daemon_by_pid()
|
|
1016
|
+
except Exception: # noqa: BLE001
|
|
1017
|
+
pass
|
|
971
1018
|
|
|
972
1019
|
|
|
973
1020
|
# ---- update 子命令 ----
|
|
@@ -1306,7 +1353,6 @@ def main(
|
|
|
1306
1353
|
)
|
|
1307
1354
|
|
|
1308
1355
|
# 渠道自动激活:有 enabled 渠道时 spawn 守护进程
|
|
1309
|
-
from illusion.channels import kill_channel_daemon
|
|
1310
1356
|
_daemon_proc = None
|
|
1311
1357
|
try:
|
|
1312
1358
|
from illusion.channels import maybe_spawn_channel_daemon
|
|
@@ -1315,10 +1361,29 @@ def main(
|
|
|
1315
1361
|
import logging
|
|
1316
1362
|
logging.getLogger(__name__).warning("渠道自动激活失败: %s", exc)
|
|
1317
1363
|
|
|
1318
|
-
def _kill_channel_daemon() -> None:
|
|
1319
|
-
"""
|
|
1364
|
+
def _kill_channel_daemon(*, force: bool = False) -> None:
|
|
1365
|
+
"""退出时询问是否终止渠道守护进程
|
|
1366
|
+
|
|
1367
|
+
illusion 和 illusion web 可能同时运行并共享同一个守护进程。
|
|
1368
|
+
退出时如果守护进程仍在运行,询问用户是否一同退出,避免
|
|
1369
|
+
一个进程退出导致另一个进程失去渠道服务。
|
|
1370
|
+
|
|
1371
|
+
Args:
|
|
1372
|
+
force: True 时直接停止守护进程(用于 ctrl+c 场景),False 时询问用户
|
|
1373
|
+
"""
|
|
1320
1374
|
try:
|
|
1321
|
-
|
|
1375
|
+
from illusion.channels import is_channel_daemon_running, stop_channel_daemon_by_pid
|
|
1376
|
+
if not is_channel_daemon_running():
|
|
1377
|
+
return
|
|
1378
|
+
if force:
|
|
1379
|
+
# ctrl+c 触发的退出:直接停止守护进程(用户已通过 ctrl+c 表达退出意图)
|
|
1380
|
+
stop_channel_daemon_by_pid()
|
|
1381
|
+
return
|
|
1382
|
+
# 正常退出时询问用户;y 或直接回车(空输入)默认杀灭
|
|
1383
|
+
from illusion.config.i18n import t
|
|
1384
|
+
answer = input(t("channel_daemon_exit_prompt") + " ").strip().lower()
|
|
1385
|
+
if answer in ("", "y", "yes"):
|
|
1386
|
+
stop_channel_daemon_by_pid()
|
|
1322
1387
|
except Exception: # noqa: BLE001
|
|
1323
1388
|
pass
|
|
1324
1389
|
|
|
@@ -1448,6 +1513,9 @@ def main(
|
|
|
1448
1513
|
return
|
|
1449
1514
|
|
|
1450
1515
|
# 启动交互式 REPL 会话
|
|
1516
|
+
# ctrl+c 触发 KeyboardInterrupt 时,force=True 直接停止守护进程
|
|
1517
|
+
# 正常退出时,询问用户是否一同退出渠道(y/回车默认杀灭)
|
|
1518
|
+
_interrupted = False
|
|
1451
1519
|
try:
|
|
1452
1520
|
asyncio.run(
|
|
1453
1521
|
run_repl(
|
|
@@ -1465,8 +1533,10 @@ def main(
|
|
|
1465
1533
|
channel_tools=pc_channel_tools,
|
|
1466
1534
|
)
|
|
1467
1535
|
)
|
|
1536
|
+
except KeyboardInterrupt:
|
|
1537
|
+
_interrupted = True
|
|
1468
1538
|
finally:
|
|
1469
|
-
_kill_channel_daemon()
|
|
1539
|
+
_kill_channel_daemon(force=_interrupted)
|
|
1470
1540
|
|
|
1471
1541
|
|
|
1472
1542
|
# ---- channel 子命令 ----
|
|
@@ -209,10 +209,12 @@ MESSAGES: dict[str, dict[str, str]] = {
|
|
|
209
209
|
"channel_disconnected": {"zh-CN": "未连接", "en-US": "disconnected"},
|
|
210
210
|
# --- 飞书侧(用户在飞书中看到)---
|
|
211
211
|
"feishu_thinking": {"zh-CN": "illusion code 正在思考中...", "en-US": "illusion code is thinking..."},
|
|
212
|
-
"feishu_cmd_help": {"zh-CN": "可用命令: /help /clear /new /delete /sessions /resume /detach /model", "en-US": "Commands: /help /clear /new /delete /sessions /resume /detach /model"},
|
|
212
|
+
"feishu_cmd_help": {"zh-CN": "可用命令: /help /clear /new /delete /stop /sessions /resume /detach /model", "en-US": "Commands: /help /clear /new /delete /stop /sessions /resume /detach /model"},
|
|
213
213
|
"feishu_cmd_cleared": {"zh-CN": "飞书会话已清空,开始新对话。", "en-US": "Feishu session cleared, starting fresh."},
|
|
214
214
|
# --- 通用渠道命令文案(不限渠道)---
|
|
215
215
|
"cmd_new": {"zh-CN": "已开启新的会话。", "en-US": "New session started."},
|
|
216
|
+
"cmd_stop_no_task": {"zh-CN": "当前没有正在执行的任务。", "en-US": "No running task to stop."},
|
|
217
|
+
"cmd_stop_done": {"zh-CN": "已中断当前任务。", "en-US": "Task interrupted."},
|
|
216
218
|
"feishu_cmd_sessions_title": {"zh-CN": "本地未完成会话:", "en-US": "Local unfinished sessions:"},
|
|
217
219
|
"feishu_cmd_no_sessions": {"zh-CN": "没有本地会话可恢复。", "en-US": "No local sessions to resume."},
|
|
218
220
|
"feishu_cmd_resumed": {"zh-CN": "已恢复本地会话({n} 条历史),继续吧。", "en-US": "Resumed local session ({n} messages), continue."},
|
|
@@ -242,6 +244,11 @@ MESSAGES: dict[str, dict[str, str]] = {
|
|
|
242
244
|
"zh-CN": "请先访问 https://q.qq.com 注册机器人应用,获取 App ID 和 Client Secret",
|
|
243
245
|
"en-US": "Please visit https://q.qq.com to register a bot app and obtain App ID and Client Secret",
|
|
244
246
|
},
|
|
247
|
+
# 渠道守护进程退出确认
|
|
248
|
+
"channel_daemon_exit_prompt": {
|
|
249
|
+
"zh-CN": "渠道守护进程仍在运行,是否一同退出?(y/N)",
|
|
250
|
+
"en-US": "Channel daemon is still running. Stop it too? (y/N)",
|
|
251
|
+
},
|
|
245
252
|
}
|
|
246
253
|
|
|
247
254
|
# --- 命令描述翻译 ---
|
|
@@ -106,6 +106,9 @@ class WebHostConfig:
|
|
|
106
106
|
restore_session_id: str | None = None
|
|
107
107
|
enforce_max_turns: bool = True
|
|
108
108
|
effort: str | None = None
|
|
109
|
+
# 渠道感知:与 illusion 主命令一致,注入渠道提示词和跨渠道工具
|
|
110
|
+
channel_hint: str | None = None
|
|
111
|
+
channel_tools: list[Any] | None = None
|
|
109
112
|
|
|
110
113
|
|
|
111
114
|
class WebBackendHost:
|
|
@@ -168,6 +171,8 @@ class WebBackendHost:
|
|
|
168
171
|
ask_user_prompt=self._ask_question, # type: ignore[arg-type]
|
|
169
172
|
plan_approval_prompt=self._ask_plan_approval,
|
|
170
173
|
effort=self._config.effort,
|
|
174
|
+
channel_hint=self._config.channel_hint,
|
|
175
|
+
channel_tools=self._config.channel_tools,
|
|
171
176
|
)
|
|
172
177
|
except Exception as exc:
|
|
173
178
|
log.exception("Failed to build runtime")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/CommandPicker.tsx
RENAMED
|
File without changes
|
|
File without changes
|
{illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ComposerController.tsx
RENAMED
|
File without changes
|
{illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/ConversationView.tsx
RENAMED
|
File without changes
|
|
File without changes
|
{illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/MarkdownContent.tsx
RENAMED
|
File without changes
|
{illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/MarkdownTable.tsx
RENAMED
|
File without changes
|
|
File without changes
|
{illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/MultilineTextInput.tsx
RENAMED
|
File without changes
|
{illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/PromptInput.tsx
RENAMED
|
File without changes
|
|
File without changes
|
{illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/QuestionPreviewBox.tsx
RENAMED
|
File without changes
|
{illusion_code-0.2.9 → illusion_code-0.2.10}/frontend/terminal/src/components/SelectModal.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|