Skip to content

Commit 75cfcf5

Browse files
authored
Merge pull request #332 from aliyun/codex/fix-a2a-normal-permission-recovery
feat(skill): default iac-code pipeline to solution-first
2 parents f283164 + 33e4485 commit 75cfcf5

9 files changed

Lines changed: 1454 additions & 79 deletions

File tree

‎skills/iac-code/SKILL.md‎

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Treat a bridge error returned before job creation as the authoritative outcome f
2929
```json
3030
{
3131
"channel": "codex",
32+
"pipelineName": "selling_solution_first",
3233
"permissionWaitPolicy": {
3334
"residentTimeoutSeconds": null,
3435
"subPipelineTimeoutSeconds": null,
@@ -37,10 +38,10 @@ Treat a bridge error returned before job creation as the authoritative outcome f
3738
}
3839
```
3940

40-
`channel` stores only the channel identifier; the bridge adds the `skill/` prefix before sending it to iac-code. `permissionWaitPolicy` applies only to the temporary A2A server owned by this Skill: `null` timeouts mean unlimited waits, positive finite values set resident/Sub Pipeline limits, and grace is a non-negative finite value. Finite values cannot exceed 10 years; use `null` instead of an arbitrarily large number for an unlimited resident or Sub Pipeline wait. The bridge validates and converts this object into server configuration; it never sends the policy through A2A message metadata. Missing fields use the defaults shown above. The bridge rejects unknown configuration fields. If the file or a field is absent, no corresponding override is applied. Never derive these values from the user's request, ask the user for them, or create, edit, or reveal this install-local configuration during an infrastructure task.
41+
`channel` stores only the channel identifier; the bridge adds the `skill/` prefix before sending it to iac-code. `pipelineName` selects the implementation used only after Pipeline mode is chosen: `selling_solution_first` is the default, while the legacy `selling` flow is used only when this install-local file explicitly selects it. `permissionWaitPolicy` applies only to the temporary A2A server owned by this Skill: `null` timeouts mean unlimited waits, positive finite values set resident/Sub Pipeline limits, and grace is a non-negative finite value. Finite values cannot exceed 10 years; use `null` instead of an arbitrarily large number for an unlimited resident or Sub Pipeline wait. The bridge validates and converts this object into server configuration; it never sends the policy through A2A message metadata. The bridge rejects unknown configuration fields and invalid Pipeline names. If `config.json` or `pipelineName` is absent, Pipeline mode uses `selling_solution_first`; other absent fields keep their existing defaults. Never derive these values from the user's request, ask the user for them, or create, edit, or reveal this install-local configuration during an infrastructure task.
4142

