Skip to content

Commit acebef0

Browse files
committed
Enhanced Quality Generation
1 parent 6c796b4 commit acebef0

File tree

6 files changed

+215
-59
lines changed

6 files changed

+215
-59
lines changed

tools/CreateMappings_rules.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,5 +979,45 @@
979979
{
980980
"module": "DependencyMap",
981981
"alias": "DependencyMap"
982+
},
983+
{
984+
"alias": "YashMaps",
985+
"module": "YashMaps"
986+
},
987+
{
988+
"alias": "YashMaps2",
989+
"module": "YashMaps2"
990+
},
991+
{
992+
"alias": "TestArizeAI",
993+
"module": "TestArizeAI"
994+
},
995+
{
996+
"alias": "TestData",
997+
"module": "TestData"
998+
},
999+
{
1000+
"alias": "YashMaps3",
1001+
"module": "YashMaps3"
1002+
},
1003+
{
1004+
"alias": "YashMaps4",
1005+
"module": "YashMaps4"
1006+
},
1007+
{
1008+
"alias": "YashMaps5",
1009+
"module": "YashMaps5"
1010+
},
1011+
{
1012+
"alias": "YashMaps6",
1013+
"module": "YashMaps6"
1014+
},
1015+
{
1016+
"alias": "TestPinecone",
1017+
"module": "TestPinecone"
1018+
},
1019+
{
1020+
"module": "YashMaps7",
1021+
"alias": "YashMaps7"
9821022
}
9831023
]

tools/Mcp/src/services/toolsService.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,16 @@ export class ToolsService {
161161
console.error(`Error eliciting input for example ${name}:`, error);
162162
}
163163
}
164-
return [exampleSpecsPath, examplePath];
164+
const idealExamplePaths = utils.getIdealModuleExamplePaths();
165+
return [exampleSpecsPath, examplePath, idealExamplePaths];
165166
}
166167

167168
createTestsFromSpecs = async <Args extends ZodRawShape>(args: Args): Promise<string[]> => {
168169
const workingDirectory = z.string().parse(Object.values(args)[0]);
169170
const testPath = path.join(workingDirectory, "test");
170171
const exampleSpecsPath = await utils.getExamplesFromSpecs(workingDirectory);
171-
return [exampleSpecsPath, testPath];
172+
const idealTestPaths = utils.getIdealModuleTestPaths();
173+
return [exampleSpecsPath, testPath, idealTestPaths];
172174
}
173175

174176
setupModuleStructure = async <Args extends ZodRawShape>(args: Args): Promise<string[]> => {
@@ -271,7 +273,7 @@ export class ToolsService {
271273
});
272274

