Skip to content

Commit 9efaa85

Browse files
committed
Integrate anthropic backend to generate UI modal
1 parent dbc19c2 commit 9efaa85

5 files changed

Lines changed: 177 additions & 38 deletions

File tree

src/components/atoms/flow/Textarea.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const Textarea = ({ id, placeHolder, onChangeHandler, name, value, rows }) => {
55
<textarea
66
id={id}
77
placeholder={placeHolder}
8-
className='nodrag nowheel min-h-12 w-full min-w-72 resize rounded border border-slate-700 bg-background-light p-2.5 text-sm text-slate-900 outline-none'
8+
className='nodrag nowheel min-h-12 w-full min-w-72 rounded border border-slate-700 bg-background-light p-2.5 text-sm text-slate-900 outline-none'
99
name={name}
1010
onChange={onChangeHandler}
1111
rows={rows}

src/components/molecules/flow/flowtestai.js

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,24 @@ const translateGeneratedNodesToOpenApiNodes = (generatedNodes, openApiNodes) =>
99
if (node !== undefined) {
1010
// take best of both worlds (parameters and request body generated by ai model and ones intelligently generated by parser)
1111
const outputNode = JSON.parse(JSON.stringify(node)); //{ ...node };
12-
const node_arguments = JSON.parse(gnode.arguments);
13-
// if (node_arguments.requestBody) {
14-
// outputNode['requestBody'] = {};
15-
// outputNode['requestBody']['type'] = 'raw-json';
16-
// outputNode['requestBody']['body'] = JSON.stringify(node_arguments.requestBody);
17-
// }
18-
if (node_arguments.parameters) {
19-
Object.entries(node_arguments.parameters).forEach(([paramName, paramValue], _) => {
20-
if (!outputNode.preReqVars) {
21-
outputNode.preReqVars = {};
22-
}
23-
outputNode.preReqVars[paramName] = {
24-
type: typeof paramValue,
25-
value: paramValue,
26-
};
27-
});
12+
if (gnode.arguments) {
13+
const node_arguments = JSON.parse(gnode.arguments);
14+
// if (node_arguments.requestBody) {
15+
// outputNode['requestBody'] = {};
16+
// outputNode['requestBody']['type'] = 'raw-json';
17+
// outputNode['requestBody']['body'] = JSON.stringify(node_arguments.requestBody);
18+
// }
19+
if (node_arguments.parameters) {
20+
Object.entries(node_arguments.parameters).forEach(([paramName, paramValue], _) => {
21+
if (!outputNode.preReqVars) {
22+
outputNode.preReqVars = {};
23+
}
24+
outputNode.preReqVars[paramName] = {
25+
type: typeof paramValue,
26+
value: paramValue,
27+
};
28+
});
29+
}
2830
}
2931
outputNodes.push({
3032
...outputNode,
@@ -64,6 +66,36 @@ export const generateFlowData = async (instruction, modelName, modelKey, collect
6466
nodes: translateGeneratedNodesToOpenApiNodes(generatedNodes, collection.nodes),
6567
};
6668
return flowData;
69+
} else if (modelName === GENAI_MODELS.bedrock_claude) {
70+
if (!collection.dotEnvVariables) {
71+
await ipcRenderer.invoke(
72+
'renderer:create-dotenv',
73+
collection.pathname,
74+
`BEDROCK_ACCESS_KEYID=${modelKey.accessKeyId}\nBEDROCK_SECRET_ACCESSKEY=${modelKey.secretAccessKey}`,
75+
);
76+
} else if (
77+
!Object.prototype.hasOwnProperty.call(collection.dotEnvVariables, 'BEDROCK_ACCESS_KEYID') ||
78+
modelKey.accessKeyId != collection.dotEnvVariables['BEDROCK_ACCESS_KEYID'] ||
79+
!Object.prototype.hasOwnProperty.call(collection.dotEnvVariables, 'BEDROCK_SECRET_ACCESSKEY') ||
80+
modelKey.secretAccessKey != collection.dotEnvVariables['BEDROCK_SECRET_ACCESSKEY']
81+
) {
82+
const vars = {
83+
BEDROCK_ACCESS_KEYID: modelKey.accessKeyId,
84+
BEDROCK_SECRET_ACCESSKEY: modelKey.secretAccessKey,
85+
};
86+
await addOrUpdateDotEnvironmentFile(collectionId, {
87+
...collection.dotEnvVariables,
88+
...vars,
89+
});
90+
}
91+
const generatedNodes = await ipcRenderer.invoke('renderer:generate-nodes-ai', instruction, collectionId, {
92+
name: GENAI_MODELS.bedrock_claude,
93+
apiKey: modelKey,
94+
});
95+
const flowData = {
96+
nodes: translateGeneratedNodesToOpenApiNodes(generatedNodes, collection.nodes),
97+
};
98+
return flowData;
6799
} else {
68100
return Promise.reject(new Error(`model: ${modelName} not supported`));
69101
}

src/components/molecules/flow/nodes/RequestNode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const RequestNode = ({ id, data }) => {
5959
const variables = vType === 'pre-request' ? data.preReqVars : data.postRespVars;
6060
return (
6161
<>
62-
{variables ? (
62+
{variables && Object.keys(variables).length > 0 ? (
6363
<div className='p-2 pt-4 border-t border-neutral-300 bg-slate-50'>
6464
{Object.keys(variables).map((id) => (
6565
<div className='flex items-center justify-between pb-2' key={id}>

src/components/molecules/modals/GenerateFlowTestModal.js

Lines changed: 126 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const GenerateFlowTestModal = ({ closeFn = () => null, open = false, collectionI
3131
const [selectedModel, setSelectedModel] = useState(null);
3232
const [textareaValue, setTextareaValue] = useState('');
3333
const [modelKey, setModelKey] = useState('');
34+
const [bedrockAccessKeyId, setBedrockAccessKeyId] = useState('');
35+
const [bedrockSecretAccessKey, setBedrockSecretAccessKey] = useState('');
3436

3537
const [flowtestName, setFlowtestName] = useState('');
3638
const [selectedCollection, setSelectionCollection] = useState(
@@ -44,6 +46,8 @@ const GenerateFlowTestModal = ({ closeFn = () => null, open = false, collectionI
4446
const [showSelectedModelError, setSelectedModelError] = useState(false);
4547
const [showModelKeyError, setShowModelKeyError] = useState(false);
4648
const [showDescribeFlowError, setShowDescribeFlowError] = useState(false);
49+
const [showBedrockAccessKeyIdError, setShowBedrockAccessKeyIdError] = useState(false);
50+
const [showBedrockSecretAccessKeyError, setShowBedrockSecretAccessKeyError] = useState(false);
4751
//const [showFolderSelectionError, setShowFolderSelectionError] = useState(false);
4852

4953
const resetFields = () => {
@@ -60,7 +64,8 @@ const GenerateFlowTestModal = ({ closeFn = () => null, open = false, collectionI
6064
setShowModelKeyError(false);
6165
setShowDescribeFlowError(false);
6266
setSelectedModelError(false);
63-
//setShowFolderSelectionError(false);
67+
setShowBedrockAccessKeyIdError(false);
68+
setShowBedrockSecretAccessKeyError(false);
6469
};
6570

6671
const containsFolder = (collection) => {
@@ -133,7 +138,7 @@ const GenerateFlowTestModal = ({ closeFn = () => null, open = false, collectionI
133138
{!collectionId && (
134139
<>
135140
<div>
136-
<div className='flex justify-between gap-2 transition border rounded bg-background-light hover:bg-background whitespace-nowrap border-cyan-900 text-cyan-900'>
141+
<div className='flex justify-between gap-2 transition border rounded whitespace-nowrap border-cyan-900 bg-background-light text-cyan-900 hover:bg-background'>
137142
<Listbox
138143
value={selectedCollection}
139144
onChange={(value) => {
@@ -196,7 +201,7 @@ const GenerateFlowTestModal = ({ closeFn = () => null, open = false, collectionI
196201
</div>
197202
{!isEmpty(selectedCollection) && containsFolder(selectedCollection) ? (
198203
<div>
199-
<div className='justify-between gap-2 transition border rounded bg-background-light hover:bg-background whitespace-nowrap border-cyan-900 text-cyan-900'>
204+
<div className='justify-between gap-2 transition border rounded whitespace-nowrap border-cyan-900 bg-background-light text-cyan-900 hover:bg-background'>
200205
<Listbox
201206
value={selectedFolder}
202207
onChange={(value) => {
@@ -270,20 +275,42 @@ const GenerateFlowTestModal = ({ closeFn = () => null, open = false, collectionI
270275
<div>
271276
{!isEmpty(selectedCollection) && (
272277
<div>
273-
<div className='justify-between gap-2 transition border rounded bg-background-light hover:bg-background whitespace-nowrap border-cyan-900 text-cyan-900'>
278+
<div className='justify-between gap-2 transition border rounded whitespace-nowrap border-cyan-900 bg-background-light text-cyan-900 hover:bg-background'>
274279
<Listbox
275280
value={selectedModel}
276281
onChange={(m) => {
277-
if (GENAI_MODELS.openai) {
278-
if (
279-
selectedCollection &&
280-
selectedCollection.dotEnvVariables &&
281-
Object.prototype.hasOwnProperty.call(
282-
selectedCollection.dotEnvVariables,
283-
'OPENAI_APIKEY',
284-
)
285-
) {
286-
setModelKey(selectedCollection.dotEnvVariables['OPENAI_APIKEY']);
282+
if (selectedCollection && selectedCollection.dotEnvVariables) {
283+
if (GENAI_MODELS.openai) {
284+
if (
285+
Object.prototype.hasOwnProperty.call(
286+
selectedCollection.dotEnvVariables,
287+
'OPENAI_APIKEY',
288+
)
289+
) {
290+
setModelKey(selectedCollection.dotEnvVariables['OPENAI_APIKEY']);
291+
}
292+
}
293+
294+
if (GENAI_MODELS.bedrock_claude) {
295+
if (
296+
Object.prototype.hasOwnProperty.call(
297+
selectedCollection.dotEnvVariables,
298+
'BEDROCK_ACCESS_KEYID',
299+
)
300+
) {
301+
setBedrockAccessKeyId(selectedCollection.dotEnvVariables['BEDROCK_ACCESS_KEYID']);
302+
}
303+
304+
if (
305+
Object.prototype.hasOwnProperty.call(
306+
selectedCollection.dotEnvVariables,
307+
'BEDROCK_SECRET_ACCESSKEY',
308+
)
309+
) {
310+
setBedrockSecretAccessKey(
311+
selectedCollection.dotEnvVariables['BEDROCK_SECRET_ACCESSKEY'],
312+
);
313+
}
287314
}
288315
}
289316
setSelectedModel(m);
@@ -339,12 +366,12 @@ const GenerateFlowTestModal = ({ closeFn = () => null, open = false, collectionI
339366
)}
340367
{selectedModel === GENAI_MODELS.openai ? (
341368
<div>
342-
<div className='flex items-center justify-center w-full h-12 mt-6 text-sm border rounded bg-background-light hover:bg-background border-cyan-900 text-cyan-900'>
369+
<div className='flex items-center justify-center w-full h-12 mt-6 text-sm border rounded border-cyan-900 bg-background-light text-cyan-900 hover:bg-background'>
343370
<label
344371
className='flex items-center w-32 h-full px-4 bg-transparent border-r border-cyan-900'
345372
htmlFor='openAIkey'
346373
>
347-
OpenAI Key
374+
API_KEY
348375
</label>
349376
<input
350377
id='openAIkey'
@@ -366,6 +393,64 @@ const GenerateFlowTestModal = ({ closeFn = () => null, open = false, collectionI
366393
) : (
367394
''
368395
)}
396+
{selectedModel === GENAI_MODELS.bedrock_claude ? (
397+
<div>
398+
<div className='flex items-center justify-center w-full h-12 mt-6 text-sm border rounded border-cyan-900 bg-background-light text-cyan-900 hover:bg-background'>
399+
<label
400+
className='flex items-center w-32 h-full px-4 bg-transparent border-r border-cyan-900'
401+
htmlFor='bedrockAccessKeyId'
402+
>
403+
ACCESS_KEYID
404+
</label>
405+
<input
406+
id='bedrockAccessKeyId'
407+
type='text'
408+
className='nodrag nowheel block w-full bg-transparent p-2.5 outline-none'
409+
name='keyId'
410+
placeholder='Enter your BEDROCK access key id'
411+
value={
412+
bedrockAccessKeyId.trim() != '' ? bedrockAccessKeyId : 'Enter your BEDROCK access key id'
413+
}
414+
//readOnly='readonly'
415+
onChange={(e) => setBedrockAccessKeyId(e.target.value)}
416+
/>
417+
</div>
418+
{bedrockAccessKeyId.trim() === '' && showBedrockAccessKeyIdError ? (
419+
<div className='py-2 text-red-600'> {`Please enter ${selectedModel} access key id`}</div>
420+
) : (
421+
''
422+
)}
423+
<div className='flex items-center justify-center w-full h-12 mt-6 text-sm border rounded border-cyan-900 bg-background-light text-cyan-900 hover:bg-background'>
424+
<label
425+
className='flex items-center w-32 h-full px-4 bg-transparent border-r border-cyan-900'
426+
htmlFor='bedrockSecretAccessKey'
427+
>
428+
SECRET_ACCESSKEY
429+
</label>
430+
<input
431+
id='bedrockSecretAccessKey'
432+
type='text'
433+
className='nodrag nowheel block w-full bg-transparent p-2.5 outline-none'
434+
name='keyName'
435+
placeholder='Enter your BEDROCK secret access key'
436+
value={
437+
bedrockSecretAccessKey.trim() != ''
438+
? bedrockSecretAccessKey
439+
: 'Enter your BEDROCK secret access key'
440+
}
441+
//readOnly='readonly'
442+
onChange={(e) => setBedrockSecretAccessKey(e.target.value)}
443+
/>
444+
</div>
445+
{bedrockSecretAccessKey.trim() === '' && showBedrockSecretAccessKeyError ? (
446+
<div className='py-2 text-red-600'> {`Please enter ${selectedModel} secret access key`}</div>
447+
) : (
448+
''
449+
)}
450+
</div>
451+
) : (
452+
''
453+
)}
369454
<div>
370455
<div className='mt-6'>
371456
<Textarea
@@ -425,28 +510,49 @@ const GenerateFlowTestModal = ({ closeFn = () => null, open = false, collectionI
425510
return;
426511
}
427512

428-
if (!modelKey || modelKey.trim() === '') {
513+
if (selectedModel === GENAI_MODELS.openai && (!modelKey || modelKey.trim() === '')) {
429514
setShowModelKeyError(true);
430515
return;
431516
}
432517

518+
if (
519+
selectedModel === GENAI_MODELS.bedrock_claude &&
520+
(!bedrockAccessKeyId || bedrockAccessKeyId.trim() === '')
521+
) {
522+
setShowBedrockAccessKeyIdError(true);
523+
return;
524+
}
525+
526+
if (
527+
selectedModel === GENAI_MODELS.bedrock_claude &&
528+
(!bedrockSecretAccessKey || bedrockSecretAccessKey.trim() === '')
529+
) {
530+
setShowBedrockSecretAccessKeyError(true);
531+
return;
532+
}
533+
433534
if (!textareaValue || textareaValue.trim() === '') {
434535
setShowDescribeFlowError(true);
435536
return;
436537
}
437538

438539
setShowFlowtestNameError(false);
439540
setShowCollectionSelectionError(false);
440-
//setShowFolderSelectionError(false);
441541
setShowModelKeyError(false);
542+
setShowBedrockAccessKeyIdError(false);
543+
setShowBedrockSecretAccessKeyError(false);
442544
setShowDescribeFlowError(false);
443545
setSelectedModelError(false);
444546

547+
const creds =
548+
selectedModel === GENAI_MODELS.openai
549+
? modelKey
550+
: { accessKeyId: bedrockAccessKeyId, secretAccessKey: bedrockSecretAccessKey };
445551
function gen() {
446552
setShowLoader(true);
447553
promiseWithTimeout(
448-
generateFlowData(textareaValue, selectedModel, modelKey, selectedCollection.id),
449-
30000,
554+
generateFlowData(textareaValue, selectedModel, creds, selectedCollection.id),
555+
60000,
450556
)
451557
.then((flowData) => {
452558
setShowLoader(false);

src/constants/Common.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ export const OBJ_TYPES = {
3131

3232
export const GENAI_MODELS = {
3333
openai: 'OPENAI',
34+
bedrock_claude: 'BEDROCK_CLAUDE',
3435
};

0 commit comments

Comments
 (0)