OpenRobot.Litegraph.Core
1.0.0
dotnet add package OpenRobot.Litegraph.Core --version 1.0.0
NuGet\Install-Package OpenRobot.Litegraph.Core -Version 1.0.0
<PackageReference Include="OpenRobot.Litegraph.Core" Version="1.0.0" />
<PackageVersion Include="OpenRobot.Litegraph.Core" Version="1.0.0" />
<PackageReference Include="OpenRobot.Litegraph.Core" />
paket add OpenRobot.Litegraph.Core --version 1.0.0
#r "nuget: OpenRobot.Litegraph.Core, 1.0.0"
#:package OpenRobot.Litegraph.Core@1.0.0
#addin nuget:?package=OpenRobot.Litegraph.Core&version=1.0.0
#tool nuget:?package=OpenRobot.Litegraph.Core&version=1.0.0
OpenRobot.Litegraph.Core
Litegraph 流程引擎核心(net8.0):把一张画布 JSON 变成可运行的执行图 —— 解析 → 校验 → 装配 → 通道调度与周期 tick,
并全程留执行记录。通过 LitegraphModule 接入 OpenRobot.Framework.Modularity 的模块宿主,日志走 Microsoft.Extensions.Logging。
- 画布即配置:
FlowGraphParser解析 Litegraph 画布 JSON,FlowValidator出带码的 Error / Warning(E0xx/W1xx)。 加载失败不抛异常,逐文件返回GraphLoadResult,由宿主决定怎么打日志、怎么定退出码。 - 处理器是唯一数据源:每个
nodeType一个INodeHandler,默认端口、默认 properties、Init产物、执行逻辑都在它里面 —— 「JSON 缺键回落默认值」只有这一处实现。内置 46 个处理器,覆盖通用 / 触发 / 用户输入 / 工具 / 数据处理 / 报警保护 / 逻辑控制 / 信号输出 / 业务模型 / 规则模型 / 动态数据源 / CNC 解析。 - 双通道执行:
sync在流程自己的执行带上一路跑完;async投递到服务级AsyncChannel,不阻塞本轮 tick。 哪类节点走哪条由Litegraph:ChannelRouting配,未列出的走default(默认sync,上传与设备控制默认async)。 - 全程可诊断:每个节点产出
NodeExecutionRecord,每轮流程产出FlowRunRecord(耗时 / 节点数 / 错误数 / 是否中断), 进环形缓冲Records;加载期另给一张FlowSummary(区域划分、环、不可达节点、各类节点计数)。 - 模块化装配:
LitegraphModule : StartupModule,日志为构造注入的ILogger<LitegraphModule>,配置读appsettings.json的Litegraph节;Shutdown的顺序是停 tick → 关通道 → 释放各图。
安装
<PackageReference Include="OpenRobot.Litegraph.Core" Version="1.0.0" />
包由本仓库产出:
dotnet pack Litegraph/OpenRobot.Litegraph.Core/OpenRobot.Litegraph.Core.csproj -c Release
依赖:
OpenRobot.Litegraph.Common1.0.0OpenRobot.Framework.Modularity1.0.0(传递Microsoft.Extensions.DependencyInjection8.0.1、Microsoft.Extensions.Logging.Abstractions8.0.2)
库不带具体日志实现。控制台输出由宿主引
Microsoft.Extensions.Logging.Console并调AddSimpleConsole()决定; 模块需要容器能解析ILogger<LitegraphModule>,也就是先services.AddLogging()。
快速开始
配置写在宿主 appsettings.json 的同名节(文件在 AppContext.BaseDirectory 下):
{
"Litegraph": {
"Enabled": true,
"AssetsPath": "assets",
"AutoStartFlows": true,
"MainFlowTickMs": 100
}
}
接入模块宿主:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OpenRobot.Framework.Modularity;
using OpenRobot.Litegraph.Core;
var builder = ModuleHostBuilder.Create(args);
builder.Services.AddLogging(b => b
.AddSimpleConsole(o => { o.SingleLine = true; o.TimestampFormat = "HH:mm:ss.fff "; })
.SetMinimumLevel(LogLevel.Information));
builder.AddModule<LitegraphModule>(); // 显式登记;模块由容器构造
await using var host = builder.Build();
await host.RunAsync(); // Initialize 里加载画布并启动引擎
不经模块宿主
轻量宿主(探针、单元测试)直接用 LitegraphService,不必起模块宿主:
using OpenRobot.Litegraph.Core;
using OpenRobot.Litegraph.Core.Options;
var options = new LitegraphOptions
{
AssetsPath = Path.Combine(AppContext.BaseDirectory, "assets"),
};
await using var service = new LitegraphService(options, logger);
foreach (var result in service.LoadDirectory(options.AssetsPath))
{
if (!result.Success)
logger.LogError("加载失败 {File}:{Code} {Message}",
result.File, result.Error!.Code, result.Error.Message);
}
service.Start(cancellationToken); // 通道恒启;AutoStartFlows 决定是否自动 tick
var record = await service.RunTickAsync("sample-main"); // graphId = 文件名(去扩展名)
写一个节点处理器
继承 NodeHandlerBase 即可 —— 日志、异常策略、执行记录、trace 四条都由基类落,子类只写业务语义:
public sealed class UpperHandler : NodeHandlerBase
{
public UpperHandler(ILogger logger, LitegraphOptions options) : base(logger, options) { }
public override string NodeType => "my/upper";
public override NodeDefaults GetDefaults() => new()
{
Inputs = [NodeDefaults.Port("input")],
Outputs = [NodeDefaults.Port("output")],
Properties = new Dictionary<string, object?> { ["prefix"] = "" },
};
protected override Task ExecuteCoreAsync(IFlowContext ctx)
{
var text = ctx.GetInput(0)?.ToString() ?? "";
ctx.SetOutput(0, ctx.Properties.GetString("prefix") + text.ToUpperInvariant());
return Task.CompletedTask;
}
}
注册进引擎(替换默认注册表时):
service.Handlers.Register(new UpperHandler(logger, options));
不要在
ExecuteCoreAsync里自己try/catch吞异常 —— 异常是异常策略表(Continue/AbortFlow/AbortGraph) 的判定输入,吞掉就再也走不到策略。
灌上下文变量
上下文变量按 varId 存,值是可变的:MutableContextValueProvider 与引擎共享同一个实例,运行中可继续写。
var contextValues = new MutableContextValueProvider();
contextValues.Set(varId: 3, value: 1);
var service = new LitegraphService(options, logger, contextValues: contextValues);
// ...运行中随时更新
contextValues.Set(varId: 3, value: 0);
手动触发
await service.TriggerAsync("sample-main", nodeId: 1); // 触发某个区域(触发节点 / link-in)
await service.TriggerAllManualAsync("sample-main"); // 触发全部手动触发节点
API 速查
装配与执行
| 成员 | 说明 |
|---|---|
LitegraphService(options, logger, contextValues?, uploadSink?, deviceInvoker?, clock?) |
引擎门面;clock 可注入,用于确定性超时测试 |
Load(json, sourceName, graphId?) / LoadFile(path) |
加载单张图,出错抛 FlowJsonException |
LoadDirectory(dir) |
扫顶层 *.json,逐文件返回 GraphLoadResult,失败不抛 |
Start(ct) |
StartChannels + StartFlows;两者各自幂等 |
RunTickAsync(graphId) / TriggerAsync(graphId, nodeId) / TriggerAllManualAsync(graphId) |
手动跑一轮 / 触发一个区域 / 触发全部手动节点,返回 FlowRunRecord |
StopAsync() / DisposeAsync() |
停 tick、排空并关闭通道 |
Graphs / Get(graphId) / Handlers / AsyncChannel / Records |
已加载的图、注册表、异步通道、执行记录 |
| 类型 | 说明 |
|---|---|
GraphEntry |
一张已装配的图:GraphId / SourceFile / Summary / Graph / Engine / Runtime / HasErrors |
GraphLoadResult |
单文件加载结果:File / Entry / Error / Success |
FlowSummary |
加载期概要:区域、HasCycle、UnreachableNodeCount、NodeTypeCounts、ToReport() |
FlowRunRecord |
一轮执行:StartedAt / DurationMs / NodeCount / ErrorCount / Success / Aborted / AbortReason |
LitegraphModule |
模块入口:Service / Options / ConfigureOptions / AdditionalGraphLoader / ContextValues / LoadResults |
配置
| 项 | 默认 | 说明 |
|---|---|---|
Enabled |
true |
false 时模块初始化后立即返回,不加载任何图 |
AssetsPath |
assets |
画布目录;相对路径以 AppContext.BaseDirectory 为基准 |
AllowUnimplementedNodes |
false |
false 时「表内但无 handler」升为 Error(W117) |
AutoStartFlows |
true |
是否自动起主流程周期 tick |
MainFlowTickMs |
100 |
主流程 tick 间隔(毫秒) |
SubFlowHardTimeout |
true |
子流程超时是否硬取消(false 退化为前端式的「只能检测」) |
DefaultSubFlowTimeoutSec |
30 |
调用节点没给有效 timeoutSec 时的兜底 |
CronPollIntervalMs |
1000 |
Cron 触发轮询间隔 |
ChannelRouting |
default=sync、上传 / 设备控制 = async |
节点 → 通道 |
ExceptionPolicy |
空 | nodeType → Continue / AbortFlow / AbortGraph,优先于内置表 |
Trace |
见下 | VerboseNodeLog(默认关)/ LogSuccessfulNodes / AlwaysLogErrors / MaxValueLength |
RecordRingCapacity |
1000 |
内存里保留的最近执行记录条数(0 = 不保留) |
扩展点
| 类型 | 说明 |
|---|---|
INodeHandler |
NodeType / GetDefaults() / GetPortLayout() / Init() / ExecuteAsync() |
NodeHandlerBase |
处理器基类:日志、异常策略、执行记录、trace 已实现,只留 ExecuteCoreAsync |
NodeDefaults |
默认端口、必需输入、默认 properties、默认标题;NodeDefaults.Port(...) 造端口 |
NodeHandlerRegistry |
Register / RegisterAll / TryResolve / Resolve / IsImplemented / LayoutOf |
BuiltinNodeHandlers |
ImplementedTypes(46 个)/ Create(...) / CreateRegistry(...) |
IFlowContext |
节点执行上下文:GetInput / SetOutput / Properties / Runtime / GetInit<T>() |
IContextValueProvider |
上下文变量源;MutableContextValueProvider 为可写实现 |
IDataUploadSink / IDeviceControlInvoker |
副作用出口;不传时处理器回落「只落日志」 |
已知限制
- 一张图一套运行时:用户变量、触发路由表、流程调用表都按图独立 —— 两张图各自从
last_node_id起编节点 id, 落在同一个注册表里会互相顶掉。跨图共享用户变量、跨图触发目前做不到。 - 启动后再加载的图拿不到周期 tick:
StartFlows只遍历一次已加载的图。要追加图请在LitegraphModule.AdditionalGraphLoader里做(它在Start之前执行)。 - 校验有 Error 仍照常加载执行:与前端行为一致(前端同样宽容),Error 只记 Warn 日志。
需要「有 Error 即不跑」的宿主,自己按
GraphEntry.HasErrors判断。 Shutdown是同步签名:内部用GetAwaiter().GetResult()阻塞等通道排空和 tick 收尾, 不要在有同步上下文(如 UI 线程)的进程里长时间持有它。AssetsPath以AppContext.BaseDirectory为基准,不是当前工作目录 ——dotnet run与守护进程的 cwd 往往不同, 用 cwd 会让配置时灵时不灵。- 未实现节点不是静默跳过:画布来自更新版前端时,默认会以
W117升 Error 显式失败; 确实要临时放行才置AllowUnimplementedNodes=true。
版本历史
1.0.0(首次发布)
- 画布解析与语义校验(
FlowGraphParser/FlowValidator/FlowSummary) - 46 个内置节点处理器、
NodeHandlerRegistry、可选NodeDefaults回落 - 同步 / 异步双通道执行、主流程周期 tick、子流程硬超时、Cron 触发
- 节点级与流程级执行记录(
RingBufferRecordSink)、trace 开关 LitegraphModule:模块化装配,日志构造注入,支持追加图加载器与上下文变量源
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- OpenRobot.Framework.Modularity (>= 1.0.0)
- OpenRobot.Litegraph.Common (>= 1.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on OpenRobot.Litegraph.Core:
| Package | Downloads |
|---|---|
|
OpenRobot.Litegraph.Cloud
Litegraph 云端对接:画布拉取与备份、云端工件(画布/元数据)发布、ABP 信封解析;传输层留缝,可走 HTTP 直连或宿主自己的出网通道。 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 42 | 10/28/2026 |