---
name: alibabacloud-ros-agent
description: Use Alibaba Cloud ROS Agent through its StartChat API for remote infrastructure conversations. Trigger when the user explicitly asks for the ROS Agent, its StartChat API, or a remote iac-code conversation through Alibaba Cloud. Supports normal and selling Pipeline conversations, questions, candidate selection, correlated permission approval or denial, and explicit StopChat cancellation. Do not trigger for ordinary Alibaba Cloud infrastructure work that can use the local iac-code Skill, or for unrelated ROS API operations.
---

# Alibaba Cloud ROS Agent

Use the bridge at `scripts/ros_agent.py`. Its default code transport uses the Alibaba Cloud Credentials SDK default credential chain and Tea OpenAPI V3 signing to send ROS RPCs directly and consume StartChat SSE incrementally. The bridge never reads credential environment variables or credential values from Profile files itself. A Profile explicitly pinned by local policy is delegated to the Credentials SDK Profile provider and is exclusive: it never falls back to the default chain or another Profile. Credentials exist only inside the SDK-backed request path and are never accepted as bridge arguments, persisted in job state, or returned. An optional dependency-free transport invokes the ROS CLI plugin's `start-chat` and `stop-chat` commands. Run the bridge with `python3` on macOS/Linux or `py -3` on Windows.

## Required interaction contract

Visible narration is part of completing this workflow, not optional styling. Internal reasoning/thinking, a tool description, raw tool output, and the wording of a user question are not substitutes for a user-visible assistant text block. Keep each update concise—normally one to three sentences in the user's language. An update and the following tool call may be in the same assistant response, so do not pause merely to narrate.

Use these stage gates:

- After loading this Skill and before the first operational tool call, acknowledge the infrastructure task, identify Normal or Pipeline mode, and state the immediate next phase.
- After `check` succeeds and before local prompt preparation or `start`, report that readiness passed and what ROS Agent will work on next. Do not expose commands, Profile details, or opaque IDs.
- Whenever bridge JSON has `presentationRequired: true`, the next assistant response must begin with a user-visible text block before any further tool call. For every `boundaryReached` result, emit every ready-to-display `userUpdates` string—even after earlier Pipeline updates; skipping a repeated stage gate and going directly to Bash is a protocol violation. For `followTimedOut`, show the `heartbeat` without claiming completion. For `turn-completed`, present the authoritative `finalText` and relevant artifacts before starting another action or asking a follow-up question.
- Before asking the user to confirm a deployment, present the proposed architecture as a fenced Mermaid diagram after the deployment summary. The confirmation question must come after the diagram; tool output or an unrendered diagram field does not satisfy this gate. Follow the architecture rules below.
- When input is required, first explain in a separate visible update what has completed, what ROS Agent is waiting for, and why the answer is needed; then ask the question with every returned option intact using an interaction method appropriate to the host. For permissions, include the safe action, target, and `permissionClass`; for `pendingPermissions`, state how many independent Sub Pipeline steps are waiting. End the agent turn without choosing for the user.
- After the user answers a question, selects a candidate, or allows/denies a permission, begin the next assistant response by acknowledging the choice and saying that ROS Agent is resuming, then call `continue` or `respond`. Before sending any later natural-language request such as a change or cleanup through `continue`, similarly state what the same ROS Agent session will do next.
- On completion or failure, present the authoritative result or concise sanitized error immediately. Do not dump raw JSON, event counts, correlation IDs, or the full prior milestone history, and do not repeat already presented progress.

Do not call `TodoWrite`, `Task`, or another planning tool merely to track this managed workflow. The preserved `jobId` and `cursor` are its state; report progress directly to the user instead.

While a Pipeline has `wireState: TASK_STATE_WORKING`, `follow` is the only observation operation. This remains true after `permission-responded` and when a cursor has not advanced. Never invoke or offer `continue` as a retry, poll, nudge, or way to unstick a Pipeline: it sends a real natural-language interrupt. Present a returned heartbeat and keep following; if the bridge reports `state: failed`, present that error rather than inventing a recovery message.

## Prerequisites

