iac-code 0.2.0__tar.gz → 0.2.2__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.
- {iac_code-0.2.0 → iac_code-0.2.2}/PKG-INFO +7 -1
- {iac_code-0.2.0 → iac_code-0.2.2}/README.md +7 -1
- iac_code-0.2.2/src/iac_code/__init__.py +2 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/__init__.py +9 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/auth.py +62 -23
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/model.py +2 -2
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/registry.py +7 -1
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/config.py +40 -3
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/de/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/de/LC_MESSAGES/messages.po +154 -147
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/es/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/es/LC_MESSAGES/messages.po +154 -147
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/fr/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/fr/LC_MESSAGES/messages.po +154 -147
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/ja/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/ja/LC_MESSAGES/messages.po +154 -147
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/pt/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/pt/LC_MESSAGES/messages.po +154 -147
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/zh/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/locales/zh/LC_MESSAGES/messages.po +155 -148
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/registry.py +5 -2
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/thinking.py +4 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/client.py +4 -4
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/names.py +1 -1
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/aliyun/aliyun_api.py +20 -1
- iac_code-0.2.2/src/iac_code/tools/cloud/aliyun/api_hooks.py +49 -0
- iac_code-0.2.2/src/iac_code/tools/cloud/aliyun/hooks/ros_validate.py +57 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/banner.py +5 -2
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/core/input_history.py +31 -7
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/core/prompt_input.py +12 -7
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/renderer.py +10 -4
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/repl.py +47 -7
- iac_code-0.2.2/src/iac_code/utils/image/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/image/clipboard.py +31 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code.egg-info/PKG-INFO +7 -1
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code.egg-info/SOURCES.txt +3 -0
- iac_code-0.2.0/src/iac_code/__init__.py +0 -2
- {iac_code-0.2.0 → iac_code-0.2.2}/LICENSE +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/MANIFEST.in +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/pyproject.toml +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/setup.cfg +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/setup.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/agent_card.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/app.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/artifacts.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/client.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/events.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/executor.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/metrics.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/parts.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/persistence.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/push.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/push_queue.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/push_secrets.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/push_worker.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/router.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/signing.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/task_store.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transport.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/base.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/dispatcher.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/grpc.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/grpc_jsonrpc.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/http.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/redis_streams.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/stdio.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/unix.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/transports/websocket.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/a2a/types.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/convert.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/http_sse.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/mcp.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/metrics.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/server.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/session.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/slash_registry.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/state.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/tools.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/types.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/acp/version.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/agent/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/agent/agent_loop.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/agent/agent_tool.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/agent/agent_types.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/agent/message.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/agent/system_prompt.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/cli/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/cli/headless.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/cli/main.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/cli/output_formats.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/clear.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/compact.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/debug.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/effort.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/exit.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/help.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/resume.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/commands/tasks.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/i18n/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/memory/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/memory/memory_manager.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/memory/memory_tools.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/anthropic_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/azure_openai_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/base.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/dashscope_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/deepseek_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/gemini_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/kimi_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/lmstudio_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/manager.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/minimax_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/modelscope_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/ollama_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/openai_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/openrouter_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/retry.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/siliconflow_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/stream_watchdog.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/volcengine_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/providers/zhipu_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/agent_factory.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/capabilities/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/capabilities/auto_detect.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/capabilities/multimodal.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/cloud_credentials.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/context_manager.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/permissions/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/permissions/loader.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/permissions/pipeline.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/permissions/storage.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/providers/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/providers/aliyun.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/qwenpaw_source.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/session_index.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/session_storage.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/attributes.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/config.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/constants.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/content_serializer.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/events.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/fallback.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/identity.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/metrics.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/sanitize.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/sink.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/tracing.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/telemetry/types.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/token_budget.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/services/token_counter.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/SKILL.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/ecs.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/oss.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/rds.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/redis.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/slb.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/vpc.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/references/ros-template.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/references/template-parameters.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/references/terraform-template.md +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/iac_aliyun/scripts/tf2ros.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/bundled/simplify.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/discovery.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/frontmatter.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/listing.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/loader.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/processor.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/renderer.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/skill_definition.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/skills/skill_tool.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/state/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/state/app_state.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tasks/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tasks/notification_queue.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tasks/task_state.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tasks/task_tools.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/base.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/bash/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/bash/bash_tool.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/bash/command_parser.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/bash/mode_validation.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/bash/path_validation.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/bash/permissions.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/bash/readonly_commands.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/bash/rule_matching.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/bash/safety_checks.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/aliyun/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/aliyun/aliyun_doc_search.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/aliyun/endpoints.yml +0 -0
- {iac_code-0.2.0/src/iac_code/ui/components → iac_code-0.2.2/src/iac_code/tools/cloud/aliyun/hooks}/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/aliyun/ros_client.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/aliyun/ros_stack.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/aliyun/ros_stack_instances.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/base_api.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/base_stack.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/registry.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/cloud/types.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/edit_file.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/glob.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/grep.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/list_files.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/read_file.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/result_storage.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/tool_executor.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/web_fetch.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/tools/write_file.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/types/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/types/permissions.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/types/skill_source.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/types/stream_events.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/__init__.py +0 -0
- {iac_code-0.2.0/src/iac_code/ui/core → iac_code-0.2.2/src/iac_code/ui/components}/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/components/dialog.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/components/divider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/components/fuzzy_picker.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/components/progress_bar.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/components/search_box.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/components/select.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/components/status_icon.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/components/tabs.py +0 -0
- {iac_code-0.2.0/src/iac_code/ui/dialogs → iac_code-0.2.2/src/iac_code/ui/core}/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/core/in_place_render.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/core/key_event.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/core/raw_input.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/core/screen.py +0 -0
- {iac_code-0.2.0/src/iac_code/ui/keybindings → iac_code-0.2.2/src/iac_code/ui/dialogs}/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/dialogs/global_search.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/dialogs/history_search.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/dialogs/model_picker.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/dialogs/quick_open.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/dialogs/resume_picker.py +0 -0
- {iac_code-0.2.0/src/iac_code/ui/suggestions → iac_code-0.2.2/src/iac_code/ui/keybindings}/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/keybindings/manager.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/spinner.py +0 -0
- {iac_code-0.2.0/src/iac_code/utils → iac_code-0.2.2/src/iac_code/ui/suggestions}/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/suggestions/aggregator.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/suggestions/command_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/suggestions/directory_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/suggestions/file_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/suggestions/shell_history_provider.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/suggestions/token_extractor.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/suggestions/types.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/ui/transcript_view.py +0 -0
- {iac_code-0.2.0/src/iac_code/utils/image → iac_code-0.2.2/src/iac_code/utils}/__init__.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/background_housekeeping.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/cleanup.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/image/format_detect.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/image/pasted_content.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/image/processor.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/image/resizer.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/image/store.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/json_utils.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/log.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/project_paths.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code/utils/tool_input_parser.py +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code.egg-info/dependency_links.txt +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code.egg-info/entry_points.txt +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code.egg-info/requires.txt +0 -0
- {iac_code-0.2.0 → iac_code-0.2.2}/src/iac_code.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: iac_code
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Your AI-powered Infrastructure as Code assistant
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -65,3 +65,9 @@ Reading from stdin is also supported:
|
|
|
65
65
|
```bash
|
|
66
66
|
echo "Create an OSS Bucket" | iac-code --prompt -
|
|
67
67
|
```
|
|
68
|
+
|
|
69
|
+
## Contact Us
|
|
70
|
+
|
|
71
|
+
| [DingTalk](https://qr.dingtalk.com/action/joingroup?code=v1,k1,ubm/77U7qRh/STFZUNBP26X4PNg2z6+uhiPcLGtDNfU=&_dt_no_comment=1&origin=11) | [Discord](https://discord.gg/qECFuFBwF) |
|
|
72
|
+
| :----------------------------------------------------------: | :----------------------------------------------------------: |
|
|
73
|
+
| [<img src="website/static/img/qrcode-dingtalk.jpg" width="120" height="120" alt="DingTalk">](https://qr.dingtalk.com/action/joingroup?code=v1,k1,ubm/77U7qRh/STFZUNBP26X4PNg2z6+uhiPcLGtDNfU=&_dt_no_comment=1&origin=11) | [<img src="website/static/img/qrcode-discord.jpg" width="120" height="120" alt="Discord">](https://discord.gg/qECFuFBwF) |
|
|
@@ -45,4 +45,10 @@ Reading from stdin is also supported:
|
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
47
|
echo "Create an OSS Bucket" | iac-code --prompt -
|
|
48
|
-
```
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Contact Us
|
|
51
|
+
|
|
52
|
+
| [DingTalk](https://qr.dingtalk.com/action/joingroup?code=v1,k1,ubm/77U7qRh/STFZUNBP26X4PNg2z6+uhiPcLGtDNfU=&_dt_no_comment=1&origin=11) | [Discord](https://discord.gg/qECFuFBwF) |
|
|
53
|
+
| :----------------------------------------------------------: | :----------------------------------------------------------: |
|
|
54
|
+
| [<img src="website/static/img/qrcode-dingtalk.jpg" width="120" height="120" alt="DingTalk">](https://qr.dingtalk.com/action/joingroup?code=v1,k1,ubm/77U7qRh/STFZUNBP26X4PNg2z6+uhiPcLGtDNfU=&_dt_no_comment=1&origin=11) | [<img src="website/static/img/qrcode-discord.jpg" width="120" height="120" alt="Discord">](https://discord.gg/qECFuFBwF) |
|
|
@@ -22,6 +22,7 @@ def create_default_registry() -> CommandRegistry:
|
|
|
22
22
|
description=_("Show available commands"),
|
|
23
23
|
handler=help_command,
|
|
24
24
|
aliases=["?"],
|
|
25
|
+
history_mode="session",
|
|
25
26
|
)
|
|
26
27
|
)
|
|
27
28
|
registry.register(
|
|
@@ -29,6 +30,7 @@ def create_default_registry() -> CommandRegistry:
|
|
|
29
30
|
name="clear",
|
|
30
31
|
description=_("Clear conversation history"),
|
|
31
32
|
handler=clear_command,
|
|
33
|
+
history_mode="session",
|
|
32
34
|
)
|
|
33
35
|
)
|
|
34
36
|
registry.register(
|
|
@@ -37,6 +39,7 @@ def create_default_registry() -> CommandRegistry:
|
|
|
37
39
|
description=_("Show or switch model"),
|
|
38
40
|
handler=model_command,
|
|
39
41
|
arg_names=["model_name"],
|
|
42
|
+
history_mode="session",
|
|
40
43
|
)
|
|
41
44
|
)
|
|
42
45
|
registry.register(
|
|
@@ -45,6 +48,7 @@ def create_default_registry() -> CommandRegistry:
|
|
|
45
48
|
description=_("Show or switch thinking effort"),
|
|
46
49
|
handler=effort_command,
|
|
47
50
|
arg_names=["level"],
|
|
51
|
+
history_mode="session",
|
|
48
52
|
)
|
|
49
53
|
)
|
|
50
54
|
registry.register(
|
|
@@ -53,6 +57,7 @@ def create_default_registry() -> CommandRegistry:
|
|
|
53
57
|
description=_("Compact conversation context"),
|
|
54
58
|
handler=compact_command,
|
|
55
59
|
progress_label=_("Compacting conversation"),
|
|
60
|
+
history_mode="session",
|
|
56
61
|
)
|
|
57
62
|
)
|
|
58
63
|
registry.register(
|
|
@@ -61,6 +66,7 @@ def create_default_registry() -> CommandRegistry:
|
|
|
61
66
|
description=_("Exit the application"),
|
|
62
67
|
handler=exit_command,
|
|
63
68
|
aliases=["quit", "q"],
|
|
69
|
+
history_mode="none",
|
|
64
70
|
)
|
|
65
71
|
)
|
|
66
72
|
registry.register(
|
|
@@ -69,6 +75,7 @@ def create_default_registry() -> CommandRegistry:
|
|
|
69
75
|
description=_("Authenticate with LLM provider"),
|
|
70
76
|
handler=auth_command,
|
|
71
77
|
aliases=["login"],
|
|
78
|
+
history_mode="session",
|
|
72
79
|
)
|
|
73
80
|
)
|
|
74
81
|
registry.register(
|
|
@@ -77,6 +84,7 @@ def create_default_registry() -> CommandRegistry:
|
|
|
77
84
|
description=_("Toggle debug logging"),
|
|
78
85
|
handler=debug_command,
|
|
79
86
|
arg_hint="[on|off]",
|
|
87
|
+
history_mode="session",
|
|
80
88
|
)
|
|
81
89
|
)
|
|
82
90
|
registry.register(
|
|
@@ -85,6 +93,7 @@ def create_default_registry() -> CommandRegistry:
|
|
|
85
93
|
description=_("Resume a previous session"),
|
|
86
94
|
handler=resume_command,
|
|
87
95
|
arg_hint=_("[conversation id or search term]"),
|
|
96
|
+
history_mode="session",
|
|
88
97
|
)
|
|
89
98
|
)
|
|
90
99
|
return registry
|
|
@@ -14,10 +14,14 @@ if TYPE_CHECKING:
|
|
|
14
14
|
|
|
15
15
|
from iac_code.config import (
|
|
16
16
|
_LEGACY_KEY_NAME_ALIASES,
|
|
17
|
+
PARTNER_SOURCES,
|
|
18
|
+
PartnerSource,
|
|
17
19
|
_load_yaml,
|
|
18
20
|
_save_yaml,
|
|
19
21
|
get_active_provider_key,
|
|
22
|
+
get_available_partner_sources,
|
|
20
23
|
get_credentials_path,
|
|
24
|
+
get_llm_source,
|
|
21
25
|
get_provider_config,
|
|
22
26
|
get_settings_path,
|
|
23
27
|
)
|
|
@@ -595,6 +599,47 @@ def _get_active_key_name() -> str:
|
|
|
595
599
|
return get_active_provider_key() or ""
|
|
596
600
|
|
|
597
601
|
|
|
602
|
+
def _third_party_auth_flow(
|
|
603
|
+
available_partners: list[PartnerSource],
|
|
604
|
+
current_llm_source: str,
|
|
605
|
+
) -> str | None | _BackSentinel:
|
|
606
|
+
"""Second-level selection within the Third-party category."""
|
|
607
|
+
candidates = list(available_partners)
|
|
608
|
+
if any(ps.key == current_llm_source for ps in PARTNER_SOURCES):
|
|
609
|
+
if not any(ps.key == current_llm_source for ps in candidates):
|
|
610
|
+
for ps in PARTNER_SOURCES:
|
|
611
|
+
if ps.key == current_llm_source:
|
|
612
|
+
candidates.append(ps)
|
|
613
|
+
break
|
|
614
|
+
|
|
615
|
+
if len(candidates) == 0:
|
|
616
|
+
return _BACK
|
|
617
|
+
|
|
618
|
+
options: list[str] = []
|
|
619
|
+
default_idx = 0
|
|
620
|
+
for i, ps in enumerate(candidates):
|
|
621
|
+
label = ps.display_name
|
|
622
|
+
if current_llm_source == ps.key:
|
|
623
|
+
label += _(" (current)")
|
|
624
|
+
default_idx = i
|
|
625
|
+
options.append(label)
|
|
626
|
+
|
|
627
|
+
idx = _select(_("Select provider — {group}").format(group=_("Third-party")), options, default_index=default_idx)
|
|
628
|
+
if idx is None:
|
|
629
|
+
return _BACK
|
|
630
|
+
partner = candidates[idx]
|
|
631
|
+
|
|
632
|
+
settings_path = get_settings_path()
|
|
633
|
+
config = _load_yaml(settings_path)
|
|
634
|
+
config.pop("activeProvider", None)
|
|
635
|
+
config["llm_source"] = partner.key
|
|
636
|
+
_save_yaml(settings_path, config)
|
|
637
|
+
return _("{status}: {provider}").format(
|
|
638
|
+
status=_("Configured"),
|
|
639
|
+
provider=partner.display_name,
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
|
|
598
643
|
def _llm_auth_flow(console, store) -> str | None | _BackSentinel:
|
|
599
644
|
"""LLM provider auth flow with two-step vendor group selection."""
|
|
600
645
|
active_key_name = _get_active_key_name()
|
|
@@ -621,49 +666,42 @@ def _llm_auth_flow(console, store) -> str | None | _BackSentinel:
|
|
|
621
666
|
|
|
622
667
|
provider_map: dict[str, LLMProvider] = {str(p["key_name"]): p for p in PROVIDERS}
|
|
623
668
|
|
|
624
|
-
from iac_code.config import PARTNER_SOURCES, get_llm_source
|
|
625
|
-
|
|
626
|
-
num_partner_sources = len(PARTNER_SOURCES)
|
|
627
|
-
|
|
628
669
|
current_llm_source = get_llm_source()
|
|
670
|
+
available_partners = get_available_partner_sources()
|
|
671
|
+
is_current_partner = any(ps.key == current_llm_source for ps in PARTNER_SOURCES)
|
|
672
|
+
show_third_party = len(available_partners) > 0 or is_current_partner
|
|
629
673
|
|
|
630
674
|
while True:
|
|
631
|
-
# Step 1: Select vendor group (partner sources shown at the top)
|
|
632
675
|
group_options: list[str] = []
|
|
633
676
|
group_default_idx = 0
|
|
634
677
|
|
|
635
|
-
|
|
636
|
-
label =
|
|
637
|
-
if
|
|
678
|
+
if show_third_party:
|
|
679
|
+
label = _("Third-party")
|
|
680
|
+
if is_current_partner:
|
|
638
681
|
label += _(" (current)")
|
|
639
|
-
group_default_idx =
|
|
682
|
+
group_default_idx = 0
|
|
640
683
|
group_options.append(label)
|
|
641
684
|
|
|
642
685
|
for i, (group_name, keys) in enumerate(provider_groups):
|
|
643
686
|
label = _(group_name)
|
|
687
|
+
offset = 1 if show_third_party else 0
|
|
644
688
|
if active_key_name in keys:
|
|
645
689
|
label += _(" (current)")
|
|
646
|
-
group_default_idx = i +
|
|
690
|
+
group_default_idx = i + offset
|
|
647
691
|
group_options.append(label)
|
|
648
692
|
|
|
649
693
|
group_idx = _select(_("Select provider"), group_options, default_index=group_default_idx)
|
|
650
694
|
if group_idx is None:
|
|
651
695
|
return _BACK
|
|
652
696
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
config.pop("activeProvider", None)
|
|
659
|
-
config["llm_source"] = partner["key"]
|
|
660
|
-
_save_yaml(settings_path, config)
|
|
661
|
-
return _("{status}: {provider}").format(
|
|
662
|
-
status=_("Configured"),
|
|
663
|
-
provider=partner["display_name"],
|
|
664
|
-
)
|
|
697
|
+
if show_third_party and group_idx == 0:
|
|
698
|
+
result = _third_party_auth_flow(available_partners, current_llm_source)
|
|
699
|
+
if isinstance(result, _BackSentinel):
|
|
700
|
+
continue
|
|
701
|
+
return result
|
|
665
702
|
|
|
666
|
-
|
|
703
|
+
offset = 1 if show_third_party else 0
|
|
704
|
+
group_name, group_keys = provider_groups[group_idx - offset]
|
|
667
705
|
group_providers = [provider_map[k] for k in group_keys if k in provider_map]
|
|
668
706
|
|
|
669
707
|
# Step 2: Select provider within group (skip if only one)
|
|
@@ -755,6 +793,7 @@ def _llm_auth_flow(console, store) -> str | None | _BackSentinel:
|
|
|
755
793
|
|
|
756
794
|
|
|
757
795
|
_GROUP_NAME_MARKERS = [
|
|
796
|
+
_("Third-party"),
|
|
758
797
|
_("Alibaba Cloud"),
|
|
759
798
|
_("ZhiPu AI"),
|
|
760
799
|
_("Kimi"),
|
|
@@ -50,8 +50,8 @@ async def model_command(context: "CommandContext | None" = None, args: list[str]
|
|
|
50
50
|
|
|
51
51
|
display_name = llm_source
|
|
52
52
|
for ps in PARTNER_SOURCES:
|
|
53
|
-
if ps
|
|
54
|
-
display_name = ps
|
|
53
|
+
if ps.key == llm_source:
|
|
54
|
+
display_name = ps.display_name
|
|
55
55
|
break
|
|
56
56
|
return _(
|
|
57
57
|
"Model is managed by '{source}'. To change model, modify it in {source} or switch provider via /auth."
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
|
-
from typing import TYPE_CHECKING, Any, Awaitable, Callable
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Literal
|
|
7
7
|
|
|
8
8
|
from iac_code.types.skill_source import SkillSource
|
|
9
9
|
|
|
@@ -42,6 +42,12 @@ class LocalCommand(Command):
|
|
|
42
42
|
progress_label: str | None = None
|
|
43
43
|
"""When set, the REPL shows a spinner with this label while the handler runs.
|
|
44
44
|
Use for commands that perform slow async work (e.g. an LLM call)."""
|
|
45
|
+
history_mode: Literal["persist", "session", "none"] = "persist"
|
|
46
|
+
"""Controls how the command is recorded in input history.
|
|
47
|
+
- "persist": saved to disk (default, for normal commands).
|
|
48
|
+
- "session": kept in memory for the current session only.
|
|
49
|
+
- "none": never recorded in history.
|
|
50
|
+
"""
|
|
45
51
|
|
|
46
52
|
|
|
47
53
|
@dataclass
|
|
@@ -9,13 +9,14 @@ expansion supported); when set, every persisted artifact follows.
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
11
|
import os
|
|
12
|
+
from dataclasses import dataclass
|
|
12
13
|
from pathlib import Path
|
|
13
14
|
from typing import Any
|
|
14
15
|
|
|
15
16
|
import yaml
|
|
16
17
|
|
|
17
18
|
# Default LLM model used when no model is saved in settings
|
|
18
|
-
DEFAULT_MODEL = "qwen3.
|
|
19
|
+
DEFAULT_MODEL = "qwen3.7-max"
|
|
19
20
|
|
|
20
21
|
# Configuration directory
|
|
21
22
|
_CONFIG_DIR_NAME = ".iac-code"
|
|
@@ -179,11 +180,47 @@ def get_llm_source() -> str:
|
|
|
179
180
|
return "local"
|
|
180
181
|
|
|
181
182
|
|
|
182
|
-
|
|
183
|
-
|
|
183
|
+
@dataclass(frozen=True)
|
|
184
|
+
class PartnerSource:
|
|
185
|
+
key: str
|
|
186
|
+
display_name: str
|
|
187
|
+
|
|
188
|
+
def is_available(self) -> bool:
|
|
189
|
+
if self.key == "qwenpaw":
|
|
190
|
+
from iac_code.services.qwenpaw_source import _resolve_secret_dir
|
|
191
|
+
|
|
192
|
+
return _resolve_secret_dir() is not None
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
def get_provider_display(self) -> str:
|
|
196
|
+
if self.key == "qwenpaw":
|
|
197
|
+
from iac_code.services.qwenpaw_source import load_from_qwenpaw
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
config = load_from_qwenpaw()
|
|
201
|
+
except Exception:
|
|
202
|
+
return ""
|
|
203
|
+
if config:
|
|
204
|
+
from iac_code.providers.registry import PROVIDER_REGISTRY
|
|
205
|
+
|
|
206
|
+
desc = PROVIDER_REGISTRY.get(config.provider_key)
|
|
207
|
+
if desc:
|
|
208
|
+
from iac_code.i18n import _
|
|
209
|
+
|
|
210
|
+
return _(desc.display_name)
|
|
211
|
+
return config.provider_key
|
|
212
|
+
return ""
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
PARTNER_SOURCES: list[PartnerSource] = [
|
|
216
|
+
PartnerSource(key="qwenpaw", display_name="QwenPaw"),
|
|
184
217
|
]
|
|
185
218
|
|
|
186
219
|
|
|
220
|
+
def get_available_partner_sources() -> list[PartnerSource]:
|
|
221
|
+
return [ps for ps in PARTNER_SOURCES if ps.is_available()]
|
|
222
|
+
|
|
223
|
+
|
|
187
224
|
# ---------------------------------------------------------------------------
|
|
188
225
|
# Path helpers
|
|
189
226
|
# ---------------------------------------------------------------------------
|