Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ src/iac_code/tools/cloud/aliyun/data/** text eol=lf
tests/tools/cloud/aliyun/fixtures/** text eol=lf
# Pipeline definitions, prompts, and bundled skills are byte-validated release resources.
src/iac_code/pipeline/selling_solution_first/** text eol=lf
src/iac_code/web/static/js/vendor/ore-resource-selector.min.js text eol=lf
src/iac_code/web/static/js/vendor/mermaid.min.js -whitespace
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ Prefer using `uv` and existing Makefile targets. When adding new dependencies, u
- `providers/` — LLM provider adapters.
- `services/` — session, context, credentials, capabilities, permissions, telemetry, and other business services.
- `services/configuration_readiness.py` — non-secret readiness report (LLM + Alibaba Cloud credential completeness) for runtimes that embed iac-code.
- Cloud resource selection:
- `resource_selector/` — selector profiles and capabilities, the allowlisted query/response-projection layer, parameter/result validation, and the model-facing `resolve_cloud_resource_selector` and `select_cloud_resource` tools. This feature is limited to selecting one cloud resource or one value derived from a selected resource.
- The selector tools use the same effective Alibaba Cloud credential decision as `aliyun_api`. Web and Desktop use the normal local credential chain. A2A gives request/session credentials priority and otherwise falls back to local configuration, environment variables, and Alibaba Cloud CLI credentials. If no valid effective credential exists, neither selector tool is registered.
- A2A additionally requires `IAC_CODE_A2A_RESOURCE_SELECTOR_ENABLED` and a client resource-selector capability with the matching loaded `profileHash`. Safe Mode keeps both selector tools in its allowlist, but does not bypass the server flag, client capability, profile hash, or credential gate.
- iac-code must not contain ORE TypeScript, TSX, or CSS source. It may contain only the obfuscated browser bundle, its manifest, and third-party notices. When updating the bundle, also update the manifest/hash, contract fixtures, E2E cases, and the frontend cache-busting token and tests.
- Orchestration and integration protocols:
- `pipeline/` — multi-step IaC pipeline engine (`engine/`) and the selling flow (`selling/`: candidate generation, cost estimation, and `ros_deploy` deployment orchestration). Selling-flow steps support per-surface `surface_overrides` in `pipeline.yaml` (prompt file, injected tools, conclusion schema) — for example the `a2a` and `a2a_rich` variants of `confirm_and_select`; keep rich candidate presentation scoped to Skill/A2A surfaces so REPL/Web behavior stays unchanged.
- `a2a/` — A2A 1.0 server and client with multiple transports (`transports/`: gRPC, stdio, unix socket, Redis streams), plus input-required permission coordination (`input_required.py`) and request-scoped overrides such as the caller's preferred language (`runtime_overrides.py`).
Expand All @@ -76,6 +81,7 @@ Prefer using `uv` and existing Makefile targets. When adding new dependencies, u
- When testing environment variables and credential reading, use `tmp_path`, `patch.dict`, or mocks to isolate state.
- For small changes, run at least the relevant tests; after changes to shared logic, CLI, providers, credentials, or tool execution paths, run `make test` and `make lint` if necessary.
- Tests must pass across the full Python matrix (3.10–3.14). Keep code cross-platform: CI also runs on Windows, so watch for path-separator assumptions, binary-vs-text file I/O, `expanduser` reading `USERPROFILE` on Windows, and subprocess encoding (decode Node/other subprocess output with `encoding="utf-8"`).
- `tests/resource_selector/` contains offline selector contracts and must not require network access or real cloud credentials. `tests/resource_selector_live/` is reserved for explicit, read-only real-cloud checks marked `resource_selector_live`; ordinary offline test runs must exclude them.

## Desktop Development

Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ version = {attr = "iac_code.__version__"}
"**/*.svg",
"**/*.LICENSE",
"**/*.NOTICE",
"**/*THIRD_PARTY_NOTICES",
"**/*.rego",
"**/*.mo",
"**/*.po",
Expand Down Expand Up @@ -155,6 +156,7 @@ default = true
timeout = 30
markers = [
"integration: process-level integration tests that use local services only",
"resource_selector_live: explicit read-only Alibaba Cloud selector API contract smoke tests",
]

[tool.coverage.run]
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"**/*.svg",
"**/*.LICENSE",
"**/*.NOTICE",
"**/*THIRD_PARTY_NOTICES",
"**/*.mo",
"**/*.po",
],
Expand Down
22 changes: 22 additions & 0 deletions src/iac_code/a2a/agent_card.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import os
from typing import Any

from a2a.server.request_handlers.response_helpers import agent_card_to_dict
Expand Down Expand Up @@ -29,6 +30,11 @@
from iac_code.a2a.signing import sign_agent_card_dict
from iac_code.i18n import _
from iac_code.pipeline.config import RunMode, get_run_mode
from iac_code.resource_selector.capability import (
A2A_RESOURCE_SELECTOR_ENV,
RESOURCE_SELECTOR_EXTENSION_URI,
env_enabled,
)

IAC_CODE_ARTIFACT_METADATA_EXTENSION_URI = "urn:iac-code:a2a:artifact-metadata:v1"
IAC_CODE_EXECUTION_CONTROL_EXTENSION_URI = "urn:iac-code:a2a:execution-control:v1"
Expand Down Expand Up @@ -169,6 +175,22 @@ def build_agent_card(
required=False,
)
)
if env_enabled(os.environ.get(A2A_RESOURCE_SELECTOR_ENV)):
resource_selector_extension = AgentExtension(
uri=RESOURCE_SELECTOR_EXTENSION_URI,
description="Select one Alibaba Cloud resource or one derived value through a compatible ROS frontend.",
required=False,
)
ParseDict(
{
"schemaVersion": 1,
"singleSelection": True,
"derivedValue": True,
"queryMode": "ros_api_json",
},
resource_selector_extension.params,
)
card.capabilities.extensions.append(resource_selector_extension)
has_http_extension_surface = any(
interface.url.startswith(("http://", "https://"))
and interface.protocol_binding.upper() in {"JSONRPC", "HTTP+JSON"}
Expand Down
Loading
Loading