The selected credential must be allowed to call `ros:StartChat`. Explicit cancellation additionally requires `ros:StopChat`; it is not required for an ordinary completed conversation. The default code transport requires the packages pinned in `scripts/requirements.txt` to be installed for the Python interpreter that runs the bridge. The Credentials SDK default chain or explicitly pinned Profile provider resolves the effective identity without bridge-level credential parsing. The `aliyun_cli` transport has no Python package dependency. Its local execution mode requires the installed CLI and a ROS plugin that provides `start-chat` and `stop-chat`; its remote execution mode uses the host's same-name `aliyun` command as an externally managed executor. Run the bridge check once before the first StartChat call:

```text
python3 <absolute-bridge-path>/ros_agent.py check
```

The bounded JSON result includes the effective `transport`, `aliyunCLIExecutionMode`, endpoint, Agent modes, Thinking policy, configured Profile policy, effective region when locally available, and only non-secret credential metadata. `cli` and `version` are null when the code transport does not need the CLI. In unpinned code mode, `mode: DefaultCredentialChain` means the Credentials SDK resolved the identity without bridge-level credential parsing. In local CLI mode, `rosPluginReady`, `pluginAutoInstallEnabled`, and `pluginInstallRequired` describe plugin readiness. If and only if `pluginInstallRequired` is true, visibly report that the required ROS CLI plugin is being installed, run exactly `aliyun plugin install --name ros`, and then rerun `check`; never add a version, package URL, mirror, or source override. If the plugin is absent but CLI automatic plugin installation is enabled, `pluginInstallRequired` is false and the first `start-chat` invocation may install it. In remote CLI mode, `check` deliberately does not run CLI management commands or inspect local Profiles/plugins; it reports only the configured forwarded environment names and which names are currently present, never their values.

Use the check result as the sole readiness source. Except for the one local-mode plugin install command directed by `pluginInstallRequired`, never run `aliyun configure`, `aliyun plugin`, or other discovery/management commands, enumerate profiles, or read Alibaba Cloud CLI configuration files yourself. The check deliberately excludes credential values and does not prove that a token is still accepted by ROS; the StartChat response is authoritative for authentication and authorization failures.

The returned `transport` is installation policy, not an Agent choice. In an AgentHub-managed ephemeral runtime, if `check` returns `sdk_not_installed`, use the same Python interpreter to install only the exact bundled dependencies from `scripts/requirements.txt` into that ephemeral runtime, without `sudo` or system changes, and then rerun `check` once. This readiness repair does not authorize a transport change, alternative tooling, or credential access. If installation, the repeated `check`, or any other readiness check fails, report the exact error and stop. Never edit `config.json`, propose or attempt another transport, pass a transport override, or fall back to `aliyun_cli` to bypass the failure. Only the user or installation administrator may change this policy outside the infrastructure task, after which a new `check` is required.

Add `--aliyun-path <path>` to `check` or `start` only when the effective credential path requires native aliyun CLI and it is not on `PATH`; the managed job preserves it for later requests. Use the returned credential source and region without asking the user to choose a Profile. Omit `--profile` unless the user explicitly supplied a Profile and local policy did not pin one; never try to override `aliyunCLIProfile`. Never pass credentials on the command line, put them in prompt files, or expose CLI configuration.

## Optional local policy

The bridge reads an optional `config.json` beside this `SKILL.md`. If it is absent, the transport defaults to `code`, the endpoint defaults to `ros.aliyuncs.com`, both Agent modes are allowed, Thinking is enabled, the Credentials SDK default chain selects the effective identity, and the temporary loopback manager exits 60 seconds after the last SSE worker and manager request become idle. The file accepts these settings:

```json
{
  "transport": "code",
  "endpoint": "127.0.0.1:56124",
  "allowedAgentModes": ["normal", "pipeline"],
  "managerIdleSeconds": 60,
  "enableThinking": true,
  "aliyunCLIProfile": ""
}
```

When `transport` is `aliyun_cli`, add `"aliyunCLIExecutionMode": "local"` or `"remote"`; do not add that field to a `code` transport configuration.

