iac-code 0.1.0__py3-none-any.whl
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/__init__.py +2 -0
- iac_code/acp/__init__.py +97 -0
- iac_code/acp/convert.py +423 -0
- iac_code/acp/http_sse.py +448 -0
- iac_code/acp/mcp.py +54 -0
- iac_code/acp/metrics.py +71 -0
- iac_code/acp/server.py +662 -0
- iac_code/acp/session.py +446 -0
- iac_code/acp/slash_registry.py +125 -0
- iac_code/acp/state.py +99 -0
- iac_code/acp/tools.py +112 -0
- iac_code/acp/types.py +13 -0
- iac_code/acp/version.py +26 -0
- iac_code/agent/__init__.py +19 -0
- iac_code/agent/agent_loop.py +640 -0
- iac_code/agent/agent_tool.py +269 -0
- iac_code/agent/agent_types.py +87 -0
- iac_code/agent/message.py +153 -0
- iac_code/agent/system_prompt.py +313 -0
- iac_code/cli/__init__.py +3 -0
- iac_code/cli/headless.py +114 -0
- iac_code/cli/main.py +246 -0
- iac_code/cli/output_formats.py +125 -0
- iac_code/commands/__init__.py +93 -0
- iac_code/commands/auth.py +1055 -0
- iac_code/commands/clear.py +34 -0
- iac_code/commands/compact.py +43 -0
- iac_code/commands/debug.py +45 -0
- iac_code/commands/effort.py +116 -0
- iac_code/commands/exit.py +10 -0
- iac_code/commands/help.py +49 -0
- iac_code/commands/model.py +130 -0
- iac_code/commands/registry.py +245 -0
- iac_code/commands/resume.py +49 -0
- iac_code/commands/tasks.py +41 -0
- iac_code/config.py +304 -0
- iac_code/i18n/__init__.py +141 -0
- iac_code/i18n/locales/zh/LC_MESSAGES/messages.po +1355 -0
- iac_code/memory/__init__.py +1 -0
- iac_code/memory/memory_manager.py +92 -0
- iac_code/memory/memory_tools.py +88 -0
- iac_code/providers/__init__.py +1 -0
- iac_code/providers/anthropic_provider.py +284 -0
- iac_code/providers/base.py +128 -0
- iac_code/providers/dashscope_provider.py +47 -0
- iac_code/providers/deepseek_provider.py +36 -0
- iac_code/providers/manager.py +399 -0
- iac_code/providers/openai_provider.py +344 -0
- iac_code/providers/retry.py +58 -0
- iac_code/providers/stream_watchdog.py +47 -0
- iac_code/providers/thinking.py +164 -0
- iac_code/services/__init__.py +1 -0
- iac_code/services/agent_factory.py +127 -0
- iac_code/services/cloud_credentials.py +22 -0
- iac_code/services/context_manager.py +221 -0
- iac_code/services/providers/__init__.py +1 -0
- iac_code/services/providers/aliyun.py +232 -0
- iac_code/services/session_index.py +281 -0
- iac_code/services/session_storage.py +245 -0
- iac_code/services/telemetry/__init__.py +66 -0
- iac_code/services/telemetry/attributes.py +84 -0
- iac_code/services/telemetry/client.py +330 -0
- iac_code/services/telemetry/config.py +76 -0
- iac_code/services/telemetry/constants.py +75 -0
- iac_code/services/telemetry/content_serializer.py +124 -0
- iac_code/services/telemetry/events.py +42 -0
- iac_code/services/telemetry/fallback.py +59 -0
- iac_code/services/telemetry/identity.py +73 -0
- iac_code/services/telemetry/metrics.py +62 -0
- iac_code/services/telemetry/names.py +199 -0
- iac_code/services/telemetry/sanitize.py +88 -0
- iac_code/services/telemetry/sink.py +67 -0
- iac_code/services/telemetry/tracing.py +38 -0
- iac_code/services/telemetry/types.py +13 -0
- iac_code/services/token_budget.py +54 -0
- iac_code/services/token_counter.py +76 -0
- iac_code/skills/__init__.py +1 -0
- iac_code/skills/bundled/__init__.py +94 -0
- iac_code/skills/bundled/iac_aliyun/SKILL.md +192 -0
- iac_code/skills/bundled/iac_aliyun/__init__.py +16 -0
- iac_code/skills/bundled/iac_aliyun/references/cloud-products/ecs.md +167 -0
- iac_code/skills/bundled/iac_aliyun/references/cloud-products/oss.md +69 -0
- iac_code/skills/bundled/iac_aliyun/references/cloud-products/rds.md +95 -0
- iac_code/skills/bundled/iac_aliyun/references/cloud-products/redis.md +100 -0
- iac_code/skills/bundled/iac_aliyun/references/cloud-products/slb.md +60 -0
- iac_code/skills/bundled/iac_aliyun/references/cloud-products/vpc.md +54 -0
- iac_code/skills/bundled/iac_aliyun/references/ros-template.md +155 -0
- iac_code/skills/bundled/iac_aliyun/references/template-parameters.md +206 -0
- iac_code/skills/bundled/iac_aliyun/references/terraform-template.md +101 -0
- iac_code/skills/bundled/iac_aliyun/scripts/tf2ros.py +77 -0
- iac_code/skills/bundled/simplify.py +28 -0
- iac_code/skills/discovery.py +136 -0
- iac_code/skills/frontmatter.py +119 -0
- iac_code/skills/listing.py +92 -0
- iac_code/skills/loader.py +42 -0
- iac_code/skills/processor.py +81 -0
- iac_code/skills/renderer.py +157 -0
- iac_code/skills/skill_definition.py +82 -0
- iac_code/skills/skill_tool.py +261 -0
- iac_code/state/__init__.py +5 -0
- iac_code/state/app_state.py +122 -0
- iac_code/tasks/__init__.py +1 -0
- iac_code/tasks/notification_queue.py +28 -0
- iac_code/tasks/task_state.py +66 -0
- iac_code/tasks/task_tools.py +114 -0
- iac_code/tools/__init__.py +8 -0
- iac_code/tools/base.py +226 -0
- iac_code/tools/bash.py +133 -0
- iac_code/tools/cloud/__init__.py +0 -0
- iac_code/tools/cloud/aliyun/__init__.py +0 -0
- iac_code/tools/cloud/aliyun/aliyun_api.py +510 -0
- iac_code/tools/cloud/aliyun/aliyun_doc_search.py +145 -0
- iac_code/tools/cloud/aliyun/endpoints.yml +343 -0
- iac_code/tools/cloud/aliyun/ros_client.py +56 -0
- iac_code/tools/cloud/aliyun/ros_stack.py +633 -0
- iac_code/tools/cloud/aliyun/ros_stack_instances.py +247 -0
- iac_code/tools/cloud/base_api.py +162 -0
- iac_code/tools/cloud/base_stack.py +242 -0
- iac_code/tools/cloud/registry.py +20 -0
- iac_code/tools/cloud/types.py +105 -0
- iac_code/tools/edit_file.py +121 -0
- iac_code/tools/glob.py +103 -0
- iac_code/tools/grep.py +254 -0
- iac_code/tools/list_files.py +104 -0
- iac_code/tools/read_file.py +127 -0
- iac_code/tools/result_storage.py +39 -0
- iac_code/tools/tool_executor.py +165 -0
- iac_code/tools/web_fetch.py +177 -0
- iac_code/tools/write_file.py +88 -0
- iac_code/types/__init__.py +40 -0
- iac_code/types/permissions.py +26 -0
- iac_code/types/skill_source.py +11 -0
- iac_code/types/stream_events.py +227 -0
- iac_code/ui/__init__.py +5 -0
- iac_code/ui/banner.py +110 -0
- iac_code/ui/components/__init__.py +0 -0
- iac_code/ui/components/dialog.py +142 -0
- iac_code/ui/components/divider.py +20 -0
- iac_code/ui/components/fuzzy_picker.py +308 -0
- iac_code/ui/components/progress_bar.py +54 -0
- iac_code/ui/components/search_box.py +165 -0
- iac_code/ui/components/select.py +319 -0
- iac_code/ui/components/status_icon.py +42 -0
- iac_code/ui/components/tabs.py +128 -0
- iac_code/ui/core/__init__.py +0 -0
- iac_code/ui/core/in_place_render.py +129 -0
- iac_code/ui/core/input_history.py +118 -0
- iac_code/ui/core/key_event.py +41 -0
- iac_code/ui/core/prompt_input.py +507 -0
- iac_code/ui/core/raw_input.py +302 -0
- iac_code/ui/core/screen.py +80 -0
- iac_code/ui/dialogs/__init__.py +0 -0
- iac_code/ui/dialogs/global_search.py +178 -0
- iac_code/ui/dialogs/history_search.py +100 -0
- iac_code/ui/dialogs/model_picker.py +280 -0
- iac_code/ui/dialogs/quick_open.py +108 -0
- iac_code/ui/dialogs/resume_picker.py +749 -0
- iac_code/ui/keybindings/__init__.py +0 -0
- iac_code/ui/keybindings/manager.py +124 -0
- iac_code/ui/renderer.py +1535 -0
- iac_code/ui/repl.py +772 -0
- iac_code/ui/spinner.py +112 -0
- iac_code/ui/suggestions/__init__.py +0 -0
- iac_code/ui/suggestions/aggregator.py +171 -0
- iac_code/ui/suggestions/command_provider.py +43 -0
- iac_code/ui/suggestions/directory_provider.py +95 -0
- iac_code/ui/suggestions/file_provider.py +121 -0
- iac_code/ui/suggestions/shell_history_provider.py +108 -0
- iac_code/ui/suggestions/token_extractor.py +77 -0
- iac_code/ui/suggestions/types.py +45 -0
- iac_code/ui/transcript_view.py +199 -0
- iac_code/utils/__init__.py +0 -0
- iac_code/utils/background_housekeeping.py +53 -0
- iac_code/utils/cleanup.py +68 -0
- iac_code/utils/json_utils.py +60 -0
- iac_code/utils/log.py +150 -0
- iac_code/utils/project_paths.py +74 -0
- iac_code/utils/tool_input_parser.py +62 -0
- iac_code-0.1.0.dist-info/LICENSE +201 -0
- iac_code-0.1.0.dist-info/METADATA +64 -0
- iac_code-0.1.0.dist-info/RECORD +184 -0
- iac_code-0.1.0.dist-info/WHEEL +5 -0
- iac_code-0.1.0.dist-info/entry_points.txt +2 -0
- iac_code-0.1.0.dist-info/top_level.txt +1 -0
iac_code/acp/tools.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from contextlib import suppress
|
|
5
|
+
|
|
6
|
+
import acp
|
|
7
|
+
|
|
8
|
+
from iac_code.tools.base import Tool, ToolContext, ToolResult
|
|
9
|
+
|
|
10
|
+
TERMINAL_TIMEOUT = 300 # 5 minutes default timeout
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ACPTerminalBashTool(Tool):
|
|
14
|
+
def __init__(self, original: Tool, conn: acp.Client, session_id: str) -> None:
|
|
15
|
+
self._original = original
|
|
16
|
+
self._conn = conn
|
|
17
|
+
self._session_id = session_id
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def name(self) -> str:
|
|
21
|
+
return self._original.name
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def description(self) -> str:
|
|
25
|
+
return self._original.description
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def input_schema(self) -> dict:
|
|
29
|
+
return self._original.input_schema
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def timeout(self) -> float | None:
|
|
33
|
+
return self._original.timeout
|
|
34
|
+
|
|
35
|
+
def is_read_only(self, input: dict | None = None) -> bool:
|
|
36
|
+
return self._original.is_read_only(input)
|
|
37
|
+
|
|
38
|
+
def is_destructive(self, input: dict | None = None) -> bool:
|
|
39
|
+
return self._original.is_destructive(input)
|
|
40
|
+
|
|
41
|
+
async def check_permissions(self, input: dict, context: dict | None = None):
|
|
42
|
+
return await self._original.check_permissions(input, context)
|
|
43
|
+
|
|
44
|
+
async def execute(self, *, tool_input: dict, context: ToolContext) -> ToolResult:
|
|
45
|
+
command = tool_input.get("command")
|
|
46
|
+
if not command:
|
|
47
|
+
return ToolResult.error("Bash command is required.")
|
|
48
|
+
|
|
49
|
+
timeout = tool_input.get("timeout", TERMINAL_TIMEOUT)
|
|
50
|
+
terminal_id: str | None = None
|
|
51
|
+
try:
|
|
52
|
+
created = await self._conn.create_terminal(
|
|
53
|
+
command=command,
|
|
54
|
+
session_id=self._session_id,
|
|
55
|
+
cwd=context.cwd,
|
|
56
|
+
output_byte_limit=50_000,
|
|
57
|
+
)
|
|
58
|
+
terminal_id = created.terminal_id
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
async with asyncio.timeout(timeout):
|
|
62
|
+
exit_status = await self._conn.wait_for_terminal_exit(
|
|
63
|
+
session_id=self._session_id,
|
|
64
|
+
terminal_id=terminal_id,
|
|
65
|
+
)
|
|
66
|
+
output = await self._conn.terminal_output(
|
|
67
|
+
session_id=self._session_id,
|
|
68
|
+
terminal_id=terminal_id,
|
|
69
|
+
)
|
|
70
|
+
except TimeoutError:
|
|
71
|
+
with suppress(Exception):
|
|
72
|
+
await self._conn.kill_terminal(session_id=self._session_id, terminal_id=terminal_id)
|
|
73
|
+
return ToolResult.error(f"Command timed out after {timeout} seconds")
|
|
74
|
+
|
|
75
|
+
if output.exit_status:
|
|
76
|
+
exit_status = output.exit_status
|
|
77
|
+
|
|
78
|
+
# TODO: Push TerminalToolCallContent via session_update for streaming output.
|
|
79
|
+
# Currently Tool.execute only returns ToolResult; streaming will be handled
|
|
80
|
+
# at the session layer in a future phase.
|
|
81
|
+
|
|
82
|
+
if exit_status.signal:
|
|
83
|
+
return ToolResult.error(f"Command terminated by signal: {exit_status.signal}\n{output.output}")
|
|
84
|
+
if exit_status.exit_code not in (None, 0):
|
|
85
|
+
return ToolResult.error(f"Command failed with exit code {exit_status.exit_code}\n{output.output}")
|
|
86
|
+
return ToolResult.success(output.output)
|
|
87
|
+
except asyncio.CancelledError:
|
|
88
|
+
if terminal_id is not None:
|
|
89
|
+
with suppress(Exception):
|
|
90
|
+
await self._conn.kill_terminal(session_id=self._session_id, terminal_id=terminal_id)
|
|
91
|
+
with suppress(Exception):
|
|
92
|
+
await self._conn.release_terminal(session_id=self._session_id, terminal_id=terminal_id)
|
|
93
|
+
raise
|
|
94
|
+
finally:
|
|
95
|
+
if terminal_id is not None:
|
|
96
|
+
with suppress(Exception):
|
|
97
|
+
await self._conn.release_terminal(session_id=self._session_id, terminal_id=terminal_id)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def replace_bash_with_acp_terminal(tool_registry, client_capabilities, conn: acp.Client, session_id: str) -> set[str]:
|
|
101
|
+
"""Replace the local bash tool with an ACP terminal-backed tool.
|
|
102
|
+
|
|
103
|
+
Returns the set of tool names that were replaced (whose output is
|
|
104
|
+
streamed via the ACP terminal and should be marked as already displayed).
|
|
105
|
+
"""
|
|
106
|
+
if not client_capabilities or not client_capabilities.terminal:
|
|
107
|
+
return set()
|
|
108
|
+
bash = tool_registry.get("bash")
|
|
109
|
+
if bash is None:
|
|
110
|
+
return set()
|
|
111
|
+
tool_registry.register(ACPTerminalBashTool(bash, conn, session_id))
|
|
112
|
+
return {"bash"}
|
iac_code/acp/types.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import acp
|
|
4
|
+
|
|
5
|
+
ACPContentBlock = (
|
|
6
|
+
acp.schema.TextContentBlock
|
|
7
|
+
| acp.schema.ImageContentBlock
|
|
8
|
+
| acp.schema.AudioContentBlock
|
|
9
|
+
| acp.schema.ResourceContentBlock
|
|
10
|
+
| acp.schema.EmbeddedResourceContentBlock
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
MCPServer = acp.schema.HttpMcpServer | acp.schema.SseMcpServer | acp.schema.McpServerStdio
|
iac_code/acp/version.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True)
|
|
7
|
+
class ACPVersionSpec:
|
|
8
|
+
protocol_version: int
|
|
9
|
+
sdk_version: str
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
CURRENT_VERSION = ACPVersionSpec(protocol_version=1, sdk_version="0.9.0")
|
|
13
|
+
SUPPORTED_VERSIONS: dict[int, ACPVersionSpec] = {1: CURRENT_VERSION}
|
|
14
|
+
MIN_PROTOCOL_VERSION = 1
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def negotiate_version(client_protocol_version: int) -> ACPVersionSpec:
|
|
18
|
+
if client_protocol_version < MIN_PROTOCOL_VERSION:
|
|
19
|
+
return CURRENT_VERSION
|
|
20
|
+
|
|
21
|
+
best: ACPVersionSpec | None = None
|
|
22
|
+
for version, spec in SUPPORTED_VERSIONS.items():
|
|
23
|
+
if version <= client_protocol_version and (best is None or version > best.protocol_version):
|
|
24
|
+
best = spec
|
|
25
|
+
|
|
26
|
+
return best if best is not None else CURRENT_VERSION
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from iac_code.agent.message import (
|
|
2
|
+
ContentBlock,
|
|
3
|
+
Conversation,
|
|
4
|
+
Message,
|
|
5
|
+
TextBlock,
|
|
6
|
+
ToolResultBlock,
|
|
7
|
+
ToolUseBlock,
|
|
8
|
+
)
|
|
9
|
+
from iac_code.agent.system_prompt import build_system_prompt
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"ContentBlock",
|
|
13
|
+
"Conversation",
|
|
14
|
+
"Message",
|
|
15
|
+
"TextBlock",
|
|
16
|
+
"ToolResultBlock",
|
|
17
|
+
"ToolUseBlock",
|
|
18
|
+
"build_system_prompt",
|
|
19
|
+
]
|