owenkaplinsky commited on
Commit
596096e
·
1 Parent(s): 009a2d4

Improve prompt; debug

Browse files
Files changed (1) hide show
  1. project/chat.py +56 -42
project/chat.py CHANGED
@@ -10,6 +10,7 @@ import gradio as gr
10
  import asyncio
11
  import queue
12
  import json
 
13
 
14
  # Initialize OpenAI client (will be updated when API key is set)
15
  client = None
@@ -434,8 +435,7 @@ You’ll receive the workspace state in this format:
434
  `blockId | block_name(inputs(input_name: value))`
435
 
436
  **Special cases:**
437
- - `create_mcp` and `func_def` use
438
- `blockId | block_name(inputs(input_name: type), outputs(output_name: value))`
439
  - Indentation or nesting shows logic hierarchy (like loops or conditionals).
440
  - The `blockId` before the pipe `|` is each block’s unique identifier.
441
 
@@ -443,16 +443,11 @@ You’ll receive the workspace state in this format:
443
 
444
  ### Your job
445
  - Help users understand or fix their MCP logic in natural, human language.
446
- - Never mention the internal block syntax or say “multi-context-protocol.” Just call it **MCP**.
 
447
  - Focus on what the code *does* and what the user is trying to achieve, not on the raw block format.