- `transport` accepts exactly `code` or `aliyun_cli`. `code` is the default: it delegates identity resolution to the Credentials SDK default chain unless a Profile is explicitly pinned, in which case the SDK Profile provider owns resolution and refresh. It signs and sends StartChat or StopChat to the configured endpoint while exposing SSE events as they arrive. `aliyun_cli` is the dependency-free path and invokes only the ROS plugin's validated `start-chat` and `stop-chat` operations. SDK imports are lazy and never occur in `aliyun_cli` mode. There is no silent fallback between transports or from a pinned Profile to the default chain.
- `aliyunCLIExecutionMode` accepts exactly `local` or `remote`, defaults to `local`, and is valid only with `transport: "aliyun_cli"`. `local` uses the native local CLI, Profile, and plugin installation. `remote` treats the same-name `aliyun` executable as a host-provided executor whose routing and execution mechanism is outside the bridge contract; the bridge may invoke only `aliyun ros start-chat` and `aliyun ros stop-chat`, never CLI management or another API operation. Remote mode does not read or pass a local Profile, does not infer a local region, rejects `aliyunCLIProfile`, and requires a public `*.aliyuncs.com` endpoint. All prompt and response payloads are passed inline; never pass a file-backed CLI parameter to the remote command.
- `aliyunCLIForwardEnv` is valid only for remote CLI execution and accepts at most 16 unique, non-secret environment variable names. It defaults to `[]`; each remote implementation must list any required names explicitly in `config.json`. Every foreground `start`, `continue`, `respond`, or `cancel` captures current values and replaces stale manager-inherited values for the launched operation. Values are never persisted or returned. The bridge does not prescribe how a remote CLI implementation uses these variables.
- `endpoint` fixes the ROS endpoint for every StartChat and StopChat request in a managed job. A conflicting `--endpoint` is rejected, so do not try to override this local policy. Public endpoints must be `*.aliyuncs.com` hostnames. For local integration tests only, `localhost:<port>` and `127.0.0.1:<port>` are accepted; both transports use HTTPS and skip certificate verification only for those loopback addresses.
- `allowedAgentModes` is a non-empty allowlist containing `normal`, `pipeline`, or both. Do not invoke or suggest a mode excluded by this list.
- `managerIdleSeconds` is an integer from 1 through 86400. It defaults to 60. The countdown starts only when no StartChat SSE worker is running—including a concurrent Sub Pipeline permission-response worker—and is refreshed by each manager request; after exit, any managed command starts a new manager automatically while preserving job state.
- `enableThinking` is a boolean and defaults to `true`. It fixes `EnableThinking` for the whole managed job; do not pass `--no-thinking` or try to override it per request.
- `aliyunCLIProfile` is an empty or exact CLI Profile name and defaults to empty. In code mode, empty uses the Credentials SDK default chain. A non-empty value pins that Profile for code transport or local CLI execution and fails instead of falling back when the Profile is unavailable. It is invalid in remote CLI execution. Do not pass a conflicting `--profile`.

Unknown fields, invalid values, and duplicate modes fail closed. Never edit `config.json` during an infrastructure task or store credentials in it; it is an administrator/user installation policy.

## Managed StartChat workflow

1. Put the complete user request in a UTF-8 prompt file inside the target workspace. Run `start` with the shell process working directory set to that target workspace while invoking the resolved bridge script by its absolute path. Never change into the Skill directory or copy prompt, answer, or permission files there merely to satisfy workspace validation.
2. Start a normal managed job from the target workspace. The bridge uses its process working directory only for local prompt-file isolation; it never sends a workspace or `cwd` field to StartChat:

   ```text
   python3 <absolute-bridge-path>/ros_agent.py start --prompt-file <prompt-file> --mode normal --follow
   ```

   Pass `--region-id` only when the user explicitly supplied a region. Otherwise the bridge uses the first supported region environment variable, then an explicitly pinned Profile region, then `cn-hangzhou`; do not query CLI configuration to fill it. Use `--mode pipeline` only when the user explicitly wants the candidate-architecture, cost-comparison, confirmation, and deployment Pipeline. Thinking is installation policy from `config.json`, not an Agent choice. Forward underspecified infrastructure requirements to ROS Agent as written so its own `ask_user_question` can gather them.
