Skip to content

Commit 228cb82

Browse files
💾 🧩 Feat, Refactor(Workflow, Contract): 工作流执行输出透传至活动日志 & 转换器修复
1. PluginCall 内置形式嵌套展开修复 - PluginCallFunction.IsNonExtractable: true → false - 8 个值产生型内置函数(InstallPlugin/ListPluginNames/RunWorkflow/ CreateWorkflow/ReadTextFile/JsonGetField/GetPluginInfoByName/ListWorks) 同步修正为 false,使其可作为嵌套表达式展开为临时 PubVar - 新增 Test T 验证 Set("x", PluginCall(...)) 嵌套展开 2. BuildPluginCallExpression 双形式支持 - 区分点号形式 Plugin.Method(args) 与内置形式 PluginCall(pluginName, methodName, args...),后者前两个参数为插件名/ 方法名(之前误从 FullFunctionName 提取导致插件名="PluginCall") 3. BS2CFGConverter.BinaryExpression 嵌套展开 - ExpandExpression 增加 BinaryExpressionSyntax 处理,递归展开 "prefix" + Get("var") + "suffix" 中嵌套的内置调用 4. Get 按声明类型返回 - BuildGetInvocation 增加 typeName 参数,按 ConstBlock 变量声明类型 生成 G.Get<string>("name") 而非总是 G.Get<object> - InferPubVarTypes 从 Script.ConstBlock 提取变量类型(BS→CFG→CS 路径 ConstNodes 为空);Get 展开的临时 PubVar 继承被读变量类型 5. 工作流执行输出透传 - WorkflowExecutionResultEventArgs 加 Output 字段 - IWorkflowManagementService 加 RunWorkflowWithDetailsAsync → WorkflowRunResult - WorkflowManagementService/TriggerManager 改用新方法,Output 随事件传出 6. 编译诊断透传(保留诊断透传改动) - ScriptCompilationBackend/CSCompiler/BlockScriptExecutor 把 Roslyn 诊断沿调用链传出,编译失败时 ErrorMessage 含具体错误而非仅 "Script compilation failed" 7. --kcs <path> 测试功能 - 可编译任意 .kcs 文件并报告诊断,无需启动 Dashboard
1 parent 0d1fc02 commit 228cb82

18 files changed

