iac-code 0.2.1__tar.gz → 0.2.3__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.1 → iac_code-0.2.3}/PKG-INFO +1 -1
- iac_code-0.2.3/src/iac_code/__init__.py +2 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/events.py +10 -8
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/executor.py +22 -1
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/session.py +11 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/cli/main.py +166 -6
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/__init__.py +9 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/registry.py +7 -1
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/config.py +1 -1
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/de/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/de/LC_MESSAGES/messages.po +162 -88
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/es/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/es/LC_MESSAGES/messages.po +169 -88
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/fr/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/fr/LC_MESSAGES/messages.po +169 -88
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/ja/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/ja/LC_MESSAGES/messages.po +156 -88
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/pt/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/pt/LC_MESSAGES/messages.po +164 -88
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/zh/LC_MESSAGES/messages.mo +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/locales/zh/LC_MESSAGES/messages.po +155 -89
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/manager.py +3 -3
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/registry.py +5 -2
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/thinking.py +4 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/__init__.py +11 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/client.py +31 -10
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/names.py +1 -1
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/SKILL.md +14 -13
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/aliyun/aliyun_api.py +20 -1
- iac_code-0.2.3/src/iac_code/tools/cloud/aliyun/api_hooks.py +54 -0
- iac_code-0.2.3/src/iac_code/tools/cloud/aliyun/hooks/ros_parameters.py +76 -0
- iac_code-0.2.3/src/iac_code/tools/cloud/aliyun/hooks/ros_validate.py +157 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/aliyun/ros_stack.py +15 -5
- iac_code-0.2.3/src/iac_code/tools/cloud/aliyun/ros_yaml.py +102 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/core/input_history.py +31 -7
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/core/prompt_input.py +83 -36
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/renderer.py +10 -4
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/repl.py +47 -7
- iac_code-0.2.3/src/iac_code/utils/image/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/image/clipboard.py +31 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code.egg-info/PKG-INFO +1 -1
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code.egg-info/SOURCES.txt +5 -0
- iac_code-0.2.1/src/iac_code/__init__.py +0 -2
- {iac_code-0.2.1 → iac_code-0.2.3}/LICENSE +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/MANIFEST.in +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/README.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/pyproject.toml +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/setup.cfg +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/setup.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/agent_card.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/app.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/artifacts.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/client.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/metrics.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/parts.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/persistence.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/push.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/push_queue.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/push_secrets.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/push_worker.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/router.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/signing.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/task_store.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transport.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/base.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/dispatcher.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/grpc.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/grpc_jsonrpc.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/http.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/redis_streams.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/stdio.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/unix.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/transports/websocket.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/a2a/types.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/convert.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/http_sse.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/mcp.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/metrics.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/server.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/slash_registry.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/state.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/tools.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/types.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/acp/version.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/agent/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/agent/agent_loop.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/agent/agent_tool.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/agent/agent_types.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/agent/message.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/agent/system_prompt.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/cli/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/cli/headless.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/cli/output_formats.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/auth.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/clear.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/compact.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/debug.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/effort.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/exit.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/help.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/model.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/resume.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/commands/tasks.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/i18n/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/memory/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/memory/memory_manager.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/memory/memory_tools.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/anthropic_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/azure_openai_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/base.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/dashscope_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/deepseek_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/gemini_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/kimi_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/lmstudio_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/minimax_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/modelscope_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/ollama_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/openai_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/openrouter_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/retry.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/siliconflow_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/stream_watchdog.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/volcengine_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/providers/zhipu_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/agent_factory.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/capabilities/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/capabilities/auto_detect.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/capabilities/multimodal.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/cloud_credentials.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/context_manager.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/permissions/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/permissions/loader.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/permissions/pipeline.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/permissions/storage.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/providers/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/providers/aliyun.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/qwenpaw_source.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/session_index.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/session_storage.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/attributes.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/config.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/constants.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/content_serializer.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/events.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/fallback.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/identity.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/metrics.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/sanitize.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/sink.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/tracing.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/telemetry/types.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/token_budget.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/services/token_counter.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/ecs.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/oss.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/rds.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/redis.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/slb.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/references/cloud-products/vpc.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/references/ros-template.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/references/template-parameters.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/references/terraform-template.md +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/iac_aliyun/scripts/tf2ros.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/bundled/simplify.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/discovery.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/frontmatter.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/listing.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/loader.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/processor.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/renderer.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/skill_definition.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/skills/skill_tool.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/state/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/state/app_state.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tasks/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tasks/notification_queue.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tasks/task_state.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tasks/task_tools.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/base.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/bash/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/bash/bash_tool.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/bash/command_parser.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/bash/mode_validation.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/bash/path_validation.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/bash/permissions.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/bash/readonly_commands.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/bash/rule_matching.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/bash/safety_checks.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/aliyun/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/aliyun/aliyun_doc_search.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/aliyun/endpoints.yml +0 -0
- {iac_code-0.2.1/src/iac_code/ui/components → iac_code-0.2.3/src/iac_code/tools/cloud/aliyun/hooks}/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/aliyun/ros_client.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/aliyun/ros_stack_instances.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/base_api.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/base_stack.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/registry.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/cloud/types.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/edit_file.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/glob.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/grep.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/list_files.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/read_file.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/result_storage.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/tool_executor.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/web_fetch.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/tools/write_file.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/types/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/types/permissions.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/types/skill_source.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/types/stream_events.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/banner.py +0 -0
- {iac_code-0.2.1/src/iac_code/ui/core → iac_code-0.2.3/src/iac_code/ui/components}/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/components/dialog.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/components/divider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/components/fuzzy_picker.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/components/progress_bar.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/components/search_box.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/components/select.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/components/status_icon.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/components/tabs.py +0 -0
- {iac_code-0.2.1/src/iac_code/ui/dialogs → iac_code-0.2.3/src/iac_code/ui/core}/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/core/in_place_render.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/core/key_event.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/core/raw_input.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/core/screen.py +0 -0
- {iac_code-0.2.1/src/iac_code/ui/keybindings → iac_code-0.2.3/src/iac_code/ui/dialogs}/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/dialogs/global_search.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/dialogs/history_search.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/dialogs/model_picker.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/dialogs/quick_open.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/dialogs/resume_picker.py +0 -0
- {iac_code-0.2.1/src/iac_code/ui/suggestions → iac_code-0.2.3/src/iac_code/ui/keybindings}/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/keybindings/manager.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/spinner.py +0 -0
- {iac_code-0.2.1/src/iac_code/utils → iac_code-0.2.3/src/iac_code/ui/suggestions}/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/suggestions/aggregator.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/suggestions/command_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/suggestions/directory_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/suggestions/file_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/suggestions/shell_history_provider.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/suggestions/token_extractor.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/suggestions/types.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/ui/transcript_view.py +0 -0
- {iac_code-0.2.1/src/iac_code/utils/image → iac_code-0.2.3/src/iac_code/utils}/__init__.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/background_housekeeping.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/cleanup.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/image/format_detect.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/image/pasted_content.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/image/processor.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/image/resizer.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/image/store.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/json_utils.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/log.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/project_paths.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code/utils/tool_input_parser.py +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code.egg-info/dependency_links.txt +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code.egg-info/entry_points.txt +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code.egg-info/requires.txt +0 -0
- {iac_code-0.2.1 → iac_code-0.2.3}/src/iac_code.egg-info/top_level.txt +0 -0
|
@@ -31,6 +31,7 @@ from iac_code.types.stream_events import (
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
_METADATA_MAX_CHARS = 4000
|
|
34
|
+
_ERROR_TEXT_MAX_CHARS = 1000
|
|
34
35
|
_METADATA_MAX_DEPTH = 32
|
|
35
36
|
logger = logging.getLogger(__name__)
|
|
36
37
|
A2APermissionResolver: TypeAlias = Callable[[PermissionRequestEvent], "bool | Awaitable[bool]"]
|
|
@@ -298,18 +299,19 @@ async def publish_stream_event(
|
|
|
298
299
|
return None
|
|
299
300
|
|
|
300
301
|
if isinstance(event, ErrorEvent):
|
|
302
|
+
if event.is_retryable:
|
|
303
|
+
text = "A temporary error occurred. Please retry."
|
|
304
|
+
state = TaskState.TASK_STATE_INPUT_REQUIRED
|
|
305
|
+
else:
|
|
306
|
+
raw = event.error or "Unknown error"
|
|
307
|
+
text = raw[:_ERROR_TEXT_MAX_CHARS]
|
|
308
|
+
state = TaskState.TASK_STATE_FAILED
|
|
301
309
|
await _enqueue_status(
|
|
302
310
|
event_queue,
|
|
303
311
|
task_id=task_id,
|
|
304
312
|
context_id=context_id,
|
|
305
|
-
state=
|
|
306
|
-
message=_agent_text_message(
|
|
307
|
-
task_id=task_id,
|
|
308
|
-
context_id=context_id,
|
|
309
|
-
text="A temporary error occurred. Please retry."
|
|
310
|
-
if event.is_retryable
|
|
311
|
-
else "An internal error occurred.",
|
|
312
|
-
),
|
|
313
|
+
state=state,
|
|
314
|
+
message=_agent_text_message(task_id=task_id, context_id=context_id, text=text),
|
|
313
315
|
)
|
|
314
316
|
return None
|
|
315
317
|
|
|
@@ -29,6 +29,16 @@ from iac_code.services.session_storage import SessionStorage
|
|
|
29
29
|
|
|
30
30
|
logger = logging.getLogger(__name__)
|
|
31
31
|
_CONTEXT_LOCK_ACQUIRE_TIMEOUT_SECONDS = 1
|
|
32
|
+
_ERROR_TEXT_MAX_CHARS = 1000
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _format_exception(exc: BaseException) -> str:
|
|
36
|
+
message = str(exc)
|
|
37
|
+
if not message:
|
|
38
|
+
return type(exc).__name__
|
|
39
|
+
return f"{type(exc).__name__}: {message[:_ERROR_TEXT_MAX_CHARS]}"
|
|
40
|
+
|
|
41
|
+
|
|
32
42
|
A2APermissionResolver: TypeAlias = Callable[[Any], "bool | Awaitable[bool]"]
|
|
33
43
|
|
|
34
44
|
|
|
@@ -274,6 +284,17 @@ class IacCodeA2AExecutor(AgentExecutor):
|
|
|
274
284
|
ctx.touch()
|
|
275
285
|
task.touch()
|
|
276
286
|
self._task_store.mirror_context(ctx)
|
|
287
|
+
# Force-flush telemetry between tasks. The a2a server may run in
|
|
288
|
+
# an ephemeral sandbox that's destroyed immediately after the
|
|
289
|
+
# response is delivered, before the natural batch interval or
|
|
290
|
+
# process-exit graceful_shutdown can run. Synchronous flush is
|
|
291
|
+
# offloaded to a worker thread so the event loop is not blocked.
|
|
292
|
+
from iac_code.services.telemetry import flush_telemetry
|
|
293
|
+
|
|
294
|
+
try:
|
|
295
|
+
await asyncio.to_thread(flush_telemetry)
|
|
296
|
+
except Exception:
|
|
297
|
+
logger.debug("flush_telemetry after task failed", exc_info=True)
|
|
277
298
|
finally:
|
|
278
299
|
lock.release()
|
|
279
300
|
|
|
@@ -338,7 +359,7 @@ class IacCodeA2AExecutor(AgentExecutor):
|
|
|
338
359
|
if status == 401:
|
|
339
360
|
return "Authentication required. Please configure your API credentials."
|
|
340
361
|
logger.exception("Unhandled A2A executor error")
|
|
341
|
-
return
|
|
362
|
+
return _format_exception(exc)
|
|
342
363
|
|
|
343
364
|
async def _publish_status(
|
|
344
365
|
self,
|
|
@@ -351,6 +351,17 @@ class ACPSession:
|
|
|
351
351
|
duration_ms = (time.monotonic() - prompt_start) * 1000
|
|
352
352
|
if self._metrics is not None:
|
|
353
353
|
self._metrics.record_prompt(duration_ms)
|
|
354
|
+
# Force-flush telemetry between prompts. The acp server may run in
|
|
355
|
+
# an ephemeral sandbox that's destroyed immediately after the
|
|
356
|
+
# response is delivered, before the natural batch interval or
|
|
357
|
+
# process-exit graceful_shutdown can run. Synchronous flush is
|
|
358
|
+
# offloaded to a worker thread so the event loop is not blocked.
|
|
359
|
+
from iac_code.services.telemetry import flush_telemetry
|
|
360
|
+
|
|
361
|
+
try:
|
|
362
|
+
await asyncio.to_thread(flush_telemetry)
|
|
363
|
+
except Exception:
|
|
364
|
+
logger.debug("flush_telemetry after prompt failed", exc_info=True)
|
|
354
365
|
|
|
355
366
|
self.touch()
|
|
356
367
|
|
|
@@ -311,14 +311,91 @@ def acp(
|
|
|
311
311
|
debug: bool = typer.Option(False, "--debug", "-d", help=_("Enable debug logging")),
|
|
312
312
|
) -> None:
|
|
313
313
|
"""Run iac-code as an ACP server."""
|
|
314
|
-
|
|
315
|
-
|
|
314
|
+
import atexit
|
|
315
|
+
import signal as _signal_mod
|
|
316
|
+
import time
|
|
317
|
+
|
|
318
|
+
from iac_code.services.telemetry import add_metric, bootstrap_telemetry, graceful_shutdown, log_event
|
|
319
|
+
from iac_code.services.telemetry.names import Events, Metrics
|
|
320
|
+
|
|
321
|
+
telemetry_session_id = f"acp-server-{uuid.uuid4()}"
|
|
322
|
+
bootstrap_telemetry(session_id=telemetry_session_id)
|
|
323
|
+
log_event(
|
|
324
|
+
Events.SESSION_STARTED,
|
|
325
|
+
{
|
|
326
|
+
"mode": "acp-server",
|
|
327
|
+
"transport": transport,
|
|
328
|
+
},
|
|
329
|
+
)
|
|
330
|
+
add_metric(Metrics.SESSION_COUNT, 1, {})
|
|
316
331
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
332
|
+
started = time.monotonic()
|
|
333
|
+
exit_reason = "normal"
|
|
334
|
+
_finalized = [False]
|
|
335
|
+
|
|
336
|
+
def _finalize_telemetry(reason_override: str | None = None) -> None:
|
|
337
|
+
if _finalized[0]:
|
|
338
|
+
return
|
|
339
|
+
_finalized[0] = True
|
|
340
|
+
final_reason = reason_override or exit_reason
|
|
341
|
+
try:
|
|
342
|
+
log_event(
|
|
343
|
+
Events.SESSION_EXITED,
|
|
344
|
+
{
|
|
345
|
+
"mode": "acp-server",
|
|
346
|
+
"reason": final_reason,
|
|
347
|
+
"duration_s": int(time.monotonic() - started),
|
|
348
|
+
},
|
|
349
|
+
)
|
|
350
|
+
finally:
|
|
351
|
+
graceful_shutdown()
|
|
352
|
+
|
|
353
|
+
atexit.register(_finalize_telemetry, "atexit")
|
|
354
|
+
|
|
355
|
+
def _telemetry_excepthook(exc_type, exc_value, traceback_obj):
|
|
356
|
+
try:
|
|
357
|
+
log_event(
|
|
358
|
+
Events.EXCEPTION_UNCAUGHT,
|
|
359
|
+
{
|
|
360
|
+
"error_name": exc_type.__name__,
|
|
361
|
+
"location": "acp",
|
|
362
|
+
},
|
|
363
|
+
)
|
|
364
|
+
_finalize_telemetry(f"exception:{exc_type.__name__}")
|
|
365
|
+
finally:
|
|
366
|
+
sys.__excepthook__(exc_type, exc_value, traceback_obj)
|
|
367
|
+
|
|
368
|
+
sys.excepthook = _telemetry_excepthook
|
|
369
|
+
|
|
370
|
+
_prev_sigterm = _signal_mod.getsignal(_signal_mod.SIGTERM)
|
|
371
|
+
_prev_sigint = _signal_mod.getsignal(_signal_mod.SIGINT)
|
|
372
|
+
|
|
373
|
+
def _telemetry_signal_handler(signum, frame):
|
|
374
|
+
_finalize_telemetry(f"signal:{signum}")
|
|
375
|
+
prev = _prev_sigterm if signum == _signal_mod.SIGTERM else _prev_sigint
|
|
376
|
+
if callable(prev):
|
|
377
|
+
prev(signum, frame) # ty: ignore[call-top-callable]
|
|
378
|
+
return
|
|
379
|
+
_signal_mod.signal(signum, _signal_mod.SIG_DFL)
|
|
380
|
+
os.kill(os.getpid(), signum)
|
|
381
|
+
|
|
382
|
+
_signal_mod.signal(_signal_mod.SIGTERM, _telemetry_signal_handler)
|
|
383
|
+
_signal_mod.signal(_signal_mod.SIGINT, _telemetry_signal_handler)
|
|
384
|
+
|
|
385
|
+
try:
|
|
386
|
+
if transport == "http":
|
|
387
|
+
from iac_code.acp import acp_main_http
|
|
320
388
|
|
|
321
|
-
|
|
389
|
+
acp_main_http(host=host, port=port, debug=debug)
|
|
390
|
+
else:
|
|
391
|
+
from iac_code.acp import acp_main
|
|
392
|
+
|
|
393
|
+
acp_main(debug=debug)
|
|
394
|
+
except Exception:
|
|
395
|
+
exit_reason = "error"
|
|
396
|
+
raise
|
|
397
|
+
finally:
|
|
398
|
+
_finalize_telemetry()
|
|
322
399
|
|
|
323
400
|
|
|
324
401
|
def _load_a2a_config(path: str) -> dict[str, Any]:
|
|
@@ -506,6 +583,86 @@ def a2a(
|
|
|
506
583
|
err=True,
|
|
507
584
|
)
|
|
508
585
|
raise typer.Exit(1) from exc
|
|
586
|
+
|
|
587
|
+
import atexit
|
|
588
|
+
import signal as _signal_mod
|
|
589
|
+
import time
|
|
590
|
+
|
|
591
|
+
from iac_code.services.telemetry import add_metric, bootstrap_telemetry, graceful_shutdown, log_event
|
|
592
|
+
from iac_code.services.telemetry.names import Events, Metrics
|
|
593
|
+
|
|
594
|
+
telemetry_session_id = f"a2a-server-{uuid.uuid4()}"
|
|
595
|
+
bootstrap_telemetry(session_id=telemetry_session_id)
|
|
596
|
+
log_event(
|
|
597
|
+
Events.SESSION_STARTED,
|
|
598
|
+
{
|
|
599
|
+
"mode": "a2a-server",
|
|
600
|
+
"transport": transport,
|
|
601
|
+
},
|
|
602
|
+
)
|
|
603
|
+
add_metric(Metrics.SESSION_COUNT, 1, {})
|
|
604
|
+
|
|
605
|
+
started = time.monotonic()
|
|
606
|
+
exit_reason = "normal"
|
|
607
|
+
_finalized = [False]
|
|
608
|
+
|
|
609
|
+
def _finalize_telemetry(reason_override: str | None = None) -> None:
|
|
610
|
+
if _finalized[0]:
|
|
611
|
+
return
|
|
612
|
+
_finalized[0] = True
|
|
613
|
+
final_reason = reason_override or exit_reason
|
|
614
|
+
try:
|
|
615
|
+
log_event(
|
|
616
|
+
Events.SESSION_EXITED,
|
|
617
|
+
{
|
|
618
|
+
"mode": "a2a-server",
|
|
619
|
+
"reason": final_reason,
|
|
620
|
+
"duration_s": int(time.monotonic() - started),
|
|
621
|
+
},
|
|
622
|
+
)
|
|
623
|
+
finally:
|
|
624
|
+
graceful_shutdown()
|
|
625
|
+
|
|
626
|
+
# atexit fires on normal interpreter exit, including after uvicorn returns
|
|
627
|
+
# from a graceful shutdown — covers the path where the finally below also
|
|
628
|
+
# ran (idempotent via the flag).
|
|
629
|
+
atexit.register(_finalize_telemetry, "atexit")
|
|
630
|
+
|
|
631
|
+
def _telemetry_excepthook(exc_type, exc_value, traceback_obj):
|
|
632
|
+
try:
|
|
633
|
+
log_event(
|
|
634
|
+
Events.EXCEPTION_UNCAUGHT,
|
|
635
|
+
{
|
|
636
|
+
"error_name": exc_type.__name__,
|
|
637
|
+
"location": "a2a",
|
|
638
|
+
},
|
|
639
|
+
)
|
|
640
|
+
_finalize_telemetry(f"exception:{exc_type.__name__}")
|
|
641
|
+
finally:
|
|
642
|
+
sys.__excepthook__(exc_type, exc_value, traceback_obj)
|
|
643
|
+
|
|
644
|
+
sys.excepthook = _telemetry_excepthook
|
|
645
|
+
|
|
646
|
+
# Install our own SIGTERM/SIGINT handlers BEFORE uvicorn does its own. In
|
|
647
|
+
# the common path uvicorn replaces these and triggers graceful shutdown
|
|
648
|
+
# itself, after which the finally below runs. These handlers only fire if
|
|
649
|
+
# a signal arrives before uvicorn installs its own (or if uvicorn never
|
|
650
|
+
# got a chance to) — the ARMS sandbox SIGTERM-then-SIGKILL pattern.
|
|
651
|
+
_prev_sigterm = _signal_mod.getsignal(_signal_mod.SIGTERM)
|
|
652
|
+
_prev_sigint = _signal_mod.getsignal(_signal_mod.SIGINT)
|
|
653
|
+
|
|
654
|
+
def _telemetry_signal_handler(signum, frame):
|
|
655
|
+
_finalize_telemetry(f"signal:{signum}")
|
|
656
|
+
prev = _prev_sigterm if signum == _signal_mod.SIGTERM else _prev_sigint
|
|
657
|
+
if callable(prev):
|
|
658
|
+
prev(signum, frame) # ty: ignore[call-top-callable]
|
|
659
|
+
return
|
|
660
|
+
_signal_mod.signal(signum, _signal_mod.SIG_DFL)
|
|
661
|
+
os.kill(os.getpid(), signum)
|
|
662
|
+
|
|
663
|
+
_signal_mod.signal(_signal_mod.SIGTERM, _telemetry_signal_handler)
|
|
664
|
+
_signal_mod.signal(_signal_mod.SIGINT, _telemetry_signal_handler)
|
|
665
|
+
|
|
509
666
|
try:
|
|
510
667
|
if transport == "unix" and not socket_path:
|
|
511
668
|
raise RuntimeError("socket-path is required in --config for --transport unix.")
|
|
@@ -547,8 +704,11 @@ def a2a(
|
|
|
547
704
|
auto_approve_permissions=auto_approve_permissions,
|
|
548
705
|
)
|
|
549
706
|
except RuntimeError as exc:
|
|
707
|
+
exit_reason = "error"
|
|
550
708
|
typer.echo(str(exc), err=True)
|
|
551
709
|
raise typer.Exit(1) from exc
|
|
710
|
+
finally:
|
|
711
|
+
_finalize_telemetry()
|
|
552
712
|
|
|
553
713
|
|
|
554
714
|
@a2a_client_app.command(name="call", help=_("Send a prompt to an A2A JSON-RPC endpoint."))
|
|
@@ -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
|
|
@@ -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
|