3. Preserve the returned `jobId` and newest `cursor`. A temporary authenticated loopback manager owns the job, and a detached worker keeps the selected StartChat transport open after the outer tool call returns. In the default code transport, each SSE event is projected as it arrives. `--follow` returns at every step start, step completion/failure, input boundary, completed turn, terminal state, or its bounded wait window so the user can see the Pipeline progressing. A result can contain multiple ordered `userUpdates` when events were already queued, and can also contain `inputRequired` or a terminal result; present all updates first, then handle that result without an extra drain-only `follow`.
4. When the result has `boundaryReached: true`, present every `userUpdates` string to the user, then immediately follow from the returned cursor:

   ```text
   python3 <absolute-bridge-path>/ros_agent.py follow --job-id <jobId> --cursor <cursor> --wait-seconds 60
   ```

   Follow waits at most 120 seconds even if a larger value is requested. If it returns `followTimedOut: true`, present its `heartbeat` as a visible status update and call `follow` again with the newest cursor. A timeout never stops the background worker or sends a new StartChat query.
5. For every natural-language follow-up, answer to `ask_user_question`, or `candidate_selection`, write a new prompt file and continue the same job:

   ```text
   python3 <absolute-bridge-path>/ros_agent.py continue --job-id <jobId> --prompt-file <prompt-file> --follow
   ```

   Do not invent a `SessionId`; the job binds the remote session, mode, endpoint, region, Profile, and workspace. When a completed Pipeline returns `normalHandoffReady: true` or `conversationMode: normal`, its next user message is a Normal chat turn reached through this same `continue` command and `jobId`; the bridge intentionally keeps the StartChat mode while the remote A2A context performs the handoff. Never replace that handoff with `start --mode normal`. Do not start a new job merely to continue the same task.
6. Only when the user explicitly asks to stop or cancel the active ROS Agent operation, cancel that same managed job:

   ```text
   python3 <absolute-bridge-path>/ros_agent.py cancel --job-id <jobId>
   ```

   This invokes the ROS `StopChat` OpenAPI through the job's selected transport; it does not send a StartChat query or a natural-language cancellation message. Present the returned status immediately. `Stopped` means cancellation completed, `Stopping` means it was accepted and the existing job should be observed with `follow` from its current cursor, and `NoActiveStream` means there was no active remote stream to stop. Never call `cancel` merely because `follow` timed out, a local tool call was interrupted, or the outer Agent turn ended.

Without a configured endpoint, the bridge defaults to `ros.aliyuncs.com`. Use `--endpoint <ROS endpoint>` only when the user's ROS region or network requires a different endpoint and `config.json` does not fix one. The code transport sends a generic ROS RPC with API version `2019-09-10` and `ACS3-HMAC-SHA256` signing, so it does not depend on generated StartChat metadata. The `aliyun_cli` transport uses the installed/remote ROS plugin's published `start-chat` and `stop-chat` commands and does not bypass plugin validation. Both transports identify every StartChat and StopChat request with the user-agent segment `AlibabaCloud-Agent-Skills/alibabacloud-ros-agent`.

## Architecture before deployment confirmation

Immediately before any create/update deployment confirmation, render one compact `mermaid` `flowchart` showing the resources that would be deployed and their material relationships. This is presentation work by the outer Agent and does not require another StartChat query.

Use only authoritative data already returned for the current plan, in this order:

1. A non-empty `architectureDiagram` returned by ROS Agent.
2. The current ROS/Terraform template artifact. If the result exposes a local artifact `sourcePath` and the returned summary is insufficient, read only that artifact; do not inspect manager state, worker logs, or unrelated files.
3. `finalText`, `deploymentSummary`, candidate details, and other bounded result fields.

For Normal mode, derive the diagram from declared resources and explicit template references or dependencies. For Pipeline mode, render the selected candidate's returned diagram and ensure it still matches the plan being confirmed. Label nodes with user-meaningful resource types or names, group network containment when explicit, and show only relationships supported by the source. Use distinct Mermaid IDs for containers and resource nodes. Keep cloud scopes accurate: an Alibaba Cloud VPC is regional, while a VSwitch belongs to a zone, so put the VSwitch inside the VPC and include its zone in the VSwitch label rather than placing the VPC inside a zone. Collapse large repeated groups to keep the diagram readable. Never invent resources, connections, public exposure, zones, or dependencies. If relationships are unavailable, show a resource inventory diagram without speculative edges and briefly state that the returned plan did not describe the missing relationships.

Present the deployment summary, fenced Mermaid block, and confirmation question in that order. Do not ask for confirmation first and add the diagram afterward. A later permission pro