wuhp commited on
Commit
02da259
·
verified ·
1 Parent(s): 1c20ef9

Update services/geminiService.ts

Browse files
Files changed (1) hide show
  1. services/geminiService.ts +134 -6
services/geminiService.ts CHANGED
@@ -4,6 +4,38 @@ import { NodeData, LayerType } from '../types';
4
  import { LAYER_DEFINITIONS } from '../constants';
5
 
6
  // --- SCHEMAS ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  const graphResponseSchema = {
8
  type: Type.OBJECT,
9
  properties: {
@@ -94,7 +126,7 @@ const getAiClient = () => {
94
 
95
  export const DEFAULT_MODEL = 'gemini-2.5-flash';
96
 
97
- export type AgentStatus = 'idle' | 'architect' | 'critic' | 'refiner' | 'debugger' | 'patcher' | 'complete' | 'error';
98
 
99
  /**
100
  * Internal helper to build the raw specification string.
@@ -539,15 +571,95 @@ Return ONLY the final JSON object.`;
539
  }
540
  };
541
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
542
  /**
543
  * Multi-agent code generation.
544
  * Uses the detailed prompt to write, review, and polish PyTorch code.
545
  */
546
  export const generateCodeWithAgents = async (
547
- promptText: string,
548
- onStatusUpdate: (status: AgentStatus, log: string) => void,
549
- model: string = DEFAULT_MODEL
550
- ): Promise<string> => {
551
  const ai = getAiClient();
552
 
553
  // --- Step 1: Coder ---
@@ -563,6 +675,9 @@ Coding Standards:
563
  4. Use descriptive variable names.
564
  5. Include a robust 'if __name__ == "__main__":' block that instantiates the model and runs a dummy forward pass with torch.randn.
565
  6. Handle custom layer logic or external imports if specified.
 
 
 
566
 
567
  Return ONLY the Python code. No markdown backticks.`;
568
 
@@ -639,8 +754,21 @@ Return ONLY the final Python code. No markdown backticks.`;
639
  config: { systemInstruction: polisherSystemInstruction }
640
  });
641
  let finalCode = cleanJsonString(response.text);
 
 
 
 
 
 
 
 
 
 
 
 
 
642
  onStatusUpdate('complete', 'Code generation complete!');
643
- return finalCode;
644
  } catch(e) {
645
  throw new Error("Polisher agent failed to generate code.");
646
  }
 
4
  import { LAYER_DEFINITIONS } from '../constants';
5
 
6
  // --- SCHEMAS ---
