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.
Files changed (184) hide show
  1. iac_code/__init__.py +2 -0
  2. iac_code/acp/__init__.py +97 -0
  3. iac_code/acp/convert.py +423 -0
  4. iac_code/acp/http_sse.py +448 -0
  5. iac_code/acp/mcp.py +54 -0
  6. iac_code/acp/metrics.py +71 -0
  7. iac_code/acp/server.py +662 -0
  8. iac_code/acp/session.py +446 -0
  9. iac_code/acp/slash_registry.py +125 -0
  10. iac_code/acp/state.py +99 -0
  11. iac_code/acp/tools.py +112 -0
  12. iac_code/acp/types.py +13 -0
  13. iac_code/acp/version.py +26 -0
  14. iac_code/agent/__init__.py +19 -0
  15. iac_code/agent/agent_loop.py +640 -0
  16. iac_code/agent/agent_tool.py +269 -0
  17. iac_code/agent/agent_types.py +87 -0
  18. iac_code/agent/message.py +153 -0
  19. iac_code/agent/system_prompt.py +313 -0
  20. iac_code/cli/__init__.py +3 -0
  21. iac_code/cli/headless.py +114 -0
  22. iac_code/cli/main.py +246 -0
  23. iac_code/cli/output_formats.py +125 -0
  24. iac_code/commands/__init__.py +93 -0
  25. iac_code/commands/auth.py +1055 -0
  26. iac_code/commands/clear.py +34 -0
  27. iac_code/commands/compact.py +43 -0
  28. iac_code/commands/debug.py +45 -0
  29. iac_code/commands/effort.py +116 -0
  30. iac_code/commands/exit.py +10 -0
  31. iac_code/commands/help.py +49 -0
  32. iac_code/commands/model.py +130 -0
  33. iac_code/commands/registry.py +245 -0
  34. iac_code/commands/resume.py +49 -0
  35. iac_code/commands/tasks.py +41 -0
  36. iac_code/config.py +304 -0
  37. iac_code/i18n/__init__.py +141 -0
  38. iac_code/i18n/locales/zh/LC_MESSAGES/messages.po +1355 -0
  39. iac_code/memory/__init__.py +1 -0
  40. iac_code/memory/memory_manager.py +92 -0
  41. iac_code/memory/memory_tools.py +88 -0
  42. iac_code/providers/__init__.py +1 -0
  43. iac_code/providers/anthropic_provider.py +284 -0
  44. iac_code/providers/base.py +128 -0
  45. iac_code/providers/dashscope_provider.py +47 -0
  46. iac_code/providers/deepseek_provider.py +36 -0
  47. iac_code/providers/manager.py +399 -0
  48. iac_code/providers/openai_provider.py +344 -0
  49. iac_code/providers/retry.py +58 -0
  50. iac_code/providers/stream_watchdog.py +47 -0
  51. iac_code/providers/thinking.py +164 -0
  52. iac_code/services/__init__.py +1 -0
  53. iac_code/services/agent_factory.py +127 -0
  54. iac_code/services/cloud_credentials.py +22 -0
  55. iac_code/services/context_manager.py +221 -0
  56. iac_code/services/providers/__init__.py +1 -0
  57. iac_code/services/providers/aliyun.py +232 -0
  58. iac_code/services/session_index.py +281 -0
  59. iac_code/services/session_storage.py +245 -0
  60. iac_code/services/telemetry/__init__.py +66 -0
  61. iac_code/services/telemetry/attributes.py +84 -0
  62. iac_code/services/telemetry/client.py +330 -0
  63. iac_code/services/telemetry/config.py +76 -0
  64. iac_code/services/telemetry/constants.py +75 -0
  65. iac_code/services/telemetry/content_serializer.py +124 -0
  66. iac_code/services/telemetry/events.py +42 -0
  67. iac_code/services/telemetry/fallback.py +59 -0
  68. iac_code/services/telemetry/identity.py +73 -0
  69. iac_code/services/telemetry/metrics.py +62 -0
  70. iac_code/services/telemetry/names.py +199 -0
  71. iac_code/services/telemetry/sanitize.py +88 -0
  72. iac_code/services/telemetry/sink.py +67 -0
  73. iac_code/services/telemetry/tracing.py +38 -0
  74. iac_code/services/telemetry/types.py +13 -0
  75. iac_code/services/token_budget.py +54 -0
  76. iac_code/services/token_counter.py +76 -0
  77. iac_code/skills/__init__.py +1 -0
  78. iac_code/skills/bundled/__init__.py +94 -0
  79. iac_code/skills/bundled/iac_aliyun/SKILL.md +192 -0
  80. iac_code/skills/bundled/iac_aliyun/__init__.py +16 -0
  81. iac_code/skills/bundled/iac_aliyun/references/cloud-products/ecs.md +167 -0
  82. iac_code/skills/bundled/iac_aliyun/references/cloud-products/oss.md +69 -0
  83. iac_code/skills/bundled/iac_aliyun/references/cloud-products/rds.md +95 -0
  84. iac_code/skills/bundled/iac_aliyun/references/cloud-products/redis.md +100 -0
  85. iac_code/skills/bundled/iac_aliyun/references/cloud-products/slb.md +60 -0
  86. iac_code/skills/bundled/iac_aliyun/references/cloud-products/vpc.md +54 -0
  87. iac_code/skills/bundled/iac_aliyun/references/ros-template.md +155 -0
  88. iac_code/skills/bundled/iac_aliyun/references/template-parameters.md +206 -0
  89. iac_code/skills/bundled/iac_aliyun/references/terraform-template.md +101 -0
  90. iac_code/skills/bundled/iac_aliyun/scripts/tf2ros.py +77 -0
  91. iac_code/skills/bundled/simplify.py +28 -0
  92. iac_code/skills/discovery.py +136 -0
  93. iac_code/skills/frontmatter.py +119 -0
  94. iac_code/skills/listing.py +92 -0
  95. iac_code/skills/loader.py +42 -0
  96. iac_code/skills/processor.py +81 -0
  97. iac_code/skills/renderer.py +157 -0
  98. iac_code/skills/skill_definition.py +82 -0
  99. iac_code/skills/skill_tool.py +261 -0
  100. iac_code/state/__init__.py +5 -0
  101. iac_code/state/app_state.py +122 -0
  102. iac_code/tasks/__init__.py +1 -0
  103. iac_code/tasks/notification_queue.py +28 -0
  104. iac_code/tasks/task_state.py +66 -0
  105. iac_code/tasks/task_tools.py +114 -0
  106. iac_code/tools/__init__.py +8 -0
  107. iac_code/tools/base.py +226 -0
  108. iac_code/tools/bash.py +133 -0
  109. iac_code/tools/cloud/__init__.py +0 -0
  110. iac_code/tools/cloud/aliyun/__init__.py +0 -0
  111. iac_code/tools/cloud/aliyun/aliyun_api.py +510 -0
  112. iac_code/tools/cloud/aliyun/aliyun_doc_search.py +145 -0
  113. iac_code/tools/cloud/aliyun/endpoints.yml +343 -0
  114. iac_code/tools/cloud/aliyun/ros_client.py +56 -0
  115. iac_code/tools/cloud/aliyun/ros_stack.py +633 -0
  116. iac_code/tools/cloud/aliyun/ros_stack_instances.py +247 -0
  117. iac_code/tools/cloud/base_api.py +162 -0
  118. iac_code/tools/cloud/base_stack.py +242 -0
  119. iac_code/tools/cloud/registry.py +20 -0
  120. iac_code/tools/cloud/types.py +105 -0
  121. iac_code/tools/edit_file.py +121 -0
  122. iac_code/tools/glob.py +103 -0
  123. iac_code/tools/grep.py +254 -0
  124. iac_code/tools/list_files.py +104 -0
  125. iac_code/tools/read_file.py +127 -0
  126. iac_code/tools/result_storage.py +39 -0
  127. iac_code/tools/tool_executor.py +165 -0
  128. iac_code/tools/web_fetch.py +177 -0
  129. iac_code/tools/write_file.py +88 -0
  130. iac_code/types/__init__.py +40 -0
  131. iac_code/types/permissions.py +26 -0
  132. iac_code/types/skill_source.py +11 -0
  133. iac_code/types/stream_events.py +227 -0
  134. iac_code/ui/__init__.py +5 -0
  135. iac_code/ui/banner.py +110 -0
  136. iac_code/ui/components/__init__.py +0 -0
  137. iac_code/ui/components/dialog.py +142 -0
  138. iac_code/ui/components/divider.py +20 -0
  139. iac_code/ui/components/fuzzy_picker.py +308 -0
  140. iac_code/ui/components/progress_bar.py +54 -0
  141. iac_code/ui/components/search_box.py +165 -0
  142. iac_code/ui/components/select.py +319 -0
  143. iac_code/ui/components/status_icon.py +42 -0
  144. iac_code/ui/components/tabs.py +128 -0
  145. iac_code/ui/core/__init__.py +0 -0
  146. iac_code/ui/core/in_place_render.py +129 -0
  147. iac_code/ui/core/input_history.py +118 -0
  148. iac_code/ui/core/key_event.py +41 -0
  149. iac_code/ui/core/prompt_input.py +507 -0
  150. iac_code/ui/core/raw_input.py +302 -0
  151. iac_code/ui/core/screen.py +80 -0
  152. iac_code/ui/dialogs/__init__.py +0 -0
  153. iac_code/ui/dialogs/global_search.py +178 -0
  154. iac_code/ui/dialogs/history_search.py +100 -0
  155. iac_code/ui/dialogs/model_picker.py +280 -0
  156. iac_code/ui/dialogs/quick_open.py +108 -0
  157. iac_code/ui/dialogs/resume_picker.py +749 -0
  158. iac_code/ui/keybindings/__init__.py +0 -0
  159. iac_code/ui/keybindings/manager.py +124 -0
  160. iac_code/ui/renderer.py +1535 -0
  161. iac_code/ui/repl.py +772 -0
  162. iac_code/ui/spinner.py +112 -0
  163. iac_code/ui/suggestions/__init__.py +0 -0
  164. iac_code/ui/suggestions/aggregator.py +171 -0
  165. iac_code/ui/suggestions/command_provider.py +43 -0
  166. iac_code/ui/suggestions/directory_provider.py +95 -0
  167. iac_code/ui/suggestions/file_provider.py +121 -0
  168. iac_code/ui/suggestions/shell_history_provider.py +108 -0
  169. iac_code/ui/suggestions/token_extractor.py +77 -0
  170. iac_code/ui/suggestions/types.py +45 -0
  171. iac_code/ui/transcript_view.py +199 -0
  172. iac_code/utils/__init__.py +0 -0
  173. iac_code/utils/background_housekeeping.py +53 -0
  174. iac_code/utils/cleanup.py +68 -0
  175. iac_code/utils/json_utils.py +60 -0
  176. iac_code/utils/log.py +150 -0
  177. iac_code/utils/project_paths.py +74 -0
  178. iac_code/utils/tool_input_parser.py +62 -0
  179. iac_code-0.1.0.dist-info/LICENSE +201 -0
  180. iac_code-0.1.0.dist-info/METADATA +64 -0
  181. iac_code-0.1.0.dist-info/RECORD +184 -0
  182. iac_code-0.1.0.dist-info/WHEEL +5 -0
  183. iac_code-0.1.0.dist-info/entry_points.txt +2 -0
  184. 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"]