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
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""Output format writers for non-interactive (headless) mode.
|
|
2
|
+
|
|
3
|
+
Each writer consumes StreamEvents and writes formatted output to a file-like stream.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import dataclasses
|
|
9
|
+
import json
|
|
10
|
+
import sys
|
|
11
|
+
from enum import Enum
|
|
12
|
+
from typing import IO, Any
|
|
13
|
+
|
|
14
|
+
from iac_code.types.stream_events import (
|
|
15
|
+
ErrorEvent,
|
|
16
|
+
MessageEndEvent,
|
|
17
|
+
StreamEvent,
|
|
18
|
+
TextDeltaEvent,
|
|
19
|
+
ToolResultEvent,
|
|
20
|
+
ToolUseEndEvent,
|
|
21
|
+
ToolUseStartEvent,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class OutputFormat(str, Enum):
|
|
26
|
+
"""Supported output formats for non-interactive mode."""
|
|
27
|
+
|
|
28
|
+
TEXT = "text"
|
|
29
|
+
JSON = "json"
|
|
30
|
+
STREAM_JSON = "stream-json"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TextWriter:
|
|
34
|
+
"""Writes only assistant text content to the output stream.
|
|
35
|
+
|
|
36
|
+
Tool calls and other events are silently consumed.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, stream: IO[str] | None = None) -> None:
|
|
40
|
+
self._stream = stream or sys.stdout
|
|
41
|
+
self._has_output = False
|
|
42
|
+
|
|
43
|
+
def handle(self, event: StreamEvent) -> None:
|
|
44
|
+
if isinstance(event, TextDeltaEvent):
|
|
45
|
+
self._stream.write(event.text)
|
|
46
|
+
self._stream.flush()
|
|
47
|
+
self._has_output = True
|
|
48
|
+
|
|
49
|
+
def finalize(self) -> None:
|
|
50
|
+
if self._has_output:
|
|
51
|
+
self._stream.write("\n")
|
|
52
|
+
self._stream.flush()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class JsonWriter:
|
|
56
|
+
"""Collects all events and writes a single JSON object on finalize.
|
|
57
|
+
|
|
58
|
+
The output is a JSON object with keys: text, tool_uses, usage, and
|
|
59
|
+
optionally error. usage is null when no MessageEndEvent was seen.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(self, stream: IO[str] | None = None) -> None:
|
|
63
|
+
self._stream = stream or sys.stdout
|
|
64
|
+
self._text_chunks: list[str] = []
|
|
65
|
+
self._tool_uses: dict[str, dict[str, Any]] = {}
|
|
66
|
+
self._usage: dict[str, int] | None = None
|
|
67
|
+
self._error: str | None = None
|
|
68
|
+
|
|
69
|
+
def handle(self, event: StreamEvent) -> None:
|
|
70
|
+
if isinstance(event, TextDeltaEvent):
|
|
71
|
+
self._text_chunks.append(event.text)
|
|
72
|
+
elif isinstance(event, ToolUseStartEvent):
|
|
73
|
+
self._tool_uses.setdefault(event.tool_use_id, {})["name"] = event.name
|
|
74
|
+
elif isinstance(event, ToolUseEndEvent):
|
|
75
|
+
self._tool_uses.setdefault(event.tool_use_id, {})["input"] = event.input
|
|
76
|
+
elif isinstance(event, ToolResultEvent):
|
|
77
|
+
entry = self._tool_uses.setdefault(event.tool_use_id, {})
|
|
78
|
+
entry["result"] = event.result
|
|
79
|
+
entry["is_error"] = event.is_error
|
|
80
|
+
elif isinstance(event, MessageEndEvent):
|
|
81
|
+
self._usage = {
|
|
82
|
+
"input_tokens": event.usage.input_tokens,
|
|
83
|
+
"output_tokens": event.usage.output_tokens,
|
|
84
|
+
}
|
|
85
|
+
elif isinstance(event, ErrorEvent):
|
|
86
|
+
self._error = event.error
|
|
87
|
+
|
|
88
|
+
def finalize(self) -> None:
|
|
89
|
+
result: dict[str, Any] = {
|
|
90
|
+
"text": "".join(self._text_chunks),
|
|
91
|
+
"tool_uses": list(self._tool_uses.values()),
|
|
92
|
+
"usage": self._usage,
|
|
93
|
+
}
|
|
94
|
+
if self._error is not None:
|
|
95
|
+
result["error"] = self._error
|
|
96
|
+
self._stream.write(json.dumps(result, ensure_ascii=False))
|
|
97
|
+
self._stream.write("\n")
|
|
98
|
+
self._stream.flush()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class StreamJsonWriter:
|
|
102
|
+
"""Writes each event as a newline-delimited JSON (NDJSON) line immediately on handle."""
|
|
103
|
+
|
|
104
|
+
def __init__(self, stream: IO[str] | None = None) -> None:
|
|
105
|
+
self._stream = stream or sys.stdout
|
|
106
|
+
|
|
107
|
+
def handle(self, event: StreamEvent) -> None:
|
|
108
|
+
data = dataclasses.asdict(event)
|
|
109
|
+
self._stream.write(json.dumps(data, ensure_ascii=False, default=str))
|
|
110
|
+
self._stream.write("\n")
|
|
111
|
+
self._stream.flush()
|
|
112
|
+
|
|
113
|
+
def finalize(self) -> None:
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def create_writer(fmt: OutputFormat, stream: IO[str] | None = None) -> TextWriter | JsonWriter | StreamJsonWriter:
|
|
118
|
+
"""Create the appropriate writer for the given output format."""
|
|
119
|
+
if fmt == OutputFormat.TEXT:
|
|
120
|
+
return TextWriter(stream)
|
|
121
|
+
if fmt == OutputFormat.JSON:
|
|
122
|
+
return JsonWriter(stream)
|
|
123
|
+
if fmt == OutputFormat.STREAM_JSON:
|
|
124
|
+
return StreamJsonWriter(stream)
|
|
125
|
+
raise ValueError(f"Unknown output format: {fmt}")
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Command module"""
|
|
2
|
+
|
|
3
|
+
from iac_code.commands.auth import auth_command
|
|
4
|
+
from iac_code.commands.clear import clear_command
|
|
5
|
+
from iac_code.commands.compact import compact_command
|
|
6
|
+
from iac_code.commands.debug import debug_command
|
|
7
|
+
from iac_code.commands.effort import effort_command
|
|
8
|
+
from iac_code.commands.exit import exit_command
|
|
9
|
+
from iac_code.commands.help import help_command
|
|
10
|
+
from iac_code.commands.model import model_command
|
|
11
|
+
from iac_code.commands.registry import Command, CommandRegistry, LocalCommand, PromptCommand
|
|
12
|
+
from iac_code.commands.resume import resume_command
|
|
13
|
+
from iac_code.i18n import _
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def create_default_registry() -> CommandRegistry:
|
|
17
|
+
"""Create and register all default commands"""
|
|
18
|
+
registry = CommandRegistry()
|
|
19
|
+
registry.register(
|
|
20
|
+
LocalCommand(
|
|
21
|
+
name="help",
|
|
22
|
+
description=_("Show available commands"),
|
|
23
|
+
handler=help_command,
|
|
24
|
+
aliases=["?"],
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
registry.register(
|
|
28
|
+
LocalCommand(
|
|
29
|
+
name="clear",
|
|
30
|
+
description=_("Clear conversation history"),
|
|
31
|
+
handler=clear_command,
|
|
32
|
+
)
|
|
33
|
+
)
|
|
34
|
+
registry.register(
|
|
35
|
+
LocalCommand(
|
|
36
|
+
name="model",
|
|
37
|
+
description=_("Show or switch model"),
|
|
38
|
+
handler=model_command,
|
|
39
|
+
arg_names=["model_name"],
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
registry.register(
|
|
43
|
+
LocalCommand(
|
|
44
|
+
name="effort",
|
|
45
|
+
description=_("Show or switch thinking effort"),
|
|
46
|
+
handler=effort_command,
|
|
47
|
+
arg_names=["level"],
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
registry.register(
|
|
51
|
+
LocalCommand(
|
|
52
|
+
name="compact",
|
|
53
|
+
description=_("Compact conversation context"),
|
|
54
|
+
handler=compact_command,
|
|
55
|
+
progress_label=_("Compacting conversation"),
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
registry.register(
|
|
59
|
+
LocalCommand(
|
|
60
|
+
name="exit",
|
|
61
|
+
description=_("Exit the application"),
|
|
62
|
+
handler=exit_command,
|
|
63
|
+
aliases=["quit", "q"],
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
registry.register(
|
|
67
|
+
LocalCommand(
|
|
68
|
+
name="auth",
|
|
69
|
+
description=_("Authenticate with LLM provider"),
|
|
70
|
+
handler=auth_command,
|
|
71
|
+
aliases=["login"],
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
registry.register(
|
|
75
|
+
LocalCommand(
|
|
76
|
+
name="debug",
|
|
77
|
+
description=_("Toggle debug logging"),
|
|
78
|
+
handler=debug_command,
|
|
79
|
+
arg_hint="[on|off]",
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
registry.register(
|
|
83
|
+
LocalCommand(
|
|
84
|
+
name="resume",
|
|
85
|
+
description=_("Resume a previous session"),
|
|
86
|
+
handler=resume_command,
|
|
87
|
+
arg_hint=_("[conversation id or search term]"),
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
return registry
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
__all__ = ["Command", "CommandRegistry", "LocalCommand", "PromptCommand", "create_default_registry"]
|