Lines changed: 246 additions & 32 deletions
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.IO;
3+
using System.Text.Json;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using KitX.Core.DI;
6+
using KitX.Core.Contract.Workflow;
7+
using KitX.Workflow.BlockScripting;
8+
using KitX.Workflow.Contract;
9+
using KitX.Workflow.Contract.Models;
10+
11+
namespace KitX.Core.BluePrint.Test;
12+
13+
/// <summary>
14+
/// Compiles a .kcs workflow file end-to-end (parse + BS→CFG→CS→assembly) and reports
15+
/// diagnostics. Invoked via <c>--kcs &lt;path&gt;</c>. Useful for validating real workflow
16+
/// scripts without running the Dashboard.
17+
/// </summary>
18+
public partial class Program
19+
{
20+
public static void RunKcsCompileTest(string kcsPath)
21+
{
22+
Console.WriteLine($"=== KCS Compile Test: {kcsPath} ===");
23+
24+
if (!File.Exists(kcsPath))
25+
{
26+
Console.WriteLine($"FAIL: File not found: {kcsPath}");
27+
return;
28+
}
29+
30+
var services = new ServiceCollection();
31+
services.AddCoreServices();
32+
var sp = services.BuildServiceProvider();
33+
var parser = sp.GetRequiredService<IBlockScriptParser>();
34+
35+
KcsFileFormat? kcs;
36+
try
37+
{
38+
kcs = JsonSerializer.Deserialize<KcsFileFormat>(File.ReadAllText(kcsPath));
39+
}
40+
catch (Exception ex)
41+
{
42+
Console.WriteLine($"FAIL: JSON parse error: {ex.Message}");
43+
return;
44+
}
45+
if (kcs == null || string.IsNullOrEmpty(kcs.BlockScriptSource))
46+
{
47+
Console.WriteLine("FAIL: Empty BlockScriptSource");
48+
return;
49+
}
50+
51+
Console.WriteLine($"Name: {kcs.Name}");
52+
Console.WriteLine($"Id: {kcs.Id}");
53+
Console.WriteLine($"Trigger: {kcs.TriggerType}");
54+
Console.WriteLine($"UseBlockMode: {kcs.UseBlockMode}");
55+
Console.WriteLine($"Helpers: {(kcs.HelperFunctions?.Count ?? 0)}");
56+
Console.WriteLine();
57+
58+
var sourceCode = kcs.BlockScriptSource;
59+
Console.WriteLine("--- BlockScript source ---");
60+
Console.WriteLine(sourceCode);
61+
Console.WriteLine("--- end ---\n");
62+
63+
// Parse
64+
var pr = parser.Parse(sourceCode);
65+
Console.WriteLine($"Parse: {(pr.IsSuccess ? "OK" : "FAIL")}, err: {pr.ErrorMessage}");
66+
if (pr.Script == null)
67+
{
68+
Console.WriteLine("FAIL: Script is null after parse");
69+
return;
70+
}
71+
72+
// Attach helper functions from the kcs file
73+
if (kcs.HelperFunctions != null)
74+
pr.Script.HelperFunctions = kcs.HelperFunctions;
75+
76+
// Compile
77+
var compiler = new CSCompiler();
78+
var result = compiler.CompileScript(pr.Script, workflowId: kcs.Id, out var errors);
79+
Console.WriteLine($"Compiled: {(result == null ? "NULL" : "OK")}, errors: {errors.Count}");
80+
foreach (var e in errors)
81+
Console.WriteLine(" ERR: " + e);
82+
83+
if (result != null && errors.Count == 0)
84+
Console.WriteLine("\nRESULT: PASS");
85+
else
86+
Console.WriteLine("\nRESULT: FAIL");
87+
}
88+
}

KitX Clients/KitX Core/KitX.Core.BluePrint.Test/Program.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace KitX.Core.BluePrint.Test;
1616

