Use real web sessions for action execution
Remove mock/test session requirement when action != null This allows database updates to persist when action is executed through MCP.
Showing
1 changed file
with
36 additions
and
32 deletions
| ... | @@ -606,7 +606,8 @@ | ... | @@ -606,7 +606,8 @@ |
| 606 | <description>Execute a screen as an MCP tool</description> | 606 | <description>Execute a screen as an MCP tool</description> |
| 607 | <in-parameters> | 607 | <in-parameters> |
| 608 | <parameter name="screenPath" required="true"/> | 608 | <parameter name="screenPath" required="true"/> |
| 609 | <parameter name="parameters" type="Map"><description>Parameters to pass to the screen</description></parameter> | 609 | <parameter name="parameters" type="Map"><description>Parameters to pass to screen</description></parameter> |
| 610 | <parameter name="action"><description>Action being processed: if not null, use real screen rendering instead of test mock</description></parameter> | ||
| 610 | <parameter name="renderMode" default="mcp"><description>Render mode: mcp, text, html, xml, vuet, qvt</description></parameter> | 611 | <parameter name="renderMode" default="mcp"><description>Render mode: mcp, text, html, xml, vuet, qvt</description></parameter> |
| 611 | <parameter name="sessionId"><description>Session ID for user context restoration</description></parameter> | 612 | <parameter name="sessionId"><description>Session ID for user context restoration</description></parameter> |
| 612 | <parameter name="subscreenName"><description>Optional subscreen name for dot notation paths</description></parameter> | 613 | <parameter name="subscreenName"><description>Optional subscreen name for dot notation paths</description></parameter> |
| ... | @@ -628,15 +629,18 @@ def startTime = System.currentTimeMillis() | ... | @@ -628,15 +629,18 @@ def startTime = System.currentTimeMillis() |
| 628 | ec.context.putAll(parameters) | 629 | ec.context.putAll(parameters) |
| 629 | } | 630 | } |
| 630 | 631 | ||
| 632 | // Check if action is being processed - use real screen rendering if so | ||
| 633 | def isActionExecution = parameters?.action != null | ||
| 634 | |||
| 631 | // Try to render screen content for LLM consumption | 635 | // Try to render screen content for LLM consumption |
| 632 | def output = null | 636 | def output = null |
| 633 | def screenUrl = "http://localhost:8080/${screenPath}" | 637 | def screenUrl = "http://localhost:8080/${screenPath}" |
| 634 | def isError = false | 638 | def isError = false |
| 635 | 639 | ||
| 636 | try { | 640 | try { |
| 637 | ec.logger.info("MCP Screen Execution: Attempting to render screen ${screenPath} using ScreenTest with proper root screen") | 641 | ec.logger.info("MCP Screen Execution: Attempting to render screen ${screenPath} using ScreenTest with proper root screen, action=${parameters?.action}") |
| 638 | 642 | ||
| 639 | // For ScreenTest to work properly, we need to use the correct root screen | 643 | // For ScreenTest to work properly, we need to use correct root screen |
| 640 | def testScreenPath = screenPath | 644 | def testScreenPath = screenPath |
| 641 | def rootScreen = "component://webroot/screen/webroot.xml" | 645 | def rootScreen = "component://webroot/screen/webroot.xml" |
| 642 | 646 | ||
| ... | @@ -647,7 +651,7 @@ def startTime = System.currentTimeMillis() | ... | @@ -647,7 +651,7 @@ def startTime = System.currentTimeMillis() |
| 647 | def pathAfterComponent = screenPath.substring(12).replace('.xml','') // Remove "component://" | 651 | def pathAfterComponent = screenPath.substring(12).replace('.xml','') // Remove "component://" |
| 648 | def pathParts = pathAfterComponent.split("/") | 652 | def pathParts = pathAfterComponent.split("/") |
| 649 | 653 | ||
| 650 | // Check if the target screen itself is standalone | 654 | // Check if target screen itself is standalone |
| 651 | try { | 655 | try { |
| 652 | targetScreenDef = ec.screen.getScreenDefinition(screenPath) | 656 | targetScreenDef = ec.screen.getScreenDefinition(screenPath) |
| 653 | if (targetScreenDef?.screenNode) { | 657 | if (targetScreenDef?.screenNode) { |
| ... | @@ -664,7 +668,7 @@ def startTime = System.currentTimeMillis() | ... | @@ -664,7 +668,7 @@ def startTime = System.currentTimeMillis() |
| 664 | } | 668 | } |
| 665 | 669 | ||
| 666 | if (!isStandalone) { | 670 | if (!isStandalone) { |
| 667 | // Check if the screen path itself is a valid screen definition | 671 | // Check if screen path itself is a valid screen definition |
| 668 | try { | 672 | try { |
| 669 | if (ec.screen.getScreenDefinition(screenPath)) { | 673 | if (ec.screen.getScreenDefinition(screenPath)) { |
| 670 | rootScreen = screenPath | 674 | rootScreen = screenPath |
| ... | @@ -678,42 +682,42 @@ def startTime = System.currentTimeMillis() | ... | @@ -678,42 +682,42 @@ def startTime = System.currentTimeMillis() |
| 678 | testScreenPath = testScreenPath.substring("webroot/".length()) | 682 | testScreenPath = testScreenPath.substring("webroot/".length()) |
| 679 | } | 683 | } |
| 680 | } else { | 684 | } else { |
| 681 | def componentName = pathParts[0] | ||
| 682 | def remainingPath = pathParts[1..-1].join("/") | ||
| 683 | |||
| 684 | // Try to find the actual root screen for this component | ||
| 685 | def componentRootScreen = null | ||
| 686 | def possibleRootScreens = ["${componentName}.xml", "${componentName}Admin.xml", "${componentName}Root.xml"] | ||
| 687 | |||
| 688 | for (rootScreenName in possibleRootScreens) { | ||
| 689 | def candidateRoot = "component://${componentName}/screen/${rootScreenName}" | ||
| 690 | try { | ||
| 691 | if (ec.screen.getScreenDefinition(candidateRoot)) { | ||
| 692 | componentRootScreen = candidateRoot | ||
| 693 | break | ||
| 694 | } | ||
| 695 | } catch (Exception e) {} | ||
| 696 | } | ||
| 697 | |||
| 698 | if (componentRootScreen) { | ||
| 699 | rootScreen = componentRootScreen | ||
| 700 | testScreenPath = remainingPath | ||
| 701 | } else { | ||
| 702 | rootScreen = screenPath | 685 | rootScreen = screenPath |
| 703 | testScreenPath = "" | 686 | testScreenPath = "" |
| 704 | } | 687 | } |
| 705 | } | 688 | } |
| 689 | } catch (Exception e) {} | ||
| 706 | } | 690 | } |
| 707 | } catch (Exception e) { | 691 | |
| 708 | // Same as above fallback | 692 | } else { |
| 709 | rootScreen = screenPath | 693 | rootScreen = screenPath |
| 710 | testScreenPath = "" | 694 | testScreenPath = "" |
| 711 | } | 695 | } |
| 712 | } | ||
| 713 | } | ||
| 714 | 696 | ||
| 715 | // Regular screen rendering with current user context - use our custom ScreenTestImpl | 697 | // Regular screen rendering with current user context - use real rendering if action is being processed |
| 716 | def screenTest = new org.moqui.mcp.CustomScreenTestImpl(ec.ecfi) | 698 | def screenTest = null |
| 699 | def screenUrl = "http://localhost:8080/${screenPath}" | ||
| 700 | |||
| 701 | if (isActionExecution) { | ||
| 702 | // Action is being processed - use real screen rendering with database access | ||
| 703 | ec.logger.info("MCP Screen Execution: Action detected, using real screen rendering for ${screenPath}") | ||
| 704 | screenTest = ec.screen.makeTestScreen() | ||
| 705 | .rootScreen(rootScreen) | ||
| 706 | .renderMode(renderMode ? renderMode : "mcp") | ||
| 707 | .auth(ec.user.username) | ||
| 708 | |||
| 709 | def renderParams = parameters ?: [:] | ||
| 710 | renderParams.userId = ec.user.userId | ||
| 711 | renderParams.username = ec.user.username | ||
| 712 | |||
| 713 | def relativePath = subscreenName ? subscreenName.replaceAll('_','/') : testScreenPath | ||
| 714 | ec.logger.info("REALRENDER root=${rootScreen} path=${relativePath} params=${renderParams}") | ||
| 715 | |||
| 716 | def realRender = screenTest.render(relativePath, renderParams, "POST") | ||
| 717 | } else { | ||
| 718 | // Regular browse - use ScreenTest mock | ||
| 719 | ec.logger.info("MCP Screen Execution: No action detected, using ScreenTest mock") | ||
| 720 | screenTest = new org.moqui.mcp.CustomScreenTestImpl(ec.ecfi) | ||
| 717 | .rootScreen(rootScreen) | 721 | .rootScreen(rootScreen) |
| 718 | .renderMode(renderMode ? renderMode : "mcp") | 722 | .renderMode(renderMode ? renderMode : "mcp") |
| 719 | .auth(ec.user.username) | 723 | .auth(ec.user.username) | ... | ... |
-
Please register or sign in to post a comment