7
+ const patchSchema = {
8
+ type: Type.OBJECT,
9
+ properties: {
10
+ reasoning: { type: Type.STRING, description: "Why these changes are being made." },
11
+ summary: { type: Type.STRING, description: "A concise summary of what was updated (e.g., 'Added dropout to encoder')." },
12
+ files_changed: { type: Type.ARRAY, items: { type: Type.STRING }, description: "List of files modified." },
13
+ patches: {
14
+ type: Type.ARRAY,
15
+ items: {
16
+ type: Type.OBJECT,
17
+ properties: {
18
+ search: { type: Type.STRING, description: "The exact code block to find. Must be unique." },
19
+ replace: { type: Type.STRING, description: "The code to replace it with." }
20
+ },
21
+ required: ["search", "replace"]
22
+ }
23
+ }
24
+ },
25
+ required: ["patches", "summary", "files_changed"]
26
+ };
27
+
28
+ const evaluationSchema = {
29
+ type: Type.OBJECT,
30
+ properties: {
31
+ score: { type: Type.NUMBER, description: "0-100 score of how well requirements were met." },
32
+ missing_components: { type: Type.ARRAY, items: { type: Type.STRING } },
33
+ bugs: { type: Type.ARRAY, items: { type: Type.STRING } },
34
+ improvement_tasks: { type: Type.ARRAY, items: { type: Type.STRING } }
35
+ },
36
+ required: ["score", "improvement_tasks"]
37
+ };
38
+
39
  const graphResponseSchema = {
40
  type: Type.OBJECT,
41
  properties: {
 
126
 
127
  export const DEFAULT_MODEL = 'gemini-2.5-flash';
128
 
129
+ export type AgentStatus = 'idle' | 'architect' | 'critic' | 'refiner' | 'evaluator' | 'debugger' | 'patcher' | 'complete' | 'error';
130
 
131
  /**
132
  * Internal helper to build the raw specification string.
 
571
  }
572
  };
573
 
574
+ /**
575
+ * Helper: Applies a list of patches to a code string.
576
+ */
577
+ export const applyPatches = (code: string, patches: { search: string, replace: string }[]): string => {
578
+ let updatedCode = code;
579
+ for (const patch of patches) {
580
+ if (updatedCode.includes(patch.search)) {
581
+ updatedCode = updatedCode.replace(patch.search, patch.replace);
582
+ } else {
583
+ console.warn("Patch failed: Search block not found.", patch.search);
584
+ }
585
+ }
586
+ return updatedCode;
587
+ };
588
+
589
+ /**
590
+ * Evaluates generated code against the original prompt.
591
+ */
592
+ export const evaluateCode = async (
593
+ prompt: string,
594
+ code: string,
595
+ model: string = DEFAULT_MODEL
596
+ ): Promise<{ score: number, missing_components: string[], bugs: string[], improvement_tasks: string[] }> => {
597
+ const ai = getAiClient();
598
+ try {
599
+ const response = await ai.models.generateContent({
600
+ model: model,
601
+ contents: `Original Prompt: "${prompt}"\n\nGenerated Code:\n${code}`,
602
+ config: {
603
+ systemInstruction: `You are a Senior QA Engineer. Compare the generated PyTorch code against the original prompt.
604
+ Identify any missing requirements, logical bugs, or incomplete components.
605
+ Generate a list of targeted improvement tasks.
606
+ Return the evaluation in JSON format.`,
607
+ responseMimeType: "application/json",
608
+ responseSchema: evaluationSchema
609
+ }
610
+ });
611
+ return JSON.parse(cleanJsonString(response.text));
612
+ } catch (error) {
613
+ console.error("Evaluation failed:", error);
614
+ return { score: 0, missing_components: [], bugs: [], improvement_tasks: ["Manual review required."] };
615
+ }
616
+ };
617
+
618
+ /**
619
+ * Generates patches for code based on instructions.
620
+ */
621
+ export const generateCodePatches = async (
622
+ code: string,
623
+ instructions: string,
624
+ model: string = DEFAULT_MODEL
625
+ ): Promise<{ reasoning: string, summary: string, files_changed: string[], patches: { search: string, replace: string }[] }> => {
626
+ const ai = getAiClient();
627
+ try {
628
+ const response = await ai.models.generateContent({
629
+ model: model,
630
+ contents: `Current Code:\n${code}\n\nInstructions for Modification:\n${instructions}`,
631
+ config: {
632
+ systemInstruction: `You are a Principal Software Engineer. Instead of rewriting the entire file, you provide targeted patches.
633
+ A patch consists of a 'search' block (the exact code to find) and a 'replace' block (the new code).
634
+ The 'search' block MUST be a unique, contiguous substring from the current code.
635
+ Include all necessary imports if they are missing.
636
+
637
+ Output Requirements:
638
+ 1. 'summary': A concise one-line description of the update.
639
+ 2. 'files_changed': An array of filenames (e.g., ["model.py"]).
640
+ 3. 'patches': The search/replace pairs.
641
+
642
+ Return the patches in JSON format.`,
643
+ responseMimeType: "application/json",
644
+ responseSchema: patchSchema
645
+ }
646
+ });
647
+ return JSON.parse(cleanJsonString(response.text));
648
+ } catch (error) {
649
+ console.error("Patch generation failed:", error);
650
+ throw error;
651
+ }
652
+ };
653
+
654
  /**
655
  * Multi-agent code generation.
656
  * Uses the detailed prompt to write, review, and polish PyTorch code.
657
  */
658
  export const generateCodeWithAgents = async (
659
+ promptText: string,
660
+ onStatusUpdate: (status: AgentStatus, log: string) => void,
661
+ model: string = DEFAULT_MODEL
662
+ ): Promise<{ code: string, evaluation?: any, initialPatches?: any }> => {
663
  const ai = getAiClient();
664
 
665
  // --- Step 1: Coder ---
 
675
  4. Use descriptive variable names.
676
  5. Include a robust 'if __name__ == "__main__":' block that instantiates the model and runs a dummy forward pass with torch.randn.
677
  6. Handle custom layer logic or external imports if specified.
678
+ 7. Initialization Strategy:
679
+ - Use Kaiming initialization (nn.init.kaiming_normal_) for Conv2d and Linear layers.
680
+ - CRITICAL: If using SiLU (nn.SiLU) as the activation, use nonlinearity='linear' (gain=1) in the Kaiming initialization instead of 'relu'. This better preserves feature variance for SiLU.
681
 
682
  Return ONLY the Python code. No markdown backticks.`;
683
 
 
754
  config: { systemInstruction: polisherSystemInstruction }
755
  });
756
  let finalCode = cleanJsonString(response.text);
757
+
758
+ // --- Step 4: Evaluator (New Step) ---
759
+ onStatusUpdate('evaluator', 'Evaluator Agent is verifying requirements...');
760
+ const evaluation = await evaluateCode(promptText, finalCode, model);
761
+
762
+ let initialPatches = null;
763
+ if (evaluation.score < 90 && evaluation.improvement_tasks.length > 0) {
764
+ onStatusUpdate('refiner', 'Applying automated improvements based on evaluation...');
765
+ const patchResult = await generateCodePatches(finalCode, evaluation.improvement_tasks.join("\n"), model);
766
+ finalCode = applyPatches(finalCode, patchResult.patches);
767
+ initialPatches = patchResult;
768
+ }
769
+
770
  onStatusUpdate('complete', 'Code generation complete!');
771
+ return { code: finalCode, evaluation, initialPatches };
772
  } catch(e) {
773
  throw new Error("Polisher agent failed to generate code.");
774
  }