17-
public class Program
17+
public partial class Program
1818
{
1919
// Test selection: --test A,D,K or --test all (default: all)
2020
private static HashSet<string> _selectedTests = new(StringComparer.OrdinalIgnoreCase) { "ALL" };
@@ -24,6 +24,15 @@ public static void Main(string[] args)
2424
{
2525
ParseArgs(args);
2626

27+
// --kcs <path>: compile a .kcs workflow file and report diagnostics.
28+
// Useful for validating real workflow scripts without running the Dashboard.
29+
var kcsIdx = Array.IndexOf(args, "--kcs");
30+
if (kcsIdx >= 0 && kcsIdx + 1 < args.Length)
31+
{
32+
RunKcsCompileTest(args[kcsIdx + 1]);
33+
return;
34+
}
35+
2736
Console.WriteLine("=== KitX BlockScript → Blueprint Pipeline Test ===\n");
2837

2938
if (_selectedTests.Contains("ALL"))

KitX Clients/KitX Workflow/KitX.Workflow/BuiltinFunctions/CreateWorkflowFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class CreateWorkflowFunction : IBuiltinFunctionDefinition
1212
public string FunctionName => "CreateWorkflow";
1313
public string DisplayName => "Create Workflow";
1414
public bool IsFlowControl => false;
15-
public bool IsNonExtractable => true;
15+
public bool IsNonExtractable => false; // Value-producing (has Return pin) — can be nested as an expression
1616
public CFGStatementKind StatementKind => CFGStatementKind.Expression;
1717
public double NodeWidth => 180;
1818
public double NodeHeight => 80;

KitX Clients/KitX Workflow/KitX.Workflow/BuiltinFunctions/GetFunction.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ public class GetFunction : IBuiltinFunctionDefinition
3737
public List<StatementSyntax> EmitStatements(CFGStatement stmt, CSEmitContext ctx)
3838
{
3939
var varName = stmt.Arguments?.Count > 0 ? stmt.Arguments[0].Trim('"') : "";
40-
return ctx.EmitValueAssignment(stmt.PubVarTarget, CFG2CSGenerator.BuildGetInvocation(varName));
40+
// Look up the ConstBlock variable's declared type so Get<T> returns the right type.
41+
// Without this, Get always returns object, and passing it to a function expecting
42+
// string/int/bool causes CS1503. Falls back to object if the variable is unknown.
43+
var typeName = ctx.PubVarTypes.GetValueOrDefault(varName, "object");
44+
return ctx.EmitValueAssignment(stmt.PubVarTarget, CFG2CSGenerator.BuildGetInvocation(varName, typeName));
4145
}
4246

4347
public List<CFGStatement> LowerToCFG(

KitX Clients/KitX Workflow/KitX.Workflow/BuiltinFunctions/GetPluginInfoByNameFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class GetPluginInfoByNameFunction : IBuiltinFunctionDefinition
1414
public string FunctionName => "GetPluginInfoByName";
1515
public string DisplayName => "Get Plugin Info";
1616
public bool IsFlowControl => false;
17-
public bool IsNonExtractable => true;
17+
public bool IsNonExtractable => false; // Value-producing (has Return pin) — can be nested as an expression
1818
public CFGStatementKind StatementKind => CFGStatementKind.Expression;
1919
public double NodeWidth => 160;
2020
public double NodeHeight => 60;

KitX Clients/KitX Workflow/KitX.Workflow/BuiltinFunctions/InstallPluginFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class InstallPluginFunction : IBuiltinFunctionDefinition
1313
public string FunctionName => "InstallPlugin";
1414
public string DisplayName => "Install Plugin";
1515
public bool IsFlowControl => false;
16-
public bool IsNonExtractable => true;
16+
public bool IsNonExtractable => false; // Value-producing (has Return pin) — can be nested as an expression
1717
public CFGStatementKind StatementKind => CFGStatementKind.Expression;
1818
public double NodeWidth => 140;
1919
public double NodeHeight => 60;

KitX Clients/KitX Workflow/KitX.Workflow/BuiltinFunctions/JsonGetFieldFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class JsonGetFieldFunction : IBuiltinFunctionDefinition
1313
public string FunctionName => "JsonGetField";
1414
public string DisplayName => "JSON Get Field";
1515
public bool IsFlowControl => false;
16-
public bool IsNonExtractable => true;
16+
public bool IsNonExtractable => false; // Value-producing (has Return pin) — can be nested as an expression
1717
public CFGStatementKind StatementKind => CFGStatementKind.Expression;
1818
public double NodeWidth => 160;
1919
public double NodeHeight => 80;

KitX Clients/KitX Workflow/KitX.Workflow/BuiltinFunctions/ListPluginNamesFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class ListPluginNamesFunction : IBuiltinFunctionDefinition
1414
public string FunctionName => "ListPluginNames";
1515
public string DisplayName => "List Plugin Names";
1616
public bool IsFlowControl => false;
17-
public bool IsNonExtractable => true;
17+
public bool IsNonExtractable => false; // Value-producing (has Return pin) — can be nested as an expression
1818
public CFGStatementKind StatementKind => CFGStatementKind.Expression;
1919
public double NodeWidth => 140;
2020
public double NodeHeight => 60;

KitX Clients/KitX Workflow/KitX.Workflow/BuiltinFunctions/ListWorkflowsFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class ListWorkflowsFunction : IBuiltinFunctionDefinition
1313
public string FunctionName => "ListWorkflows";
1414
public string DisplayName => "List Workflows";
1515
public bool IsFlowControl => false;
16-
public bool IsNonExtractable => true;
16+
public bool IsNonExtractable => false; // Value-producing (has Return pin) — can be nested as an expression
1717
public CFGStatementKind StatementKind => CFGStatementKind.Expression;
1818
public double NodeWidth => 140;
1919
public double NodeHeight => 60;

0 commit comments

Comments
 (0)