42-
Normal is the default, including concrete resource queries/changes, template work, troubleshooting, and deployment of a clear target. Use `--mode pipeline --pipeline-name selling` only when the user explicitly requests it or the request genuinely needs the fixed candidate-architecture, cost-comparison, plan-confirmation, and deployment flow. Questions, permissions, tool use, or deployment alone do not select Pipeline. When uncertain, use normal.
43-
Start performs a non-secret configuration preflight through the Runtime. An incomplete LLM provider/API Key returns `llm_not_configured` and stops before creating a job. Selling Pipeline also requires complete Alibaba Cloud credentials and otherwise returns `cloud_credentials_not_configured`. Normal mode may continue without cloud credentials for work that does not call cloud APIs; report its preflight warning rather than claiming cloud operations are available.
43+
Normal is the overall default, including concrete resource queries/changes, template work, troubleshooting, and deployment of a clear target. Use `--mode pipeline` only when the user explicitly requests it or the request genuinely needs the candidate-architecture, cost-comparison, plan-confirmation, and deployment flow. Pipeline mode uses solution-first unless the installed configuration explicitly selects legacy selling. Questions, permissions, tool use, or deployment alone do not select Pipeline. When uncertain, use normal.
44+
Start performs a non-secret configuration preflight through the Runtime. An incomplete LLM provider/API Key returns `llm_not_configured` and stops before creating a job. Both supported Pipelines require complete Alibaba Cloud credentials and otherwise return `cloud_credentials_not_configured`. Normal mode may continue without cloud credentials for work that does not call cloud APIs; report its preflight warning rather than claiming cloud operations are available.
4445
3. `--follow` consumes the event stream until the next parent/candidate step boundary, permission, user question, candidate selection, `turn_completed`, or terminal state. It writes every parent `step_started`/`step_completed`/`step_failed` and candidate `candidate_step_started`/`candidate_step_completed`/`candidate_step_failed` boundary plus low-frequency bounded heartbeats to stderr; stdout contains one bounded JSON result. A boundary result sets `boundaryReached: true`, `presentationRequired: true`, and provides ready-to-display localized strings in `userUpdates`. Before invoking another tool, emit every `userUpdates` string in a user-visible assistant text block, including the Step 1/2 conclusion already embedded in completed-step updates. Never leave these updates only in reasoning, Bash output, a tool description, or the final summary. After that visible text block, immediately call `follow` again with the returned cursor. Do not treat `boundaryReached` as completion. Do not expand this into raw tool-event or token-delta output.
4546
While it is running, do not independently answer the infrastructure task or ask a parallel business question. Only ask the user when the current result contains `inputRequired`.
4647
4. If follow reaches its bounded wait window, call the diagnostic follow command again with the returned cursor:
@@ -50,6 +51,7 @@ Treat a bridge error returned before job creation as the authoritative outcome f
5051
```
5152

5253
The recommended wait is 60 seconds and the bridge enforces a 120-second maximum even if a larger value is supplied.
54+
If a result says `state: input-required` but does not contain `inputRequired`, there is no user boundary to answer. Report its `latestText` or error, keep the same job unchanged, and stop. Never call `continue`, repeat `respond`, call `cancel`, or start a replacement job unless the user explicitly requests that action.
5355

5456
5. When `state` is `turn_completed`, treat `finalText` and `artifacts` as the authoritative normal-turn result. When a Pipeline reaches any terminal state, including `completed`, `failed`, `canceled`, or `rejected`, treat `pipelineResult` and `artifacts` as its authoritative result and present its success or failure details directly. If rollback cleanup is pending, the bridge automatically runs a cleanup-only normal task in the same context before returning the Pipeline result; keep following it and handle any returned permission normally. If cleanup is `failed` or `unavailable`, report that manual inspection or retry is required and do not claim it succeeded. Never send a synthetic cleanup prompt or a follow-up merely to retrieve or summarize an existing result. Never recover an answer from Session files, spool files, logs, or raw tool-result files.
5557
6. To send the next natural-language message in the same normal conversation, or after a completed Pipeline has handed the same conversation to normal mode, write it to another workspace prompt file and continue the existing job:
@@ -68,24 +70,20 @@ python3 scripts/iac_code.py poll --job-id <job-id> --cursor <cursor> --wait-seco
6870

6971
## User input
7072

71-
When `inputRequired` is present, preserve every correlation field in the response. Never reuse an answer file from another request.
73+
Treat every `inputRequired` as a hard user-interaction boundary. Present it through the outer Agent's native user-question or approval UI and stop until the user explicitly answers that specific boundary. If no native UI is available, ask in a visible assistant turn and stop. Never infer, recommend-and-select, or submit an answer from the original infrastructure request, a prior answer, an outer tool-execution approval, a default, or the fact that only one option is available. Do not write an answer file or invoke `respond` before the user's answer arrives. Preserve every correlation field in the response, and never reuse an answer file from another request.
7274

73-
- For `permission`, apply the outer Agent's own equivalent permission policy. If the same operation would proceed without asking when invoked directly by the outer Agent, respond `allow_once`; if that policy would deny, respond `deny`; otherwise ask the user. iac-code has already applied its own allow/deny rules, and the outer Agent must not override an iac-code denial. Base the decision on `title`, `purpose`, `effect`, `target`, `isReadOnly`, `deploymentSummary`, and `safeSummary`; do not infer safety from the internal `toolName` alone. When asking about deployment, show the provided plan, region, stack, template, total price, and per-resource prices without exposing raw tool input.
74-
- For `ask_user_question`, present the current prompt and options without inventing a second question. Accept a listed option. Accept free text only when `allowFreeText` is `true`; when present, show `freeTextPrompt` with the input.
75-
- For `candidate_selection`, first present every option's `summary`, render `architectureDiagram` as Mermaid when present, and show `totalMonthlyCost` plus `costItems`. Do not invent missing details or replace these prices with a rough estimate. Then return the selected candidate ID/index requested by the envelope.
75+
- For `permission`, always ask the user to choose one of the returned actions, including for read-only or apparently safe operations. The original request and the outer Agent's permission policy do not authorize an iac-code permission boundary. iac-code has already applied its own allow/deny rules, and the outer Agent must not override an iac-code denial. Present `title`, `purpose`, `effect`, `target`, `isReadOnly`, `deploymentSummary`, and `safeSummary`; do not expose raw tool input or infer safety from the internal `toolName` alone.
76+
- For `ask_user_question`, present the current prompt and options without inventing a second question, then wait for the answer. Accept a listed option. Accept free text only when `allowFreeText` is `true`; when present, show `freeTextPrompt` with the input.
77+
- For `candidate_selection`, present every option's `summary`, render `architectureDiagram` as Mermaid when present, and show `totalMonthlyCost` plus `costItems`, then ask the user to select one. Ask even when there is only one candidate. Do not invent missing details, replace these prices with a rough estimate, or choose on the user's behalf. Return only the candidate ID/index selected by the user.
78+
- For `deployment_confirmation`, present `solutionSummary`, `templateUrl`, the quote or explicit quote failure in `cost`, `effectiveDeploymentParameters`, `parameterOverrides`, `previewReadyForCreate`, and exactly the actions returned in `options`, then ask the user to select an action. A request to create or deploy infrastructure is not confirmation for this boundary. The bridge derives this bounded display projection directly from the Runtime's existing A2A Pipeline confirmation event; never supplement it from local Session, journal, template, spool, or tool-result files. Never confirm, adjust, reselect, or cancel on the user's behalf, including after a failed quote or Preview.
7679
- Bind every user answer only to the current `kind`, `inputId`, `requestTaskId`, and `contextId`. Never reinterpret a resource selection as deployment confirmation or reuse it for a later input.
7780

78-
For an automatically decided permission, respond in one tool call while preserving the current input and tool identities:
79-
80-
```text
81-
python3 scripts/iac_code.py respond --job-id <job-id> --input-id <inputId> --tool-use-id <toolUseId> --decision allow_once --follow
82-
```
83-
84-
Use `deny` when the outer Agent's policy denies it. For a user question, candidate selection, or permission that was explicitly shown to the user, write the correlated answer as JSON to a UTF-8 file and resume the same job:
81+
After the user answers, write the correlated answer as JSON to a UTF-8 file and resume the same job:
8582

8683
- Permission: `{"kind":"permission","requestTaskId":"<requestTaskId>","contextId":"<contextId>","inputId":"<inputId>","toolUseId":"<toolUseId>","decision":"allow_once"}` or use `deny`.
8784
- Question: `{"kind":"ask_user_question","requestTaskId":"<requestTaskId>","contextId":"<contextId>","inputId":"<inputId>","answer":"<option, or free text only when allowed>"}`.
8885
- Candidate: `{"kind":"candidate_selection","requestTaskId":"<requestTaskId>","contextId":"<contextId>","inputId":"<inputId>","answer":"<candidate ID or index>"}`.
86+
- Deployment confirmation: `{"kind":"deployment_confirmation","requestTaskId":"<requestTaskId>","contextId":"<contextId>","inputId":"<inputId>","action":"<action selected by the user>","parameterOverrides":{"<parameter selected by the user>":"<value selected by the user>"}}`. Allowed actions are `confirm`, `adjust`, `reselect`, and `cancel`; omit `parameterOverrides` when the user did not request an adjustment.
8987

9088
```text
9189
python3 scripts/iac_code.py respond --job-id <job-id> --input-file <answer-file> --follow

0 commit comments

Comments
 (0)