273275
const moduleNameResponse = await this._server!.elicitInput({
274-
message: `Configuration resolved:\n- Service: ${selectedService}\n- Provider: ${selectedProvider}\n- Version: ${selectedVersion} (${selectedStability})\n- Service Name: ${resolved.serviceName}\n- Commit ID: ${resolved.commitId}\n- Service Specs: ${resolved.serviceSpecs}\n- Swagger File: ${resolved.swaggerFileSpecs}`,
276+
message: `What would you like call the powershell module? \n\n Configuration resolved:\n- Service: ${selectedService}\n- Provider: ${selectedProvider}\n- Version: ${selectedVersion} (${selectedStability})\n- Service Name: ${resolved.serviceName}\n- Commit ID: ${resolved.commitId}\n- Service Specs: ${resolved.serviceSpecs}\n- Swagger File: ${resolved.swaggerFileSpecs}`,
275277
requestedSchema: {
276278
type: "object",
277279
properties: {

tools/Mcp/src/services/utils.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import yaml from "js-yaml";
33
import { yamlContent } from '../types.js';
44
import { execSync } from 'child_process';
55
import path from 'path';
6+
import { Dirent } from 'fs';
67

78
const GITHUB_API_BASE = 'https://api.github.com';
89
const REST_API_SPECS_OWNER = 'Azure';
@@ -370,6 +371,50 @@ export async function writeFileIfNotExists(filePath: string, content: string): P
370371
}
371372
}
372373

374+
export function getIdealModuleExamplePaths(): string {
375+
const idealModulesRoot = path.join(process.cwd(), 'src', 'ideal-modules');
376+
try {
377+
if (!fs.existsSync(idealModulesRoot)) {
378+
return '';
379+
}
380+
const modules: Dirent[] = fs.readdirSync(idealModulesRoot, { withFileTypes: true });
381+
const exampleDirs: string[] = [];
382+
for (const mod of modules) {
383+
if (!mod.isDirectory()) continue;
384+
const candidate = path.join(idealModulesRoot, mod.name, 'examples');
385+
if (fs.existsSync(candidate)) {
386+
exampleDirs.push(candidate);
387+
}
388+
}
389+
return exampleDirs.join(';');
390+
} catch (err) {
391+
console.error('Error collecting ideal module example paths:', err);
392+
return '';
393+
}
394+
}
395+
396+
export function getIdealModuleTestPaths(): string {
397+
const idealModulesRoot = path.join(process.cwd(), 'src', 'ideal-modules');
398+
try {
399+
if (!fs.existsSync(idealModulesRoot)) {
400+
return '';
401+
}
402+
const modules: Dirent[] = fs.readdirSync(idealModulesRoot, { withFileTypes: true });
403+
const testDirs: string[] = [];
404+
for (const mod of modules) {
405+
if (!mod.isDirectory()) continue;
406+
const candidate = path.join(idealModulesRoot, mod.name, 'tests');
407+
if (fs.existsSync(candidate)) {
408+
testDirs.push(candidate);
409+
}
410+
}
411+
return testDirs.join(';');
412+
} catch (err) {
413+
console.error('Error collecting ideal module test paths:', err);
414+
return '';
415+
}
416+
}
417+
373418

374419

375420

Lines changed: 69 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,69 @@
1-
# Execution rules
2-
- Do not ask before running the command, just go ahead and run.
3-
4-
# Role and Objective
5-
- You are an autonomous agent that generates Azure PowerShell modules using Autorest for partners.
6-
- Execute commands confidently without asking for confirmation.
7-
- Follow all steps carefully and halt if any MCP tool is missing or fails.
8-
- Think independently using your full context and reset if needed.
9-
- No need to provide status updates at each step.
10-
- FOLLOW ALL THE STEPS. DO NOT SKIP ANY STEPS. DO NOT MISS ANY STEPS.
11-
- If an mcp tool is not found or the tool fails then please halt execution.
12-
13-
# Instructions
14-
15-
## Stage 1: Interactive specification selection and autorest resolution
16-
- Call the MCP tool "setupModuleStructure" with no parameters
17-
- This tool will interactively guide you through:
18-
1. Selecting the specification from available azure-rest-api-specs
19-
2. Choosing the provider namespace
20-
3. Selecting the API version (stable or preview)
21-
4. Getting the module name from the user
22-
5. Automatically creating the module structure and README.md file
23-
- The tool will create the folder structure under the correct src directory and generate the README.md with proper autorest configuration
24-
- Mark Stage 1 complete once the setupModuleStructure tool finishes successfully
25-
26-
## Stage 2: Generating partner powershell module
27-
- FOLLOW ALL THE STEPS. DO NOT SKIP ANY STEPS.
28-
- Navigate to the created module directory, you can find this from the input given by the user using ellicitation for the input "moduleName" (should be under `src/<PowerShell module name>/<PowerShell module name>.Autorest`)
29-
- Use the "generate-autorest" mcp tool to generate the <PowerShell module name> module using the README.md that was created by setupModuleStructure
30-
- Stage 2 Complete.
31-
32-
## Stage 3: Updating Example Files
33-
- Use the "create-example" MCP tool to download exampleSpecs. Use the output of this tool as a prompt input/task for you.
34-
- The example files already exist as skeletons under `{workingDirectory}/examples`.
35-
- Read data from `exampleSpecs` (swagger examples) and intelligently map values to PowerShell parameters.
36-
- Complete each file by fulfilling the examples based on the data available in `exampleSpecs`.
37-
- Leave example content empty only if no relevant data is found in `exampleSpecs`.
38-
- Once all example files are updated, mark stage 3 as complete.
39-
40-
## Stage 4: Updating Test Files
41-
- Use the "create-test" MCP tool to download exampleSpecs. Use the output of this tool as a prompt input/task for you.
42-
- Read data from `exampleSpecs` and use it to define variables and write test cases.
43-
- Define setup variables inside `setupEnv` in `utils.ps1`, inferred from `exampleSpecs`.
44-
- Use those variables in the actual test case content.
45-
- The test files already exist as skeletons; your task is to intelligently complete them.
46-
- Leave test bodies empty only if no meaningful data can be inferred from `exampleSpecs`.
47-
- Once all test files are updated, mark stage 4 as complete.
48-
49-
## Stage 5: Regenerating the Autorest Module
50-
- After example and test files have been generated and written, re-run the "generate-autorest" MCP tool.
51-
- This will regenerate the Azure PowerShell module with updated examples and test logic embedded.
52-
- Use the same `workingDirectory` and make sure all directives and yaml configurations remain unchanged.
53-
- This is a mandatory finalization step before pushing to GitHub.
54-
- Do not skip this regeneration even if the module was generated earlier.
1+
# Partner Module Workflow (Simplified)
2+
3+
Goal: Generate an Azure PowerShell module via Autorest, then populate examples and tests deterministically with minimal ambiguity.
4+
5+
Core Principle: Derive the working directory once and reuse it. Do not guess or fabricate paths.
6+
7+
## 1. Create Module Structure
8+
Call MCP tool: `setup-module-structure` (no parameters).
9+
It returns `{0}` = `ModuleName` (from user input inside the tool).
10+
Derive `workingDirectory` strictly as:
11+
`<repo-root>/src/{ModuleName}/{ModuleName}.Autorest`
12+
Never alter letter casing; do not surround with quotes unless passing to a shell command.
13+
14+
## 2. Initial Code Generation
15+
Call MCP tool: `generate-autorest` with parameter `workingDirectory` = the path above.
16+
Do not call Autorest directly; always use the MCP tool.
17+
If generation fails, STOP.
18+
19+
## 3. Populate Examples
20+
Call MCP tool: `create-example` with the same `workingDirectory`.
21+
Tool returns:
22+
`{0}` = specs example source dir (downloaded JSON)
23+
`{1}` = target examples dir in module
24+
`{2}` = reference ideal examples (semicolon separated; may be empty)
25+
Use reference examples (if any) for style: parameter ordering (required first), consistent variable placeholder patterns, and advanced options inclusion.
26+
Leave an example file empty only if no relevant swagger example data exists.
27+
Quality guidance (concise):
28+
- Provide both minimal (required params only) and enriched (common optional params) variants if the skeleton expects multiple examples.
29+
- Use stable placeholder naming: `<ResourceGroupName>`, `<Location>`, `<WorkspaceName>` etc., unless a deterministic value is required by an existing test.
30+
- Do not invent unsupported parameters; omit deprecated or preview-only params unless the swagger version explicitly requires them.
31+
- Maintain consistent casing and ordering: required first, then alphabetized optional.
32+
- Prefer realistic value shapes (GUID formats, URIs) over lorem ipsum.
33+
MANDATORY: After the tool call, TREAT the returned response text itself (instructions referencing {0} {1} {2}) AS AN ACTION PLAN. Execute those instructions step-by-step: read from `{0}`, write into `{1}`, leverage `{2}` for stylistic alignment. Do not stop at calling the tool; The tool response is not informational; it is a directive sequence you must fulfill.
34+
35+
## 4. Populate Tests
36+
Call MCP tool: `create-test` with the same `workingDirectory`.
37+
Tool returns:
38+
`{0}` = specs example source dir
39+
`{1}` = target test dir
40+
`{2}` = reference ideal test dirs
41+
Fill test stubs using variables defined in `utils.ps1` `setupEnv` function.
42+
IMPORTANT: You can completely ignore the generated Test files as they only have the skeleton. Instead, you can group these test files into groups of 1 particular resource & then write 1 new file combining these 3-4 test file in the CRUD format.
43+
Add: create -> get -> assert -> (optional cleanup). Add a negative test when feasible.
44+
Leave a test empty only if genuinely no meaningful data can be inferred.
45+
Quality guidance (concise):
46+
- CRUD Pattern: Create (or Update) => Get => Assert essential fields => (List => Assert presence) => (Delete => Confirm absence) when resource lifecycle is supported.
47+
- Assertions: Prefer specific property checks (Name, Id segment patterns, ProvisioningState) over broad object dumps.
48+
- Negative Case: Intentionally supply one invalid parameter or missing required field; assert error category/message pattern.
49+
- Reuse Variables: All names & IDs defined once in `setupEnv` to avoid duplication and enable future parameterization.
50+
- Idempotency: Avoid destructive operations unless they clean up what this test created.
51+
MANDATORY: After the tool call, EXECUTE the returned test instructions: interpret response text referencing `{0}`, `{1}`, `{2}`, open each stub under `{1}`, populate bodies using data from `{0}`, and mirror style from `{2}`. The tool response is not informational; it is a directive sequence you must fulfill.
52+
53+
## 5. Regenerate Module
54+
Call `generate-autorest` again with identical `workingDirectory` to ensure examples/tests are integrated. Do not modify the README.yaml block except via directives inserted earlier.
55+
56+
## 6. Validation (Internal Logic Guideline)
57+
Before completion internally verify:
58+
- All required example parameters present where data exists.
59+
- No unknown parameters introduced.
60+
- Tests assert at least one key property per created resource.
61+
If any check fails, refine the affected file(s) then proceed.
62+
63+
## Rules & Constraints
64+
- Never recalculate or re-ask for the module name after Stage 1.
65+
- Never invent alternative directory paths.
66+
- Do not skip steps 1–5.
67+
- Halt immediately if an MCP tool is unavailable or errors.
68+
69+
End of workflow.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Execution rules
2+
- Do not ask before running the command, just go ahead and run.
3+
4+
# Role and Objective
5+
- You are an autonomous agent that generates Azure PowerShell modules using Autorest for partners.
6+
- Execute commands confidently without asking for confirmation.
7+
- Follow all steps carefully and halt if any MCP tool is missing or fails.
8+
- Think independently using your full context and reset if needed.
9+
- No need to provide status updates at each step.
10+
- FOLLOW ALL THE STEPS. DO NOT SKIP ANY STEPS. DO NOT MISS ANY STEPS.
11+
- If an mcp tool is not found or the tool fails then please halt execution.
12+
13+
# Instructions
14+
15+
## Stage 1: Interactive specification selection and autorest resolution
16+
- Call the MCP tool "setupModuleStructure" with no parameters
17+
- This tool will interactively guide you through:
18+
1. Selecting the specification from available azure-rest-api-specs
19+
2. Choosing the provider namespace
20+
3. Selecting the API version (stable or preview)
21+
4. Getting the module name from the user
22+
5. Automatically creating the module structure and README.md file
23+
- The tool will create the folder structure under the correct src directory and generate the README.md with proper autorest configuration
24+
- Mark Stage 1 complete once the setupModuleStructure tool finishes successfully
25+
26+
## Stage 2: Generating partner powershell module
27+
- FOLLOW ALL THE STEPS. DO NOT SKIP ANY STEPS.
28+
- Navigate to the created module directory, you can find this from the input given by the user using ellicitation for the input "moduleName" (should be under `src/<PowerShell module name>/<PowerShell module name>.Autorest`)
29+
- Use the "generate-autorest" mcp tool to generate the <PowerShell module name> module using the README.md that was created by setupModuleStructure
30+
- Stage 2 Complete.
31+
32+
## Stage 3: Updating Example Files
33+
- Use the "create-example" MCP tool to download exampleSpecs. Use the output of this tool as a prompt input/task for you.
34+
- The example files already exist as skeletons under `{workingDirectory}/examples`.
35+
- Read data from `exampleSpecs` (swagger examples) and intelligently map values to PowerShell parameters.
36+
- Complete each file by fulfilling the examples based on the data available in `exampleSpecs`.
37+
- Leave example content empty only if no relevant data is found in `exampleSpecs`.
38+
- Once all example files are updated, mark stage 3 as complete.
39+
40+
## Stage 4: Updating Test Files
41+
- Use the "create-test" MCP tool to download exampleSpecs. Use the output of this tool as a prompt input/task for you.
42+
- Read data from `exampleSpecs` and use it to define variables and write test cases.
43+
- Define setup variables inside `setupEnv` in `utils.ps1`, inferred from `exampleSpecs`.
44+
- Use those variables in the actual test case content.
45+
- The test files already exist as skeletons; your task is to intelligently complete them.
46+
- Leave test bodies empty only if no meaningful data can be inferred from `exampleSpecs`.
47+
- Once all test files are updated, mark stage 4 as complete.
48+
49+
## Stage 5: Regenerating the Autorest Module
50+
- After example and test files have been generated and written, re-run the "generate-autorest" MCP tool.
51+
- This will regenerate the Azure PowerShell module with updated examples and test logic embedded.
52+
- Use the same `workingDirectory` and make sure all directives and yaml configurations remain unchanged.
53+
- This is a mandatory finalization step before pushing to GitHub.
54+
- Do not skip this regeneration even if the module was generated earlier.

tools/Mcp/src/specs/responses.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
{
2323
"name": "create-example",
2424
"type": "tool",
25-
"text": "Read examples from specs under {0}. Fulfill examples under {1}. You are expert in Azure-PowerShell and Autorest.PowerShell. Leave example as empty if you don't find any matches. You know how to map data from {0} to {1}"
25+
"text": "Read examples from specs under {0}. Fulfill examples under {1}. Also leverage high-quality reference examples located in directories: {2} (semicolon-separated). When generating, mirror parameter naming, structure, and advanced option usage patterns seen in those reference examples when applicable. Produce minimal yet complete runnable examples; omit unknown or deprecated params. Leave example empty only if no relevant mapping exists."
2626
},
2727
{
2828
"name": "create-test",
2929
"type": "tool",
30-
"text": "Read examples from specs are under {0}. Implement empty test stubs under {1}. Test stubs are named as '.Test.ps1'. Define variables in function 'setupEnv' in 'utils.ps1' under {1}, and use these variables for test cases. Value of these variables are from {0}. Leave test cases as empty if you don't find any matches. You are expert in Azure-PowerShell and Autorest.PowerShell, You know how to map data from {0} to {1}. "
30+
"text": "Read examples from specs under {0}. Implement test stubs under {1}. Reference high-quality existing tests from directories: {2} (semicolon-separated) to replicate assertion style, variable patterns, and setup/teardown conventions. Test stubs are named '.Test.ps1'. Populate 'setupEnv' in 'utils.ps1' with variables derived from {0} examples; reuse them across tests. For each CRUD operation: (1) Create/Update then Get and assert key properties, (2) List and validate presence, (3) Clean up if destructive. Add one negative test if feasible (invalid parameter) asserting specific error type/message. Leave a stub empty only if absolutely no relevant example data exists."
3131
},
3232
{
3333
"name": "setup-module-structure",

0 commit comments

Comments
 (0)