448
-
449
- ---
450
-
451
- ### Using Tools
452
- Before using any tool, **explicitly plan** what you will do.
453
- You can only use **one tool per message** - NEVER EVER combine multiple tool calls in one message.
454
- If you need two actions, use two messages.
455
- ```
456
 
457
  ---
458
 
@@ -462,11 +457,9 @@ You can execute the MCP directly and get the result back.
462
  ---
463
 
464
  ### Deleting Blocks
465
- Each block starts with its ID, like `blockId | block_name(...)`.
466
- To delete one, end your message with:
467
- You can delete any block except the main `create_mcp` block.
468
- You can see the ID to the left of each block it will be a jarble of characters
469
- looking something like:
470
 
471
  `blockId | code`
472
 
@@ -476,42 +469,60 @@ the correct block.
476
  ---
477
 
478
  ### Creating Blocks
479
- You can create new blocks in the workspace.
480
- To create a block, specify its type and parameters (if any).
481
 
482
- If you want to create a block inside of a block, do it like this:
483
 
484
- block_name(inputs(value_name: block_name2(inputs(value_name2: value))))
485
 
486
- Where you specify inputs() per block, even if it's inside of another block.
 
 
 
 
 
 
 
 
487
 
488
- List of blocks:
 
 
489
 
490
- {blocks_context}
491
 
492
- YOU CANNOT CREATE A MCP BLOCK OR EDIT ITS INPUTS. YOU MUST TELL THE USER TO DO SO.
493
 
494
- For creating blocks, keep in mind: for `value`, if you want to put a string, you need to
495
- put a string block inside of it - you can't just put the string. For example:
 
496
 
497
- text_isEmpty(inputs(VALUE: "text"))
498
 
499
- This wouldn't work - you can't put a raw string in, you need to create a text block
500
- recursively inside of this. Same thing for numbers and so on.
501
 
502
- To put a block inside another (like an if inside a repeat), use two create block commands:
503
- first for the outer block, then for the inner block under it. This only applies to
504
- non-outputting blocks; outputting blocks (like a number in an addition) can be nested
505
- in one command.
 
 
 
 
 
 
 
 
 
 
 
506
 
507
  For blocks that allow infinite things (like ...N) you do not need to provide any inputs
508
  if you want it to be blank.
509
 
510
- ---
511
-
512
- Don't share the DSL (DSL being the custom Blockly language) info with the user such
513
- as when creating a block unless they ask about it. It's not sensitive so you can
514
- share it with the user if they ask.
515
  """
516
 
517
  tools = [
@@ -648,20 +659,23 @@ share it with the user if they ask.
648
  function_name = tool_call.function.name
649
  function_args = json.loads(tool_call.function.arguments)
650
 
651
- print(f"[TOOL CALL] {function_name} with args: {function_args}")
652
-
653
  # Execute the appropriate function
654
  tool_result = None
655
  result_label = ""
656
 
657
  if function_name == "delete_block":
658
  block_id = function_args.get("id", "")
 
659
  tool_result = delete_block(block_id)
660
  result_label = "Delete Operation"
661
 
662
  elif function_name == "create_block":
663
  command = function_args.get("command", "")
664
  under_block_id = function_args.get("under", None)
 
 
 
 
665
  tool_result = create_block(command, under_block_id)
666
  result_label = "Create Operation"
667
 
@@ -673,12 +687,12 @@ share it with the user if they ask.
673
  # Format as key=value for execute_mcp
674
  params.append(f"{key}=\"{value}\"")
675
  mcp_call = f"create_mcp({', '.join(params)})"
676
- print(f"[MCP CALL] Executing: {mcp_call}")
677
  tool_result = execute_mcp(mcp_call)
678
  result_label = "MCP Execution Result"
679
 
680
  if tool_result:
681
- print(f"[TOOL RESULT] {tool_result}")
682
 
683
  # Yield the tool result
684
  if accumulated_response:
 
10
  import asyncio
11
  import queue
12
  import json
13
+ from colorama import Fore, Style
14
 
15
  # Initialize OpenAI client (will be updated when API key is set)
16
  client = None
 
435
  `blockId | block_name(inputs(input_name: value))`
436
 
437
  **Special cases:**
438
+ - `create_mcp` and `func_def` use `blockId | block_name(inputs(input_name: type), outputs(output_name: value))`
 
439
  - Indentation or nesting shows logic hierarchy (like loops or conditionals).
440
  - The `blockId` before the pipe `|` is each block’s unique identifier.
441
 
 
443
 
444
  ### Your job
445
  - Help users understand or fix their MCP logic in natural, human language.
446
+ - You may reference the internal block syntax for your own understanding, but never show or explain it to the
447
+ user unless they explicitly ask.
448
  - Focus on what the code *does* and what the user is trying to achieve, not on the raw block format.
449
+ - In your first message, you may either respond normally or call a tool. If you call a tool, you must first
450
+ explain your intended plan and the steps you will take, then perform the tool call in the same message.
 
 
 
 
 
 
451
 
452
  ---
453
 
 
457
  ---
458
 
459
  ### Deleting Blocks
460
+ - Each block starts with its ID, like `blockId | block_name(...)`.
461
+ - To delete a block, specify its block ID. Each block ID is a unique random alphanumeric string shown to the left of the block.
462
+ - You can delete any block except the main `create_mcp` block.
 
 
463
 
464
  `blockId | code`
465
 
 
469
  ---
470
 
471
  ### Creating Blocks
472
+ List of blocks:
 
473
 
474
+ {blocks_context}
475
 
476
+ ---
477
 
478
+ You can create new blocks in the workspace by specifying the block type and its input parameters, if it has any.
479
+ You cannot create a MCP block or edit its inputs or outputs.
480
+ There are two kinds of nesting in Blockly:
481
+ 1. **Statement-level nesting (main-level blocks)**
482
+ These are blocks that represent actions or structures, such as loops or conditionals, which can contain other blocks *under* them.
483
+ To create this kind of nesting, use **two separate `create_block` commands**:
484
+ - First, create the outer block (for example, a `repeat` or `if` block).
485
+ - Then, create the inner block *under* it using the `under` parameter.
486
+ Example: putting an `if` block inside a `repeat` block.
487
 
488
+ 2. **Value-level nesting (output blocks)**
489
+ These are blocks that produce a value (like a number, text, or expression). They can’t exist alone in the workspace - they must
490
+ be nested inside another block’s input. To create these, you can nest them directly in a single command, for example:
491
 
492
+ math_arithmetic(inputs(A: math_number(inputs(NUM: 1)), B: math_number(inputs(NUM: 1))))
493
 
494
+ Here, the two `math_number` blocks are nested inside the `math_arithmetic` block in one call.
495
 
496
+ When creating blocks, you are never allowed to insert raw text or numbers directly into a block's inputs.
497
+ Every value must be enclosed inside the correct block type that represents that value.
498
+ Failing to do this will cause the block to be invalid and unusable.
499
 
500
+ Example of what you must NOT do:
501
 
502
+ `text_isEmpty(inputs(VALUE: "text"))`
 
503
 
504
+ This is invalid because "text" is a raw string and not a block.
505
+
506
+ The correct and required form wraps the string inside a text block:
507
+
508
+ `text_isEmpty(inputs(VALUE: text(inputs(TEXT: "text"))))`
509
+
510
+ This is valid because it uses a text block as the value.
511
+
512
+ This rule is absolute and applies to all value types:
513
+ - Strings must always use a text block.
514
+ - Numbers must always use a math_number block.
515
+ - Booleans, lists, colors, and every other type must always use their correct block type.
516
+
517
+ If a block has a value input, that input must always contain another block.
518
+ You are not permitted to use raw values under any circumstance.
519
 
520
  For blocks that allow infinite things (like ...N) you do not need to provide any inputs
521
  if you want it to be blank.
522
 
523
+ When creating blocks, you are unable to put an outputting block inside of another block
524
+ which already exists. If you are trying to nest input blocks, you must create them all
525
+ in one call.
 
 
526
  """
527
 
528
  tools = [
 
659
  function_name = tool_call.function.name
660
  function_args = json.loads(tool_call.function.arguments)
661
 
 
 
662
  # Execute the appropriate function
663
  tool_result = None
664
  result_label = ""
665
 
666
  if function_name == "delete_block":
667
  block_id = function_args.get("id", "")
668
+ print(Fore.YELLOW + f"Agent ran delete with ID `{block_id}`." + Style.RESET_ALL)
669
  tool_result = delete_block(block_id)
670
  result_label = "Delete Operation"
671
 
672
  elif function_name == "create_block":
673
  command = function_args.get("command", "")
674
  under_block_id = function_args.get("under", None)
675
+ if under_block_id == None:
676
+ print(Fore.YELLOW + f"Agent ran create with command `{command}`." + Style.RESET_ALL)
677
+ else:
678
+ print(Fore.YELLOW + f"Agent ran create with command: `{command}`, under block ID: `{under_block_id}`." + Style.RESET_ALL)
679
  tool_result = create_block(command, under_block_id)
680
  result_label = "Create Operation"
681
 
 
687
  # Format as key=value for execute_mcp
688
  params.append(f"{key}=\"{value}\"")
689
  mcp_call = f"create_mcp({', '.join(params)})"
690
+ print(Fore.YELLOW + f"Agent ran MCP with inputs: {mcp_call}." + Style.RESET_ALL)
691
  tool_result = execute_mcp(mcp_call)
692
  result_label = "MCP Execution Result"
693
 
694
  if tool_result:
695
+ print(Fore.YELLOW + f"[TOOL RESULT] {tool_result}" + Style.RESET_ALL)
696
 
697
  # Yield the tool result
698
  if accumulated_response: