qi-coding-agent 0.1.0__tar.gz → 0.1.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.
- qi_coding_agent-0.1.1/PKG-INFO +144 -0
- qi_coding_agent-0.1.1/README.md +114 -0
- qi_coding_agent-0.1.1/THIRD_PARTY_NOTICES.md +52 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/cli.md +4 -1
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/configuration.md +0 -1
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/containerization.md +1 -2
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/index.md +2 -14
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/models.md +3 -1
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/quickstart.md +16 -12
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/security.md +5 -6
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/session-format.md +1 -2
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/tui.md +0 -6
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-agents/pyproject.toml +1 -1
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-mcp/pyproject.toml +1 -1
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/pyproject.toml +1 -1
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/pyproject.toml +4 -1
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/__init__.py +1 -1
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/cli.py +18 -6
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/compaction.py +4 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/runtime.py +47 -9
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/theme.py +7 -1
- qi_coding_agent-0.1.1/src/qi_agent/themes/README.md +13 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/tui.py +12 -2
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_docs_injection.py +8 -2
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_interrupt.py +26 -3
- qi_coding_agent-0.1.1/tests/test_third_party_notices.py +58 -0
- qi_coding_agent-0.1.1/tests/test_tui_no_model.py +154 -0
- qi_coding_agent-0.1.0/PKG-INFO +0 -151
- qi_coding_agent-0.1.0/README.md +0 -121
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/.github/workflows/publish.yml +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/.gitignore +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/.pi-lens.json +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/LICENSE +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/PLAN.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/agent-config-design.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/bash-allowlist.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/development.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/dispatcher.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/extensions-design.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/internals.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/overview.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/pi-alignment.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/plugins.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/design/web.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/compaction.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/docs.json +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/environment-variables.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/extensions.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/how-qi-works.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/json.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/keybindings.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/packages.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/providers.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/sessions.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/settings.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/skills.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/slash-commands.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/themes.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/docs/usage.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/README.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/code-analyst/agent.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/code-analyst/assets/review-rules.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/code-analyst/mcp.json +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/code-analyst/skills/code-review-checklist/SKILL.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/code-reviewer/agent.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/data-analyst/agent.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/doc-writer/agent.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/doc-writer/assets/doc-style.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/general/agent.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/test-runner/agent.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/agents/writer/agent.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/extensions/README.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/extensions/hello/README.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/examples/extensions/hello/extension.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-agents/README.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-agents/qi_agents/__init__.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-agents/qi_agents/discovery.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-agents/qi_agents/subagent.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-mcp/README.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-mcp/qi_mcp/__init__.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-mcp/qi_mcp/client.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-mcp/qi_mcp/config.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-mcp/qi_mcp/direct.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-mcp/qi_mcp/proxy.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-mcp/qi_mcp/role.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-mcp/qi_mcp/servers.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/README.md +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/__init__.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/agui.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/app.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/browse.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/files.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/schemas.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/security.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/serve.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/state.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/static/assets/index-96aT_6NK.js +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/static/assets/index-DePFgopp.css +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/qi_web/static/index.html +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/index.html +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/package-lock.json +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/package.json +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/scripts/check-design.mjs +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/scripts/check-dsh-tokens.mjs +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/App.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/api/client.test.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/api/client.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/api/contract.test.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/api/types.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/commands.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/AgentMenu.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/CommandMenu.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/ConfirmDialog.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/DirPicker.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/Dock.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/FilePanel.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/ModelMenu.test.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/ModelMenu.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/ProjectMenu.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/Rail.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/RowMenu.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/Rows.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/Settings.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/SidebarSection.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/components/icons.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/main.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/markdown/cjk.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/markdown/markdown.test.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/markdown/parse.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/markdown/render.tsx +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/state/projects.test.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/state/projects.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/state/route.test.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/state/route.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/state/stats.test.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/state/stats.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/state/turn.test.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/state/turn.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/theme/app.css +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/theme/theme.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/theme/tokens.css +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/src/vite-env.d.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/tsconfig.json +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/vite.config.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/extensions/qi-web/ui/vitest.config.ts +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/pyrightconfig.json +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/scripts/check_versions.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/scripts/e2e_ui_model.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/scripts/prune_empty_sessions.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/abort.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/auth.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/config.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/export_html.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/extensions.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/llm.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/loader.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/model_catalog.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/models.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/packages.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/paths.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/pep723.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/presets.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/prompt.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/registry.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/runner.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/session.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/settings.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/share.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/system_prompt.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/themes/dark.json +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/themes/light.json +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/titling.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/tools/__init__.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/tools/shell.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/trust.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/src/qi_agent/workspaces.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/conftest.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_branch_summary_prompt.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_browse.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_cli_init.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_cli_install.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_cli_pi_alignment.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_cli_run.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_cli_tool_flags.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_compaction.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_compaction_events.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_config.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_config_resources.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_contract_p0.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_doctor_extensions.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_example_extension.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_export_html.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_alignment.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_bus.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_cli_commands.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_commands.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_deps.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_entry_points.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_events.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_exclusions.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_flags.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_interop.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_messages.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_model.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_resolvers.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_run_agent.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_runner_events.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_session.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_tools.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extension_ui.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_extensions.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_litellm_offline.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_missing_extension_hints.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_model_catalog.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_model_thinking_levels.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_package_resource_toggle.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_packages.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_pep723.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_presets.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_prune_empty_sessions.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_qi_agents_extension.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_qi_mcp_config.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_qi_mcp_direct.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_qi_mcp_http.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_qi_mcp_proxy.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_qi_mcp_role.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_qi_mcp_stdio.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_runner_core.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_session_model_entries.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_session_store.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_session_tree.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_settings_skills.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_share.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_shell.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_skill_commands.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_streaming.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_system_prompt.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_theme.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_thinking.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_thinking_budgets.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_titling.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_tool_execution_mode.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_trust_scope.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_tui_extension_render.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_tui_model_restore.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_tui_smoke.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_tui_style.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_web_api.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_web_extensions_api.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_web_files.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/tests/test_workspaces.py +0 -0
- {qi_coding_agent-0.1.0 → qi_coding_agent-0.1.1}/uv.lock +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: qi-coding-agent
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: 编码 agent 框架:单 agent core + 扩展(MCP / 多 agent / web)
|
|
5
|
+
Project-URL: Homepage, https://github.com/viewnah/qi
|
|
6
|
+
Project-URL: Repository, https://github.com/viewnah/qi
|
|
7
|
+
Project-URL: Issues, https://github.com/viewnah/qi/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/viewnah/qi/tree/dev/docs
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agent,cli,coding-agent,llm,mcp,tui
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Requires-Dist: litellm>=1.40
|
|
21
|
+
Requires-Dist: pydantic>=2.10
|
|
22
|
+
Requires-Dist: pyyaml>=6.0
|
|
23
|
+
Requires-Dist: rich>=13.0
|
|
24
|
+
Requires-Dist: textual>=0.80
|
|
25
|
+
Requires-Dist: typer>=0.12
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# qi
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/qi-coding-agent/)
|
|
34
|
+
[](https://pypi.org/project/qi-coding-agent/)
|
|
35
|
+
[](LICENSE)
|
|
36
|
+
|
|
37
|
+
用 Python 写的编码 agent 框架 —— **pi-coding-agent 的 Python 实现**:同一套形态与用法(单 agent core + 扩展宿主),换到 Python 生态。
|
|
38
|
+
|
|
39
|
+
* **[qi-coding-agent](https://pypi.org/project/qi-coding-agent/)**:交互式编码 agent CLI(`qi` 命令)
|
|
40
|
+
* **core 就是单 agent**:会话(JSONL + 分支树)· 工具循环 · 系统提示词 · CLI + TUI · 自动压缩 · 认证 · 扩展宿主
|
|
41
|
+
|
|
42
|
+
想了解 qi:
|
|
43
|
+
|
|
44
|
+
* 读[手册](docs/index.md),先看[qi 是怎么工作的](docs/how-qi-works.md)
|
|
45
|
+
* 也可以**直接问 qi 自己** —— 自带手册的索引会进提示词,它按需 `read` 那些文件来回答
|
|
46
|
+
|
|
47
|
+
## 安装
|
|
48
|
+
|
|
49
|
+
前置:**Python ≥ 3.12**。
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
uv tool install qi-coding-agent # 推荐:装成全局命令,独立环境
|
|
53
|
+
# 或 pip install qi-coding-agent # 装进当前 venv
|
|
54
|
+
|
|
55
|
+
qi --version
|
|
56
|
+
qi doctor # 冒烟:配置 / 凭证 / 扩展 / 包声明,一次全报
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 快速开始
|
|
60
|
+
|
|
61
|
+
第一次用,**在界面里两步**就能跑起来:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
qi # 裸 qi 就是界面(装完直接敲)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
进去之后:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
/login # 选 provider(预置都在列表里)→ 遮罩输入 API key → 写 ~/.qi/agent/auth.json
|
|
71
|
+
/model # 选模型(只列解析得出凭证的;刚才没有模型时 /login 会顺带选中第一个)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
然后直接说你要做什么。三种跑法:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
qi # 交互界面
|
|
78
|
+
qi "分析这个仓库" # 进界面,并把这句话作为首条消息发出
|
|
79
|
+
qi -p "分析这个仓库" # 无头一次:stdout 只有答案(进度走 stderr)
|
|
80
|
+
qi --mode json "…" # 事件流:一行一个 JSON,喂给上层程序
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
想**在命令行里把 provider 与模型配好**(脚本 / CI / 不想进界面):
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
qi init # 引导:选 provider → 加模型 → 设为默认
|
|
87
|
+
qi init --list-presets # 看内置的预置 provider(国产为主:deepseek / qwen / kimi / glm / minimax …)
|
|
88
|
+
qi init --preset deepseek # 一条命令物化预置并设为默认(只补缺、幂等)
|
|
89
|
+
qi doctor # 校验配置与凭证
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
全部斜杠命令见[斜杠命令](docs/slash-commands.md)。
|
|
93
|
+
|
|
94
|
+
**零配置也能跑**:基座提示词在代码里,不写任何配置就是一个能用的单 agent。
|
|
95
|
+
逐步说明见[快速开始](docs/quickstart.md)。
|
|
96
|
+
|
|
97
|
+
## 扩展
|
|
98
|
+
|
|
99
|
+
qi 的能力可以按需加装 —— 命令、快捷键、工具、事件钩子、终端 UI 组件都走同一套扩展机制。
|
|
100
|
+
**core 不内置、也不默认装**,裸 qi 就是一个能用的单 agent。
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
qi install <来源> [-l] # 装:调 pip(本地目录只登记)+ 把声明写进 settings.packages(带 -l 写项目)
|
|
104
|
+
qi list # 看装了哪些(含目录通道),并与声明双向比对
|
|
105
|
+
qi doctor # 「声明了没装」「装了没声明」都报出来,并给出可复制的装法
|
|
106
|
+
qi remove <来源> # 只移除声明(不卸包),并把 pip uninstall 命令打出来
|
|
107
|
+
qi -e <目录> # 本次运行临时加载一个扩展目录(TUI 与无头都生效,只本进程)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
手工放目录也行:用户级 `~/.qi/agent/extensions/<名>/extension.py`,项目级 `.qi/extensions/<名>/extension.py`
|
|
111
|
+
(项目级**未信任不加载**;入口文件名固定)。
|
|
112
|
+
|
|
113
|
+
三条要点:
|
|
114
|
+
|
|
115
|
+
* **装到哪**:进的是 **qi 所在的那个解释器环境**(不是当前项目的 venv)—— `uv tool install` 会重建环境,
|
|
116
|
+
所以**声明**要写在 `settings.packages` 里,重建后用 `qi doctor` 发现并补回。
|
|
117
|
+
* **声明与实装是两件事**:`settings.packages` 说"这个环境该装什么",`settings.extensions` 说"到哪里找扩展目录";
|
|
118
|
+
`qi list` / `qi doctor` 永远做**两个方向**的比对。
|
|
119
|
+
* **扩展就是任意代码**:只装可信来源。写一个扩展见[写扩展](docs/extensions.md)与[终端 UI 组件](docs/tui.md);
|
|
120
|
+
装法与声明层的完整写法见[扩展的安装与声明](docs/packages.md)。
|
|
121
|
+
|
|
122
|
+
## 权限与沙箱
|
|
123
|
+
|
|
124
|
+
qi **不内置**限制文件系统 / 进程 / 网络 / 凭证访问的权限系统 —— 它默认以启动它的那个用户与进程的权限运行,
|
|
125
|
+
`bash` 工具不做命令级过滤。需要更强的边界就**把它放进容器或沙箱**:见
|
|
126
|
+
[隔离运行](docs/containerization.md),以及完整的安全模型与已知缺口 [安全地运行](docs/security.md)。
|
|
127
|
+
|
|
128
|
+
## 文档
|
|
129
|
+
|
|
130
|
+
| 去处 | 内容 |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| [docs/index.md](docs/index.md) | 手册总入口:开始 / 指南(运行 · 定制 · 构建)/ 参考 |
|
|
133
|
+
| [docs/how-qi-works.md](docs/how-qi-works.md) | agent loop、上下文、会话、工具、信任 —— 先读这一页 |
|
|
134
|
+
| [docs/cli.md](docs/cli.md) | 命令行:全部选项与行为(输出 / 模型 / 会话 / 工具 / 资源 / 凭证 …) |
|
|
135
|
+
| [docs/slash-commands.md](docs/slash-commands.md) | TUI 里的斜杠命令(模型与设置 / 会话与上下文 / 导出 / 运行时) |
|
|
136
|
+
| [docs/extensions.md](docs/extensions.md) | 写扩展:工具、事件、命令、终端 UI 组件 |
|
|
137
|
+
|
|
138
|
+
手册随 wheel 发布,索引会注入提示词;**正文不塞进上下文** —— 模型按需用 `read` 打开。
|
|
139
|
+
|
|
140
|
+
## 许可证
|
|
141
|
+
|
|
142
|
+
MIT(见 [LICENSE](LICENSE))。qi 里有两处素材移植自上游 pi(两份内置调色板与压缩/分支摘要的提示词),
|
|
143
|
+
它们的 MIT 声明与许可全文见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md);
|
|
144
|
+
**qi 与 pi 的维护者没有隶属关系**,也不是官方移植。
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# qi
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/qi-coding-agent/)
|
|
4
|
+
[](https://pypi.org/project/qi-coding-agent/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
用 Python 写的编码 agent 框架 —— **pi-coding-agent 的 Python 实现**:同一套形态与用法(单 agent core + 扩展宿主),换到 Python 生态。
|
|
8
|
+
|
|
9
|
+
* **[qi-coding-agent](https://pypi.org/project/qi-coding-agent/)**:交互式编码 agent CLI(`qi` 命令)
|
|
10
|
+
* **core 就是单 agent**:会话(JSONL + 分支树)· 工具循环 · 系统提示词 · CLI + TUI · 自动压缩 · 认证 · 扩展宿主
|
|
11
|
+
|
|
12
|
+
想了解 qi:
|
|
13
|
+
|
|
14
|
+
* 读[手册](docs/index.md),先看[qi 是怎么工作的](docs/how-qi-works.md)
|
|
15
|
+
* 也可以**直接问 qi 自己** —— 自带手册的索引会进提示词,它按需 `read` 那些文件来回答
|
|
16
|
+
|
|
17
|
+
## 安装
|
|
18
|
+
|
|
19
|
+
前置:**Python ≥ 3.12**。
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv tool install qi-coding-agent # 推荐:装成全局命令,独立环境
|
|
23
|
+
# 或 pip install qi-coding-agent # 装进当前 venv
|
|
24
|
+
|
|
25
|
+
qi --version
|
|
26
|
+
qi doctor # 冒烟:配置 / 凭证 / 扩展 / 包声明,一次全报
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 快速开始
|
|
30
|
+
|
|
31
|
+
第一次用,**在界面里两步**就能跑起来:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
qi # 裸 qi 就是界面(装完直接敲)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
进去之后:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
/login # 选 provider(预置都在列表里)→ 遮罩输入 API key → 写 ~/.qi/agent/auth.json
|
|
41
|
+
/model # 选模型(只列解析得出凭证的;刚才没有模型时 /login 会顺带选中第一个)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
然后直接说你要做什么。三种跑法:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
qi # 交互界面
|
|
48
|
+
qi "分析这个仓库" # 进界面,并把这句话作为首条消息发出
|
|
49
|
+
qi -p "分析这个仓库" # 无头一次:stdout 只有答案(进度走 stderr)
|
|
50
|
+
qi --mode json "…" # 事件流:一行一个 JSON,喂给上层程序
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
想**在命令行里把 provider 与模型配好**(脚本 / CI / 不想进界面):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
qi init # 引导:选 provider → 加模型 → 设为默认
|
|
57
|
+
qi init --list-presets # 看内置的预置 provider(国产为主:deepseek / qwen / kimi / glm / minimax …)
|
|
58
|
+
qi init --preset deepseek # 一条命令物化预置并设为默认(只补缺、幂等)
|
|
59
|
+
qi doctor # 校验配置与凭证
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
全部斜杠命令见[斜杠命令](docs/slash-commands.md)。
|
|
63
|
+
|
|
64
|
+
**零配置也能跑**:基座提示词在代码里,不写任何配置就是一个能用的单 agent。
|
|
65
|
+
逐步说明见[快速开始](docs/quickstart.md)。
|
|
66
|
+
|
|
67
|
+
## 扩展
|
|
68
|
+
|
|
69
|
+
qi 的能力可以按需加装 —— 命令、快捷键、工具、事件钩子、终端 UI 组件都走同一套扩展机制。
|
|
70
|
+
**core 不内置、也不默认装**,裸 qi 就是一个能用的单 agent。
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
qi install <来源> [-l] # 装:调 pip(本地目录只登记)+ 把声明写进 settings.packages(带 -l 写项目)
|
|
74
|
+
qi list # 看装了哪些(含目录通道),并与声明双向比对
|
|
75
|
+
qi doctor # 「声明了没装」「装了没声明」都报出来,并给出可复制的装法
|
|
76
|
+
qi remove <来源> # 只移除声明(不卸包),并把 pip uninstall 命令打出来
|
|
77
|
+
qi -e <目录> # 本次运行临时加载一个扩展目录(TUI 与无头都生效,只本进程)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
手工放目录也行:用户级 `~/.qi/agent/extensions/<名>/extension.py`,项目级 `.qi/extensions/<名>/extension.py`
|
|
81
|
+
(项目级**未信任不加载**;入口文件名固定)。
|
|
82
|
+
|
|
83
|
+
三条要点:
|
|
84
|
+
|
|
85
|
+
* **装到哪**:进的是 **qi 所在的那个解释器环境**(不是当前项目的 venv)—— `uv tool install` 会重建环境,
|
|
86
|
+
所以**声明**要写在 `settings.packages` 里,重建后用 `qi doctor` 发现并补回。
|
|
87
|
+
* **声明与实装是两件事**:`settings.packages` 说"这个环境该装什么",`settings.extensions` 说"到哪里找扩展目录";
|
|
88
|
+
`qi list` / `qi doctor` 永远做**两个方向**的比对。
|
|
89
|
+
* **扩展就是任意代码**:只装可信来源。写一个扩展见[写扩展](docs/extensions.md)与[终端 UI 组件](docs/tui.md);
|
|
90
|
+
装法与声明层的完整写法见[扩展的安装与声明](docs/packages.md)。
|
|
91
|
+
|
|
92
|
+
## 权限与沙箱
|
|
93
|
+
|
|
94
|
+
qi **不内置**限制文件系统 / 进程 / 网络 / 凭证访问的权限系统 —— 它默认以启动它的那个用户与进程的权限运行,
|
|
95
|
+
`bash` 工具不做命令级过滤。需要更强的边界就**把它放进容器或沙箱**:见
|
|
96
|
+
[隔离运行](docs/containerization.md),以及完整的安全模型与已知缺口 [安全地运行](docs/security.md)。
|
|
97
|
+
|
|
98
|
+
## 文档
|
|
99
|
+
|
|
100
|
+
| 去处 | 内容 |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| [docs/index.md](docs/index.md) | 手册总入口:开始 / 指南(运行 · 定制 · 构建)/ 参考 |
|
|
103
|
+
| [docs/how-qi-works.md](docs/how-qi-works.md) | agent loop、上下文、会话、工具、信任 —— 先读这一页 |
|
|
104
|
+
| [docs/cli.md](docs/cli.md) | 命令行:全部选项与行为(输出 / 模型 / 会话 / 工具 / 资源 / 凭证 …) |
|
|
105
|
+
| [docs/slash-commands.md](docs/slash-commands.md) | TUI 里的斜杠命令(模型与设置 / 会话与上下文 / 导出 / 运行时) |
|
|
106
|
+
| [docs/extensions.md](docs/extensions.md) | 写扩展:工具、事件、命令、终端 UI 组件 |
|
|
107
|
+
|
|
108
|
+
手册随 wheel 发布,索引会注入提示词;**正文不塞进上下文** —— 模型按需用 `read` 打开。
|
|
109
|
+
|
|
110
|
+
## 许可证
|
|
111
|
+
|
|
112
|
+
MIT(见 [LICENSE](LICENSE))。qi 里有两处素材移植自上游 pi(两份内置调色板与压缩/分支摘要的提示词),
|
|
113
|
+
它们的 MIT 声明与许可全文见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md);
|
|
114
|
+
**qi 与 pi 的维护者没有隶属关系**,也不是官方移植。
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# 第三方声明(Third-Party Notices)
|
|
2
|
+
|
|
3
|
+
qi 是独立实现,但有**两处素材移植自上游项目 pi**。它们同样在 MIT 许可下分发,因此随附下面的
|
|
4
|
+
版权声明与许可全文 —— 这是 MIT 的明确要求(“the above copyright notice and this permission
|
|
5
|
+
notice shall be included in all copies or substantial portions of the Software”)。
|
|
6
|
+
|
|
7
|
+
## pi(pi-coding-agent)
|
|
8
|
+
|
|
9
|
+
- 项目:<https://github.com/earendil-works/pi>(`packages/coding-agent`;本仓记录在案的参照版本:pi v0.85.1)
|
|
10
|
+
- 许可:**MIT License,Copyright (c) 2025 Mario Zechner**
|
|
11
|
+
- 移植清单:
|
|
12
|
+
|
|
13
|
+
| qi 里的位置 | 情况 |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `src/qi_agent/themes/dark.json`、`src/qi_agent/themes/light.json` | 两份内置调色板,取自上游 `theme/dark.json` / `theme/light.json`;键名与语义一致,qi 侧只调整了个别颜色值 |
|
|
16
|
+
| `src/qi_agent/compaction.py` 的 `SUMMARIZATION_SYSTEM_PROMPT` / `SUMMARIZATION_PROMPT` / `UPDATE_SUMMARIZATION_PROMPT` / `TURN_PREFIX_SUMMARIZATION_PROMPT` | 上下文压缩、分支摘要与 split-turn 的**提示词文本**,逐字移植 |
|
|
17
|
+
| 其余部分 | Python 代码、CLI / TUI、扩展宿主、打包与手册都是本仓自己写的;`docs/` 与 `design/pi-alignment.md` 里的上游对照是本仓重写的说明文字,只含少量短引用 |
|
|
18
|
+
|
|
19
|
+
> qi 与 pi 的维护者**没有隶属关系**,也不是官方移植。README 里"pi-coding-agent 的 Python 实现"
|
|
20
|
+
> 只是说明它对齐上游的形态与用法。
|
|
21
|
+
|
|
22
|
+
## pi 的 MIT 许可全文
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
MIT License
|
|
26
|
+
|
|
27
|
+
Copyright (c) 2025 Mario Zechner
|
|
28
|
+
|
|
29
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
30
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
31
|
+
in the Software without restriction, including without limitation the rights
|
|
32
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
33
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
34
|
+
furnished to do so, subject to the following conditions:
|
|
35
|
+
|
|
36
|
+
The above copyright notice and this permission notice shall be included in all
|
|
37
|
+
copies or substantial portions of the Software.
|
|
38
|
+
|
|
39
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
40
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
41
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
42
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
43
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
44
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
45
|
+
SOFTWARE.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
qi 自身:MIT License, **Copyright (c) 2026 viewnah**(见仓库根目录的 `LICENSE`)。
|
|
51
|
+
运行时依赖(typer / rich / textual / pydantic / litellm / PyYAML 等)各有自己的许可,
|
|
52
|
+
由 pip 在安装时随各自的 distribution 一并提供。
|
|
@@ -38,7 +38,7 @@ qi --export out.html # 导出会话后退出
|
|
|
38
38
|
| `-p`, `--print` | 跑完退出,**只把最终答案写 stdout** |
|
|
39
39
|
| `--mode text` | 文本输出;**stdin/stdout 都是终端时仍进界面**(要一次执行就配 `-p`) |
|
|
40
40
|
| `--mode json` | 输出事件流(一行一个 JSON,**隐含无头**)→ [json.md](json.md) |
|
|
41
|
-
| `--mode rpc` | **未实现**:传了会明确报错
|
|
41
|
+
| `--mode rpc` | **未实现**:传了会明确报错 |
|
|
42
42
|
| `--export <file>` | 导出会话:`.html` → 自包含 HTML,其余 → 原始 JSONL |
|
|
43
43
|
|
|
44
44
|
**选项写在消息之前**(`qi -nt "问题"`,不是 `qi "问题" -nt`):顶层选项在遇到消息后不再解析 —— 写反了会报错并提示怎么改。
|
|
@@ -56,6 +56,9 @@ qi --export out.html # 导出会话后退出
|
|
|
56
56
|
中断退出码 `128+n`:`SIGTERM` / `SIGHUP` → 回收在跑的子进程组 + `exit(143/129)`;`SIGINT` → asyncio 取消 →
|
|
57
57
|
`run_shell` 的 finally 回收 + `exit(130)`,不打 traceback。两条路径的半截回答都会落盘。
|
|
58
58
|
|
|
59
|
+
> Windows 没有 `SIGHUP`(Python 的 `signal` 模块里不存在这个属性),所以那里只装 `SIGTERM`;
|
|
60
|
+
> 其余行为一致。探测发生在**导入期之前**(代码里先 `getattr` 再登记),不会让 CLI 崩在启动。
|
|
61
|
+
|
|
59
62
|
## 模型
|
|
60
63
|
|
|
61
64
|
```sh
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# qi 文档
|
|
2
2
|
|
|
3
|
-
qi 是**可扩展的编码 agent 框架**:裸 core 就是单 agent
|
|
3
|
+
qi 是**可扩展的编码 agent 框架**:裸 core 就是单 agent,跑在终端里;其余能力按需装扩展。
|
|
4
4
|
给它一个目标和一个工作目录,它会读文件、跑命令、改内容,并一步步把任务做完。
|
|
5
5
|
|
|
6
6
|
机器可读的导航清单是同目录的 [`docs.json`](docs.json)(与下面这些分类同源)。
|
|
@@ -34,7 +34,7 @@ qi 能加载按需说明、加可执行集成、换配色,并把这些打包分
|
|
|
34
34
|
- [命令行](cli.md):`qi -p "…"` 无头一次拿结果,进度走 stderr。
|
|
35
35
|
- [JSON 事件流](json.md):把一轮里的每个事件按行喂给上层程序。
|
|
36
36
|
|
|
37
|
-
qi 没有 RPC 模式与 SDK —— `--mode rpc`
|
|
37
|
+
qi 没有 RPC 模式与 SDK —— `--mode rpc` 会明确报未实现。
|
|
38
38
|
|
|
39
39
|
## 参考
|
|
40
40
|
|
|
@@ -47,15 +47,3 @@ qi 没有 RPC 模式与 SDK —— `--mode rpc` 会明确报未实现(见 [PLAN.
|
|
|
47
47
|
qi 的工具与扩展以 **qi 进程本身的权限**运行。信任门控只决定"要不要加载项目里的资源",**不是沙箱**。
|
|
48
48
|
动不认识的仓库、扩展或无人值守的自动化之前,先读 [安全地运行](security.md);要真隔离看
|
|
49
49
|
[隔离运行](containerization.md)。
|
|
50
|
-
|
|
51
|
-
## 读完还想改 qi 本身
|
|
52
|
-
|
|
53
|
-
| 去处 | 内容 |
|
|
54
|
-
| --- | --- |
|
|
55
|
-
| [development.md](../design/development.md) | 拉起来、测试、静态检查、仓库布局 |
|
|
56
|
-
| [PLAN.md](../design/PLAN.md) | 开发计划、阶段表、未决清单 |
|
|
57
|
-
| [overview.md](../design/overview.md) | 总设计:架构总览、既定决策索引、技术选型、目录布局 |
|
|
58
|
-
| [internals.md](../design/internals.md) | 实现细节与决策记录(手册之外的部分) |
|
|
59
|
-
| [extensions-design.md](../design/extensions-design.md) | 扩展化的阶段拆解、未定清单、决策编号表(E1–E28) |
|
|
60
|
-
| [pi-alignment.md](../design/pi-alignment.md) | 与上游 pi 的逐节对照 |
|
|
61
|
-
| [bash-allowlist.md](../design/bash-allowlist.md) | bash 策略的变更记录(为什么删掉首词白名单) |
|
|
@@ -26,7 +26,9 @@ qi 通过 litellm 调各家模型。provider 与模型定义都在 `models.json`
|
|
|
26
26
|
|
|
27
27
|
- **唯一来源是 `settings.json`**:`models.json` 里的 `defaultProvider` / `defaultModel`
|
|
28
28
|
**完全不参与**(不是优先级更低),写了会被忽略并在 `qi doctor` 里报出来。
|
|
29
|
-
-
|
|
29
|
+
- 缺任一项时:**交互界面(TUI)照常启动**,顶部提示用 `/login` 登录 provider(或用 `qi init` 引导),
|
|
30
|
+
真正提交消息才报错;无头路径(`-p` / `--mode json`)直接报错退出,并给出可照抄的迁移命令
|
|
31
|
+
—— 与 pi 的 interactive / 非 interactive 同一取舍。
|
|
30
32
|
- 查看:`qi --list-models [搜索词]`(缺密钥的也列,这是诊断面;解析不出凭证的 provider 不列)。
|
|
31
33
|
|
|
32
34
|
## 接本地模型
|
|
@@ -2,29 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
从零到第一次对话:装 → 配模型 → 跑。
|
|
4
4
|
|
|
5
|
-
## 1.
|
|
5
|
+
## 1. 安装
|
|
6
6
|
|
|
7
7
|
qi 需要 **Python ≥ 3.12**。
|
|
8
8
|
|
|
9
|
-
**发行名是 `qi-coding-agent
|
|
10
|
-
`qi_agent`、命令仍是 `qi
|
|
11
|
-
`pip install qi-coding-agent` 现在就能装到东西。
|
|
9
|
+
**发行名是 [`qi-coding-agent`](https://pypi.org/project/qi-coding-agent/)** —— PyPI 上的
|
|
10
|
+
`qi-agent` 属于**别的项目**,别装错;import 包名仍是 `qi_agent`、命令仍是 `qi`。
|
|
12
11
|
|
|
13
12
|
```bash
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
uv
|
|
17
|
-
# python -m venv .venv && .venv/bin/pip install -e .
|
|
13
|
+
uv tool install qi-coding-agent # 推荐:装上 `qi` 命令,独立环境
|
|
14
|
+
# 或:pip install qi-coding-agent # 装进当前 venv
|
|
15
|
+
# 或:uv add --dev qi-coding-agent # 只给某个项目用
|
|
18
16
|
```
|
|
19
17
|
|
|
20
|
-
装完 `qi` 命令可用(`[project.scripts]` 里的入口):
|
|
21
|
-
|
|
22
18
|
```bash
|
|
23
|
-
|
|
19
|
+
qi --version # → qi 0.1.1
|
|
24
20
|
```
|
|
25
21
|
|
|
26
22
|
首次运行会创建 `~/.qi/agent/`(用户级状态都挂在这里:配置、会话、技能、扩展)。
|
|
27
23
|
|
|
24
|
+
**要改 qi 本身 / 跑测试**才需要源码:克隆仓库 → `uv sync` → `uv run qi …`(editable,改完立即生效)。
|
|
25
|
+
|
|
26
|
+
扩展是**独立包**(core 不内置、不默认装),装法与声明层见 [packages.md](packages.md)。
|
|
27
|
+
|
|
28
28
|
## 2. 配一个模型
|
|
29
29
|
|
|
30
30
|
qi 不内置任何 provider 就必须先配一个能用的模型。交互式引导:
|
|
@@ -33,6 +33,10 @@ qi 不内置任何 provider 就必须先配一个能用的模型。交互式引
|
|
|
33
33
|
qi init
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
还没配就想先看看界面也没关系:直接 `qi` 会照常进 TUI,并提示用 `/login` 登录一个
|
|
37
|
+
provider(或退出后在终端跑 `qi init`)。`/login` 只解决凭证;provider/模型清单不在
|
|
38
|
+
`models.json` 里时仍要 `qi init` 补上。
|
|
39
|
+
|
|
36
40
|
它会走三步(样式复刻 QwenPaw 的 `init`):**选 provider**(已有 / 新建 → Base URL → API 类型 → API Key)
|
|
37
41
|
→ **Add Models**(`Add a model?` 循环,含 reasoning / contextWindow / maxTokens)
|
|
38
42
|
→ **选一个默认模型**。产物是三个文件:`models.json`(provider 与模型清单)、
|
|
@@ -81,7 +85,7 @@ qi --mode json "分析这个仓库" # 事件流(一行一个 JSON 对象),给管
|
|
|
81
85
|
| 想做 | 去哪 |
|
|
82
86
|
| --- | --- |
|
|
83
87
|
| 下次接着这条会话 | `qi -c`(最近一条)或 `qi --session <id>` —— [sessions.md](sessions.md) |
|
|
84
|
-
| 换模型 / 换思考级别 | TUI 里换,或 `--thinking <级别>` —— [
|
|
88
|
+
| 换模型 / 换思考级别 | TUI 里换,或 `--thinking <级别>` —— [models.md](models.md) · [usage.md](usage.md) |
|
|
85
89
|
| 加自己的技能 | 写 `SKILL.md` 放进 `~/.qi/agent/skills/` —— [skills.md](skills.md) |
|
|
86
90
|
| 改系统提示词 | 写 `.qi/SYSTEM.md`(**整体替换**默认基座,注意副作用) —— [configuration.md](configuration.md) |
|
|
87
91
|
| 写扩展 | [extensions.md](extensions.md) |
|
|
@@ -40,8 +40,8 @@ qi 能执行任意命令、读写任意文件,而**装进来的扩展就是任
|
|
|
40
40
|
|
|
41
41
|
## bash 的边界
|
|
42
42
|
|
|
43
|
-
**qi 没有命令级过滤**:不筛子命令、不拦重定向、不做只读白名单 —— `bash`
|
|
44
|
-
|
|
43
|
+
**qi 没有命令级过滤**:不筛子命令、不拦重定向、不做只读白名单 —— `bash` 能跑任何东西。这是**刻意的**:
|
|
44
|
+
白名单挡不住 `&&` / `;` / `>` / 裸解释器这几种写法,所以它只会给一个“看起来有闸门”的错觉。
|
|
45
45
|
|
|
46
46
|
限制手段只有两档:
|
|
47
47
|
|
|
@@ -54,8 +54,7 @@ qi 能执行任意命令、读写任意文件,而**装进来的扩展就是任
|
|
|
54
54
|
- 文件工具的路径限制在**会话工作目录**内(`read` / `ls` / `find` / `grep` / `write` / `edit`),**bash 不受限**。
|
|
55
55
|
- `bash` / `powershell` 的子进程 stdin 是 `DEVNULL`(读不到 TUI 的按键);超时按**进程组**回收。
|
|
56
56
|
- TUI 里 `!` 手动命令不经任何过滤 —— 那是你亲手敲的,不算模型越权。
|
|
57
|
-
- **没有工具级审批弹窗**(那类 workflow 属于扩展或外部工具)。破坏性操作的交互前钩子(HITL)
|
|
58
|
-
见 [PLAN.md](../design/PLAN.md) 的 v2 清单。
|
|
57
|
+
- **没有工具级审批弹窗**(那类 workflow 属于扩展或外部工具)。破坏性操作的交互前钩子(HITL)**未做**。
|
|
59
58
|
|
|
60
59
|
## 配置文件里的命令
|
|
61
60
|
|
|
@@ -65,5 +64,5 @@ qi 能执行任意命令、读写任意文件,而**装进来的扩展就是任
|
|
|
65
64
|
|
|
66
65
|
## 报漏洞 / 上报问题
|
|
67
66
|
|
|
68
|
-
qi
|
|
69
|
-
[
|
|
67
|
+
qi 目前没有专门的安全上报渠道。**不做进程内沙箱是刻意的取舍**:半步隔离最容易被误当成安全边界 ——
|
|
68
|
+
要么按[隔离运行](containerization.md)那条路真隔离,要么就按“它有你进程的全部权限”来使用。
|
|
@@ -234,8 +234,7 @@ web 端同理:每轮开跑前 `WebState.bind()`(`bind_session` + `start_session`
|
|
|
234
234
|
| **内存** | True | — | `--no-session`(`ephemeral()`) | 永不写盘(append/save/set_title 全跳过) |
|
|
235
235
|
|
|
236
236
|
**为什么要"预留"而不是"启动就建文件"**:本机真实事故 —— `~/.qi/agent/sessions/` 攒了
|
|
237
|
-
3000+ 个只有一行的空会话,全部来自"进来看一眼就走"
|
|
238
|
-
[design/web.md](../design/web.md) §18.28 的"懒创建")。
|
|
237
|
+
3000+ 个只有一行的空会话,全部来自"进来看一眼就走"。web 端也有同一个根因(懒创建)。
|
|
239
238
|
|
|
240
239
|
**为什么留住会话对象、只懒文件**:构造时就 `newSession()`,
|
|
241
240
|
于是"当前会话"这个不变量始终成立 —— 历史、用量、扩展的 `ctx.session_manager`、`/session`
|
|
@@ -101,9 +101,3 @@ def register(api):
|
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
配色请走主题的语义键(别写死 `#rrggbb`),否则换主题时你的组件不会跟着变 —— 见 [themes.md](themes.md)。
|
|
104
|
-
|
|
105
|
-
## 与其它页面的关系
|
|
106
|
-
|
|
107
|
-
- 扩展整体的写法(工具、事件、命令、旗标、依赖)见 [extensions.md](extensions.md)。
|
|
108
|
-
- 键位与编辑器行为见 [keybindings.md](keybindings.md)。
|
|
109
|
-
- 实现细节(Textual 的 priority / 焦点坑)见 [design/internals.md](../design/internals.md)。
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "qi-coding-agent"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.1"
|
|
8
8
|
description = "编码 agent 框架:单 agent core + 扩展(MCP / 多 agent / web)"
|
|
9
9
|
keywords = ["agent", "coding-agent", "cli", "tui", "llm", "mcp"]
|
|
10
10
|
readme = "README.md"
|
|
@@ -49,6 +49,9 @@ packages = ["src/qi_agent"]
|
|
|
49
49
|
# 手册跟包一起走:提示词里要报出**实际**路径(`paths.docs_dir()`),模型才能自己读。
|
|
50
50
|
# 只打 `docs/`;`design/` 是写给改动者的,不进 wheel、不注入提示词。
|
|
51
51
|
"docs" = "qi_agent/docs"
|
|
52
|
+
# 移植自 pi 的素材(themes / 压缩提示词)要随包带上它们的 MIT 声明 —— 这是 MIT 的要求,
|
|
53
|
+
# 只放在仓库根目录对**装包的用户**不算"随附"。
|
|
54
|
+
"THIRD_PARTY_NOTICES.md" = "qi_agent/THIRD_PARTY_NOTICES.md"
|
|
52
55
|
|
|
53
56
|
[tool.pytest.ini_options]
|
|
54
57
|
markers = [
|
|
@@ -523,8 +523,14 @@ def _run_headless(coro) -> None:
|
|
|
523
523
|
#
|
|
524
524
|
# SIGINT 不在这里:Python 默认转 KeyboardInterrupt → asyncio 取消主任务 →
|
|
525
525
|
# `run_shell` 的 finally 回收子进程组(见 tools/shell.py)。
|
|
526
|
-
|
|
527
|
-
|
|
526
|
+
#
|
|
527
|
+
# Windows 的 `signal` 模块**没有 SIGHUP**(只有 SIGTERM / SIGINT / SIGBREAK),而这里在
|
|
528
|
+
# **import 时**就要求值 —— 直接写 `signal.SIGHUP` 会让整个 CLI 在 Windows 上崩在导入期。
|
|
529
|
+
# 所以先探测再登记(而不是写 `hasattr` 分支:注册点也要用同一个名字)。
|
|
530
|
+
_SIGHUP: int | None = getattr(signal, "SIGHUP", None)
|
|
531
|
+
_EXIT_CODE_BY_SIGNAL: dict[int, int] = {signal.SIGTERM: 143}
|
|
532
|
+
if _SIGHUP is not None: # 非 Windows 才有
|
|
533
|
+
_EXIT_CODE_BY_SIGNAL[_SIGHUP] = 129
|
|
528
534
|
|
|
529
535
|
|
|
530
536
|
def _exit_code_for(signum: int) -> int:
|
|
@@ -536,6 +542,15 @@ def _exit_code_for(signum: int) -> int:
|
|
|
536
542
|
return _EXIT_CODE_BY_SIGNAL.get(signum, 128 + signum)
|
|
537
543
|
|
|
538
544
|
|
|
545
|
+
def _exit_signal_numbers() -> list[int]:
|
|
546
|
+
"""要装处理器的信号:**SIGTERM + (非 Windows 的)SIGHUP**。
|
|
547
|
+
|
|
548
|
+
抽成函数是因为 Windows 上少一个 —— `_install_exit_signal_handlers` 和测试都要
|
|
549
|
+
按同一份口径列出它们(见 tests/test_interrupt.py)。
|
|
550
|
+
"""
|
|
551
|
+
return [signal.SIGTERM] if _SIGHUP is None else [signal.SIGTERM, _SIGHUP]
|
|
552
|
+
|
|
553
|
+
|
|
539
554
|
def _install_exit_signal_handlers() -> Callable[[], None]:
|
|
540
555
|
"""装 SIGTERM/SIGHUP 处理器:先回收在跑的子进程组,再按信号码退出。
|
|
541
556
|
|
|
@@ -543,16 +558,13 @@ def _install_exit_signal_handlers() -> Callable[[], None]:
|
|
|
543
558
|
"""
|
|
544
559
|
from .tools.shell import kill_live_children
|
|
545
560
|
|
|
546
|
-
signals = [signal.SIGTERM]
|
|
547
|
-
if hasattr(signal, "SIGHUP"): # Windows 没有 SIGHUP
|
|
548
|
-
signals.append(signal.SIGHUP)
|
|
549
561
|
previous: dict[int, Any] = {}
|
|
550
562
|
|
|
551
563
|
def handler(signum: int, _frame: object) -> None:
|
|
552
564
|
kill_live_children() # 同步:信号处理器里不能 await
|
|
553
565
|
raise SystemExit(_exit_code_for(signum))
|
|
554
566
|
|
|
555
|
-
for sig in
|
|
567
|
+
for sig in _exit_signal_numbers():
|
|
556
568
|
try:
|
|
557
569
|
previous[sig] = signal.signal(sig, handler)
|
|
558
570
|
except (ValueError, OSError): # 非主线程/平台不支持 → 跳过于净
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
qi 的差异:`custom`(助手叙述)在 qi 里**不进上下文**(见 runtime._history),所以压缩也当它
|
|
16
16
|
不可见 —— 与上下文语义保持一致,不额外发明规则。
|
|
17
|
+
|
|
18
|
+
> **许可**:下面的四个提示词文本(`SUMMARIZATION_SYSTEM_PROMPT` / `SUMMARIZATION_PROMPT` /
|
|
19
|
+
> `UPDATE_SUMMARIZATION_PROMPT` / `TURN_PREFIX_SUMMARIZATION_PROMPT`)**逐字移植自 pi**
|
|
20
|
+
> (MIT,Copyright (c) 2025 Mario Zechner)—— 改措辞前先看仓库根的 `THIRD_PARTY_NOTICES.md`。
|
|
17
21
|
"""
|
|
18
22
|
|
|
19
23
|
from __future__ import annotations
|