flen-crypto commited on
Commit
86de218
·
verified ·
1 Parent(s): d93c7ba

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +334 -0
app.py ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include <stdbool.h>
5
+ #include <ctype.h>
6
+
7
+ #define MAX_COMMAND_LEN 4096
8
+ #define MAX_DIRECTIVES 16
9
+ #define MAX_VALUE_LEN 1024
10
+
11
+ typedef enum {
12
+ UI_NONE,
13
+ UI_STREAMLIT,
14
+ UI_GRADIO,
15
+ UI_HTML
16
+ } UiShell;
17
+
18
+ typedef enum {
19
+ MEDIA_NONE,
20
+ MEDIA_TEXT_TO_IMAGE,
21
+ MEDIA_IMAGE_TO_IMAGE,
22
+ MEDIA_IMAGE_TO_VIDEO,
23
+ MEDIA_TEXT_TO_VIDEO
24
+ } MediaType;
25
+
26
+ typedef struct {
27
+ char main_prompt[MAX_COMMAND_LEN];
28
+ UiShell ui_shell;
29
+ bool web_search_enabled;
30
+ char model_id[MAX_VALUE_LEN];
31
+ struct {
32
+ MediaType type;
33
+ char prompt[MAX_COMMAND_LEN];
34
+ } media_ops[MAX_DIRECTIVES];
35
+ int media_count;
36
+ char url_redesign[MAX_VALUE_LEN];
37
+ char source_image[MAX_VALUE_LEN];
38
+ char reference_doc[MAX_VALUE_LEN];
39
+ char others[MAX_DIRECTIVES][MAX_VALUE_LEN];
40
+ int other_count;
41
+ } CommandSpec;
42
+
43
+ typedef struct {
44
+ char message[MAX_VALUE_LEN];
45
+ char type[32]; // "missing-url", "missing-image", "unknown-directive", "empty-value"
46
+ } Validation;
47
+
48
+ // Helper: trim whitespace from start and end of string
49
+ void trim(char *str) {
50
+ char *end;
51
+ while (isspace(*str)) str++;
52
+ if (*str == '\0') return;
53
+ end = str + strlen(str) - 1;
54
+ while (end > str && isspace(*end)) end--;
55
+ *(end + 1) = '\0';
56
+ }
57
+
58
+ // Helper: check if string starts with prefix (case-insensitive)
59
+ bool starts_with(const char *str, const char *prefix) {
60
+ size_t len = strlen(prefix);
61
+ if (strlen(str) < len) return false;
62
+ for (size_t i = 0; i < len; i++) {
63
+ if (tolower(str[i]) != tolower(prefix[i])) return false;
64
+ }
65
+ return true;
66
+ }
67
+
68
+ // Helper: extract value after colon (trim whitespace)
69
+ char* extract_value(const char *directive) {
70
+ char *colon = strchr(directive, ':');
71
+ if (!colon) return NULL;
72
+ char *value = colon + 1;
73
+ while (*value && isspace(*value)) value++;
74
+ return value;
75
+ }
76
+
77
+ // Split command by top-level commas (ignore commas inside URLs)
78
+ int split_command(const char *input, char *parts[], int max_parts) {
79
+ int count = 0;
80
+ char *buf = strdup(input);
81
+ char *ptr = buf;
82
+ bool in_url = false;
83
+ char quote = '\0';
84
+
85
+ for (int i = 0; ptr[i] != '\0'; i++) {
86
+ if (ptr[i] == '"' || ptr[i] == '\'') {
87
+ if (quote == '\0') quote = ptr[i];
88
+ else if (quote == ptr[i]) quote = '\0';
89
+ }
90
+ if (quote == '\0' && ptr[i] == ':' && i > 0 && ptr[i-1] == 'h') {
91
+ // Look ahead for http(s)://
92
+ if (i >= 4 && strncmp(&ptr[i-4], "http", 4) == 0) in_url = true;
93
+ }
94
+ if (quote == '\0' && !in_url && ptr[i] == ',' && i > 0 && ptr[i-1] != '\\') {
95
+ ptr[i] = '\0';
96
+ if (count < max_parts) {
97
+ parts[count] = ptr;
98
+ trim(parts[count]);
99
+ count++;
100
+ }
101
+ ptr = &ptr[i+1];
102
+ i = -1; // reset to re-check from start of new segment
103
+ }
104
+ if (in_url && ptr[i] == ' ') in_url = false; // URL ends at space
105
+ }
106
+ if (count < max_parts && strlen(ptr) > 0) {
107
+ parts[count] = ptr;
108
+ trim(parts[count]);
109
+ count++;
110
+ }
111
+ free(buf);
112
+ return count;
113
+ }
114
+
115
+ // Parse a single directive
116
+ bool parse_directive(const char *directive, CommandSpec *spec) {
117
+ char lower_dir[1024];
118
+ strcpy(lower_dir, directive);
119
+ for (int i = 0; lower_dir[i]; i++) lower_dir[i] = tolower(lower_dir[i]);
120
+
121
+ if (starts_with(lower_dir, "use streamlit")) {
122
+ spec->ui_shell = UI_STREAMLIT;
123
+ return true;
124
+ }
125
+ if (starts_with(lower_dir, "use gradio")) {
126
+ spec->ui_shell = UI_GRADIO;
127
+ return true;
128
+ }
129
+ if (starts_with(lower_dir, "use html")) {
130
+ spec->ui_shell = UI_HTML;
131
+ return true;
132
+ }
133
+ if (starts_with(lower_dir, "enable web search")) {
134
+ spec->web_search_enabled = true;
135
+ return true;
136
+ }
137
+ if (starts_with(lower_dir, "disable web search")) {
138
+ spec->web_search_enabled = false;
139
+ return true;
140
+ }
141
+ if (starts_with(lower_dir, "model:")) {
142
+ char *val = extract_value(directive);
143
+ if (val && strlen(val) > 0) {
144
+ strncpy(spec->model_id, val, MAX_VALUE_LEN - 1);
145
+ spec->model_id[MAX_VALUE_LEN - 1] = '\0';
146
+ return true;
147
+ } else {
148
+ return false; // empty value
149
+ }
150
+ }
151
+ if (starts_with(lower_dir, "redesign ")) {
152
+ char *url = extract_value(directive);
153
+ if (url && strlen(url) > 0) {
154
+ strncpy(spec->url_redesign, url, MAX_VALUE_LEN - 1);
155
+ spec->url_redesign[MAX_VALUE_LEN - 1] = '\0';
156
+ return true;
157
+ } else {
158
+ return false; // missing URL
159
+ }
160
+ }
161
+ if (starts_with(lower_dir, "generate images:")) {
162
+ if (spec->media_count < MAX_DIRECTIVES) {
163
+ char *prompt = extract_value(directive);
164
+ if (prompt && strlen(prompt) > 0) {
165
+ spec->media_ops[spec->media_count].type = MEDIA_TEXT_TO_IMAGE;
166
+ strncpy(spec->media_ops[spec->media_count].prompt, prompt, MAX_COMMAND_LEN - 1);
167
+ spec->media_ops[spec->media_count].prompt[MAX_COMMAND_LEN - 1] = '\0';
168
+ spec->media_count++;
169
+ return true;
170
+ }
171
+ }
172
+ return false;
173
+ }
174
+ if (starts_with(lower_dir, "image to image:")) {
175
+ if (spec->media_count < MAX_DIRECTIVES) {
176
+ char *prompt = extract_value(directive);
177
+ if (prompt && strlen(prompt) > 0) {
178
+ spec->media_ops[spec->media_count].type = MEDIA_IMAGE_TO_IMAGE;
179
+ strncpy(spec->media_ops[spec->media_count].prompt, prompt, MAX_COMMAND_LEN - 1);
180
+ spec->media_ops[spec->media_count].prompt[MAX_COMMAND_LEN - 1] = '\0';
181
+ spec->media_count++;
182
+ return true;
183
+ }
184
+ }
185
+ return false;
186
+ }
187
+ if (starts_with(lower_dir, "image to video:")) {
188
+ if (spec->media_count < MAX_DIRECTIVES) {
189
+ char *prompt = extract_value(directive);
190
+ if (prompt && strlen(prompt) > 0) {
191
+ spec->media_ops[spec->media_count].type = MEDIA_IMAGE_TO_VIDEO;
192
+ strncpy(spec->media_ops[spec->media_count].prompt, prompt, MAX_COMMAND_LEN - 1);
193
+ spec->media_ops[spec->media_count].prompt[MAX_COMMAND_LEN - 1] = '\0';
194
+ spec->media_count++;
195
+ return true;
196
+ }
197
+ }
198
+ return false;
199
+ }
200
+ if (starts_with(lower_dir, "text to video:")) {
201
+ if (spec->media_count < MAX_DIRECTIVES) {
202
+ char *prompt = extract_value(directive);
203
+ if (prompt && strlen(prompt) > 0) {
204
+ spec->media_ops[spec->media_count].type = MEDIA_TEXT_TO_VIDEO;
205
+ strncpy(spec->media_ops[spec->media_count].prompt, prompt, MAX_COMMAND_LEN - 1);
206
+ spec->media_ops[spec->media_count].prompt[MAX_COMMAND_LEN - 1] = '\0';
207
+ spec->media_count++;
208
+ return true;
209
+ }
210
+ }
211
+ return false;
212
+ }
213
+
214
+ // Unknown directive - treat as part of main prompt (non-fatal)
215
+ return false;
216
+ }
217
+
218
+ // Parse entire command string into CommandSpec
219
+ CommandSpec parse_command(const char *input) {
220
+ CommandSpec spec = {0};
221
+ strcpy(spec.main_prompt, input);
222
+
223
+ char *parts[MAX_DIRECTIVES + 1];
224
+ int n = split_command(input, parts, MAX_DIRECTIVES + 1);
225
+
226
+ if (n == 0) return spec;
227
+
228
+ // First part is main prompt (unless it's a redesign)
229
+ bool found_redesign = false;
230
+ for (int i = 0; i < n; i++) {
231
+ if (starts_with(parts[i], "redesign ")) {
232
+ parse_directive(parts[i], &spec);
233
+ found_redesign = true;
234
+ }
235
+ }
236
+
237
+ if (!found_redesign) {
238
+ // Extract main prompt as everything before first directive
239
+ char *first = parts[0];
240
+ if (strlen(first) > 0) {
241
+ strncpy(spec.main_prompt, first, MAX_COMMAND_LEN - 1);
242
+ spec.main_prompt[MAX_COMMAND_LEN - 1] = '\0';
243
+ }
244
+ }
245
+
246
+ // Parse modifiers
247
+ for (int i = 0; i < n; i++) {
248
+ if (starts_with(parts[i], "redesign ")) continue; // Already handled
249
+ if (!parse_directive(parts[i], &spec)) {
250
+ // Unknown directive — do nothing (per spec: non-fatal, kept in main prompt)
251
+ }
252
+ }
253
+
254
+ // Default model if not set
255
+ if (strlen(spec.model_id) == 0) {
256
+ strcpy(spec.model_id, "default-model");
257
+ }
258
+
259
+ return spec;
260
+ }
261
+
262
+ // Validate command against attachments (simplified mock)
263
+ Validation validate_command(CommandSpec *spec, bool has_source_image) {
264
+ Validation v = {0};
265
+ if (strlen(spec->url_redesign) > 0 && !strstr(spec->url_redesign, "http")) {
266
+ strcpy(v.message, "URL required for redesign");
267
+ strcpy(v.type, "missing-url");
268
+ return v;
269
+ }
270
+ for (int i = 0; i < spec->media_count; i++) {
271
+ if ((spec->media_ops[i].type == MEDIA_IMAGE_TO_IMAGE || spec->media_ops[i].type == MEDIA_IMAGE_TO_VIDEO) && !has_source_image) {
272
+ strcpy(v.message, "No source image attached");
273
+ strcpy(v.type, "missing-image");
274
+ return v;
275
+ }
276
+ }
277
+ // No errors
278
+ v.type[0] = '\0';
279
+ return v;
280
+ }
281
+
282
+ // Apply command to system state (mock implementation)
283
+ void apply_command(CommandSpec *spec) {
284
+ printf("[APPLYING COMMAND]\n");
285
+ printf("Main Prompt: %s\n", spec->main_prompt);
286
+ printf("UI Shell: ");
287
+ switch (spec->ui_shell) {
288
+ case UI_STREAMLIT: printf("Streamlit\n"); break;
289
+ case UI_GRADIO: printf("Gradio\n"); break;
290
+ case UI_HTML: printf("HTML\n"); break;
291
+ default: printf("None\n"); break;
292
+ }
293
+ printf("Web Search: %s\n", spec->web_search_enabled ? "Enabled" : "Disabled");
294
+ printf("Model: %s\n", spec->model_id);
295
+ if (strlen(spec->url_redesign) > 0) {
296
+ printf("Redesign URL: %s\n", spec->url_redesign);
297
+ }
298
+ for (int i = 0; i < spec->media_count; i++) {
299
+ char *type_str = "unknown";
300
+ switch (spec->media_ops[i].type) {
301
+ case MEDIA_TEXT_TO_IMAGE: type_str = "Text→Image"; break;
302
+ case MEDIA_IMAGE_TO_IMAGE: type_str = "Image→Image"; break;
303
+ case MEDIA_IMAGE_TO_VIDEO: type_str = "Image→Video"; break;
304
+ case MEDIA_TEXT_TO_VIDEO: type_str = "Text→Video"; break;
305
+ }
306
+ printf("Media: %s → \"%s\"\n", type_str, spec->media_ops[i].prompt);
307
+ }
308
+ }
309
+
310
+ // Main CLI entry point
311
+ int main() {
312
+ char command[MAX_COMMAND_LEN];
313
+ printf("Command Palette DSL (Type 'quit' to exit)\n");
314
+
315
+ while (true) {
316
+ printf("> ");
317
+ if (!fgets(command, sizeof(command), stdin)) break;
318
+ command[strcspn(command, "\n")] = 0; // remove newline
319
+
320
+ if (strcmp(command, "quit") == 0) break;
321
+
322
+ CommandSpec spec = parse_command(command);
323
+ Validation validation = validate_command(&spec, false); // Mock: no image attached
324
+
325
+ if (validation.type[0] != '\0') {
326
+ printf("❌ Validation Error: [%s] %s\n", validation.type, validation.message);
327
+ }
328
+
329
+ apply_command(&spec);
330
+ printf("\n");
331
+ }
332
+
333
+ return 0;
334
+ }