Skip to content

Commit

Permalink
feat: AI Codemod POC (#2325)
Browse files Browse the repository at this point in the history
* feat: move aicodemod to blade repo

* refactor: server and bin code

* feat: add example migration of table

* feat: add preset to repo

* feat: add docs and presets for aicodemod

* feat: add error handling

* feat: update aicodemod to use anurag's server

* refactor: remove unused code
  • Loading branch information
saurabhdaware authored Nov 11, 2024
1 parent b65f3a3 commit 9235163
Show file tree
Hide file tree
Showing 7 changed files with 1,357 additions and 7 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
"publish-npm": "lerna run --scope @razorpay/blade publish-npm",
"release": "lerna run --scope @razorpay/blade generate-github-npmrc && changeset publish",
"build": "lerna run --scope @razorpay/blade build",
"postinstall": "lerna run --scope eslint-plugin-blade build"
"postinstall": "lerna run --scope eslint-plugin-blade build",
"aicodemod:serve": "node packages/blade/codemods/aicodemod/server.mjs",
"aicodemod:host": "npx localtunnel --port 3000 --subdomain blade-ds"
},
"dependencies": {},
"devDependencies": {
Expand Down
26 changes: 26 additions & 0 deletions packages/blade/codemods/aicodemod/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Blade AI Codemod

## 1. Install Blade Globally

```sh
npm install -g @razorpay/blade
```

## 2. Run `aicodemod` Command to Migrate

```sh
aicodemod <path-to-migrate>
--code-knowledge presets/dashboard/table-pattern-1
```

`--code-knowledge`: The AI needs some info about existing codebase and some patterns on how to migrate. We currently have created a preset knowledge for migrating one of the patterns in table.

## 3. Fix any visual or syntax issues if there

AI Codemod is there to help you get going with migration. You might still have 10% work left to review if the code logic is in place and visually things are looking as expected.

> [!NOTE]
>
> **POC Limitations**
>
> As currently its just POC, its optimized to only migrate to Blade Table component. It can also
128 changes: 128 additions & 0 deletions packages/blade/codemods/aicodemod/bin.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/usr/bin/env node
import fs from 'fs';
import path from 'path';

const getFlagValue = (flag) => {
const flagIndex = process.argv.indexOf(flag);
if (flagIndex < 0) {
return undefined;
}

return process.argv[flagIndex + 1];
};

// This is for passing ngrok instance URL
const BASE_URL = 'https://blade-chat.dev.razorpay.in';
const SERVER_ENDPOINT = '/chat';

const preset = getFlagValue('--code-knowledge') ?? 'presets/dashboard/table-pattern-1';

const getChatCompletionFromServer = async (messages) => {
const url = BASE_URL + SERVER_ENDPOINT;

// Define the fetch options
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'rzpctx-dev-serve-user': 'base',
},
body: JSON.stringify({ input: messages }),
};

try {
// Make the fetch call
const response = await fetch(url, options);
return response.text();
} catch (err) {
throw err;
}
};

const __dirname = new URL('.', import.meta.url).pathname;
const cwd = process.cwd();

let codeKnowledge;
const consumerPresetPath = path.join(cwd, preset);
const predefinedPresetPath = path.join(__dirname, 'knowledge', `${preset}.md`);

if (fs.existsSync(consumerPresetPath)) {
codeKnowledge = fs.readFileSync(consumerPresetPath, 'utf-8');
} else {
codeKnowledge = fs.readFileSync(predefinedPresetPath, 'utf-8');
}

const bladeKnowledge = fs.readFileSync(path.resolve(__dirname, './knowledge/Table.md'), 'utf-8');

const usageFileArg = process.argv[2];
const usageFilePath = path.join(cwd, usageFileArg);
const usage = fs.readFileSync(usageFilePath, 'utf-8');

const ultimatePrompt = `
I want you to migrate our old codebase code from custom implementation, to use our design-system component called Blade.
You will find code snippets of these things below-
1. Blade's Table Documentation: Documentation of our design-system table
2. Custom Component Definitions: Custom component implementations to help figure out what some of the internally used components do
3. Migration Example: A reference example of migration. How the output migrated code would look like on given certain input.
4. Code to Migrate: Migrate this code to use our design-system components
Return Format:
- Refer to Blade's Table documentation and Custom Component Definitons and Migration Example and return the migrated code snippet of usage using Blade
- Return raw migrated code without additional text
- Don't change unrelated code and imports
- If something existed in previous code, but does not map to anything in new code. Add a TODO comment describing what needs to be done
- Remove unused variables, functions, and imports
- Make sure Blade's Header and Footer are also used wherever needed.
- Ignore the code related to mobile responsiveness as Blade components are responsive by default
## 1. Blade's Table Documentation
${bladeKnowledge}
${codeKnowledge}
## 4. Code to Migrate
\`\`\`jsx
${usage}
\`\`\`
`;

const messages = [
{
role: 'system',
content: [
{
type: 'text',
text:
'You are an AI assistant that helps in migrating codebase from old custom implementation to our internal design-system components',
},
],
},
{
role: 'user',
content: [
{
type: 'text',
text: ultimatePrompt,
},
],
},
];

const answer = await getChatCompletionFromServer(messages);

if (answer) {
console.log('USAGE STATS', {
inputLength: JSON.stringify(messages).length,
});

const cleanOut = answer.startsWith('```jsx')
? answer.slice(`\`\`\`jsx`.length + 1, -('```'.length + 1))
: answer;
fs.writeFileSync(usageFilePath, cleanOut);
} else {
console.log(
"Something's not right. The server didn't respond correctly. Hopefully there are more helpful logs above ^^",
);
}
Loading

0 comments on commit 9235163

Please sign in to comment.