File size: 9,829 Bytes
c301b38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.

### Instruction:
Create a highly detailed and annotated mermaid diagram for the following process/workflow/information. Include details about inputs, outputs, data transformations, decisions points, and other significant components. Make sure it covers all steps and branches. Break down complex sequences into smaller parts if necessary. Include edge cases, error handling, and any special considerations. Create multiple diagrams for different aspects if needed. Annotate key functions, variables, control flows, and data structures with their respective names or values. Provide clear descriptions alongside each portion of the process to aid understanding.

To achieve this, follow these guidelines:

1. Start by identifying the main starting point of your input (e.g., a user action, external source, or data stream).
2. Trace the flow of execution through each stage in the process.
3. Identify critical data structures such as tables, queues, and files.
4. Highlight variable changes and manipulations.
5. Mark decision points and branching paths.
6. Note exception handling and corner case considerations.
7. Label external tools, resources, and human interventions.
8. Annotate each segment with its corresponding part of the overall process.
9. Use color or shading to differentiate between different stages or subprocesses.
10. Finally, review and refine the diagrams based on the provided information.

### Input:
import argparse
import json
import os
import requests
import subprocess
import tempfile

class MermaidDiagramGenerator:
    def __init__(self, theme='dark', background='transparent'):
        self._theme = theme
        self._background = background
        self._entries_dir = os.path.join(os.getcwd(), 'Entries')
        os.makedirs(self._entries_dir, exist_ok=True)

    def convert_to_image(self, mermaid_code, entry_number, output_number):
        clean_code = self._remove_mermaid_block_markers(mermaid_code)
        output_filename = f"entry_{entry_number}_{output_number}.png"
        output_path = os.path.join(self._entries_dir, output_filename)
        self._generate_image_from_code(clean_code, output_path)
        return output_path

    def _remove_mermaid_block_markers(self, code):
        code_lines = code.strip().splitlines()
        if code_lines[0].startswith("```mermaid") and code_lines[-1] == "```":
            return "\n".join(code_lines[1:-1]).strip()
        return code

    def _generate_image_from_code(self, mermaid_code, output_path):
        with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.mmd') as temp_file:
            temp_file.write(mermaid_code)
            input_path = temp_file.name
        result = subprocess.run(["mmdc", "-i", input_path, "-o", output_path, "-t", self._theme, "-b", self._background], shell=True, check=False)
        os.remove(input_path)
        if result.returncode != 0:
            raise ValueError("Mermaid diagram generation failed.")

def read_input(input_source):
    if os.path.isfile(input_source):
        filename, file_extension = os.path.splitext(input_source)
        if file_extension == '.json':
            with open(input_source, 'r') as file:
                return json.load(file)
        elif file_extension == '.txt':
            with open(input_source, 'r') as file:
                return [{"input": file.read()}]
    else:
        return [{"input": input_source}]

def generate_response(prompt, base_temperatures, stream, generator, entry_number, unique_outputs):
    # prompt_template = f"{prompt}\n\n```mermaid\n"

    prompt_template = """
    Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.
    
    ### Instruction:
    Create the mermaid diagram for the following input:

    ### Input:
    {input}
    
    ### Response:
    ```mermaid
    """.format(input=prompt)

    url = "http://127.0.0.1:5000/v1/completions"
    headers = {"Content-Type": "application/json"}
    dataset_entries = []

    for output_number, temp in enumerate(base_temperatures, start=1):
        while True:
            data = {
                "prompt": prompt_template,
                "max_tokens": 4096,
                "temperature": temp,
                "top_p": 1.0,
                "seed": -1,
                "top_k": 4,
                "repetition_penalty": 1.0,
                "guidance_scale": 1.0,
                "typical_p": 1.0,
                "stream": stream,
            }

            response = requests.post(url, headers=headers, json=data, verify=False)
            response_text = response.json()['choices'][0]['text'].strip()

            if response_text.endswith("```"):  # Check if response ends with ```
                response_text = response_text[:-3].strip()  # Remove ``` from the end

            if response_text not in unique_outputs:
                try:
                    image_path = generator.convert_to_image(response_text, entry_number, output_number)
                    print(f"Mermaid diagram generated at: {image_path}")
                    unique_outputs.add(response_text)
                    break
                except ValueError as e:
                    print(f"Validation failed, retrying... Error: {e}")
            else:
                temp += 0.1  # Adjust temperature if output is not unique

        dataset_entry = {
            "input": prompt,
            "output": f"```mermaid\n{response_text}\n```",
            "temperature": temp
        }
        dataset_entries.append(dataset_entry)

    return dataset_entries

