Spaces:
Running
Running
owenkaplinsky
commited on
Commit
·
596096e
1
Parent(s):
009a2d4
Improve prompt; debug
Browse files- 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 |
-
-
|
|
|
|
| 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
|
| 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 |
-
|
| 480 |
-
To create a block, specify its type and parameters (if any).
|
| 481 |
|
| 482 |
-
|
| 483 |
|
| 484 |
-
|
| 485 |
|
| 486 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 487 |
|
| 488 |
-
|
|
|
|
|
|
|
| 489 |
|
| 490 |
-
|
| 491 |
|
| 492 |
-
|
| 493 |
|
| 494 |
-
|
| 495 |
-
|
|
|
|
| 496 |
|
| 497 |
-
|
| 498 |
|
| 499 |
-
|
| 500 |
-
recursively inside of this. Same thing for numbers and so on.
|
| 501 |
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 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"
|
| 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:
|