def generate_unique_responses(input_data, base_temperatures, stream, generator):
    all_entries = []
    unique_outputs = set()

    for entry_number, entry in enumerate(input_data, start=1):
        prompt = entry.get("input", "")
        if prompt:
            entries = generate_response(prompt, base_temperatures, stream, generator, entry_number, unique_outputs)
            all_entries.extend(entries)  # Extend the list with new entries

    return all_entries

def main(input_source, stream=False):
    generator = MermaidDiagramGenerator()
    input_data = read_input(input_source)
    base_temperatures = [i / 10 for i in range(5, 11)]  # Adjusted for batch of unique outputs per input
    output_file = "output.json"

    all_entries = generate_unique_responses(input_data, base_temperatures, stream, generator)

    # Write all entries to the JSON file at once
    with open(output_file, "w") as f:
        json.dump(all_entries, f, indent=4)  # Dump the entire list of entries into the file

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Generate unique responses and validate Mermaid diagrams.")
    parser.add_argument('input_source', type=str, help='A multi-line string, path to a .txt file, or a .json file with prompts.')
    parser.add_argument('--stream', action='store_true', help='Use streaming responses.')
    args = parser.parse_args()
    
    main(args.input_source, args.stream)

### Response:
```mermaid
graph TB;
    A[Start] --> B[Read Input Source];
    B --> C{Input Source Type};
    C --> |File| D[Read File Content];
    C --> |String| E[Split String Prompts];
    D --> F[Convert to JSON];
    E --> F;
    F --> G[Get Input Prompts];
    
    G --> H[Initialize Generator];
    H --> I[Set Base Temperatures];
    I --> J[Set Stream Flag];
    J --> K[Set Output File];
    
    K --> L[Generate Unique Responses];
    L --> M[Write All Entries to JSON];
    M --> N[End];
    
    subgraph Generate Unique Responses
        direction TB;
        L --> O[Loop Through Input Prompts];
        O --> P[Get Prompt];
        P --> Q[Generate Response]; 
        Q --> R[Validate Mermaid Diagram]; 
        R --> S[Add to All Entries]; 
        S --> T{Unique Output?}; 
        T --> |Yes| U[Increment Temperature]; 
        U --> O; 
        T --> |No| V[Retry]; 
        V --> O; 
    end; 
    
    subgraph Generate Response
        direction TB;
        Q --> W[Call OpenAI API]; 
        W --> X[Extract Response Text]; 
        X --> Y[Generate Mermaid Diagram]; 
        Y --> Z[Validate Mermaid Diagram]; 
        Z --> A1[Add to All Entries]; 
    end; 
    
    subgraph Validate Mermaid Diagram
        direction TB;
        R --> B1[Convert to Image]; 
        B1 --> C1[Check Image Validity]; 
        C1 --> D1{Valid?}; 
        D1 --> |Yes| E1[Return True]; 
        D1 --> |No| F1[Retry]; 
        F1 --> R; 
    end; 
    
    subgraph Generate Mermaid Diagram
        direction TB;
        Y --> G1[Remove Block Markers]; 
        G1 --> H1[Generate Image from Code]; 
        H1 --> I1[Return Image Path]; 
    end; 
    
    subgraph Convert to Image
        direction TB;
        B1 --> C2[Generate Command]; 
        C2 --> D2[Run Command]; 
        D2 --> E2[Check Return Code]; 
        E2 --> |0| F2[Return Image Path]; 
        E2 --> |!=0| G2[Raise Error]; 
    end; 
    
    subgraph Remove Block Markers
        direction TB;
        G1 --> H2[Split Lines]; 
        H2 --> I2[Check First Line]; 
        I2 --> |Starts With| J2[Remove Line]; 
        I2 --> |Doesn't Start| K2[Keep Line]; 
        J2 --> L2[Join Remaining Lines]; 
        K2 --> L2; 
        L2 --> M2[Return Clean Code]; 
    end; 
    
    subgraph Generate Command
        direction TB;
        C2 --> D3[Build Command]; 
        D3 --> E3[Return Command]; 
    end; 
    
    subgraph Run Command
        direction TB;
        D2 --> F3[Run Command]; 
        F3 --> G3[Check Return Code]; 
        G3 --> |0| H3[Return Image Path]; 
        G3 --> |!=0| I3[Raise Error]; 
    end; 
```