@ixo/editor 5.19.0 → 5.20.0-experimental.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-TZBRXBBJ.mjs → chunk-IALS3KWH.mjs} +2483 -5088
- package/dist/chunk-IALS3KWH.mjs.map +1 -0
- package/dist/chunk-OK2W66I7.mjs +1 -0
- package/dist/chunk-OK2W66I7.mjs.map +1 -0
- package/dist/{chunk-67477PYU.mjs → chunk-XGQRYGA3.mjs} +1200 -217
- package/dist/chunk-XGQRYGA3.mjs.map +1 -0
- package/dist/core/index.d.ts +57 -45
- package/dist/core/index.mjs +3 -4
- package/dist/core/index.mjs.map +1 -1
- package/dist/{graphql-client-xxQMIQzo.d.ts → graphql-client-Dhxgv06u.d.ts} +1 -1
- package/dist/{index-BoRWeiDg.d.ts → index-DMNPdv6v.d.ts} +112 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/mantine/index.d.ts +3 -3
- package/dist/mantine/index.mjs +2 -2
- package/dist/{store-DZobLMG3.d.ts → store-Bx5ezUFS.d.ts} +76 -67
- package/package.json +1 -1
- package/dist/chunk-67477PYU.mjs.map +0 -1
- package/dist/chunk-K4YAG7AQ.mjs +0 -63
- package/dist/chunk-K4YAG7AQ.mjs.map +0 -1
- package/dist/chunk-TZBRXBBJ.mjs.map +0 -1
|
@@ -571,15 +571,68 @@ registerAction({
|
|
|
571
571
|
});
|
|
572
572
|
|
|
573
573
|
// src/core/lib/actionRegistry/actions/pod/listDomainFlows.ts
|
|
574
|
+
function normalizeSelectedTemplates(value) {
|
|
575
|
+
if (!Array.isArray(value)) return [];
|
|
576
|
+
return value.map((item) => {
|
|
577
|
+
if (!item || typeof item !== "object") return null;
|
|
578
|
+
const raw = item;
|
|
579
|
+
const protocolDid = String(raw.protocolDid || "").trim();
|
|
580
|
+
const sourceRoomId = String(raw.sourceRoomId || "").trim();
|
|
581
|
+
if (!protocolDid || !sourceRoomId) return null;
|
|
582
|
+
const sourceLabel = String(raw.sourceLabel || raw.label || sourceRoomId).trim();
|
|
583
|
+
return {
|
|
584
|
+
protocolDid,
|
|
585
|
+
protocolName: String(raw.protocolName || protocolDid).trim(),
|
|
586
|
+
sourceRoomId,
|
|
587
|
+
sourceLabel,
|
|
588
|
+
...raw.path ? { path: String(raw.path) } : {}
|
|
589
|
+
};
|
|
590
|
+
}).filter((item) => item !== null);
|
|
591
|
+
}
|
|
574
592
|
registerAction({
|
|
575
593
|
type: "qi/pod.list-domain-flows",
|
|
576
594
|
can: "pod/list-domain-flows",
|
|
577
595
|
sideEffect: false,
|
|
578
596
|
defaultRequiresConfirmation: false,
|
|
579
|
-
outputSchema: [
|
|
597
|
+
outputSchema: [
|
|
598
|
+
{
|
|
599
|
+
path: "selectedProtocolTemplates",
|
|
600
|
+
displayName: "Selected Protocol Templates",
|
|
601
|
+
type: "array",
|
|
602
|
+
description: "Selected protocol templates with protocol DID and source room ID"
|
|
603
|
+
},
|
|
604
|
+
{ path: "selectedFlowDids", displayName: "Selected Flow Room IDs", type: "array", description: "Source Matrix room IDs for selected templates" },
|
|
605
|
+
{ path: "flowTemplateConfig", displayName: "Flow Template Config", type: "object", description: "Event payload consumed by POD signing/import steps" }
|
|
606
|
+
],
|
|
607
|
+
events: [
|
|
608
|
+
{
|
|
609
|
+
name: "configured",
|
|
610
|
+
displayName: "Flow Templates Configured",
|
|
611
|
+
description: "Fires when protocol flow templates are selected for the POD.",
|
|
612
|
+
payloadSchema: [
|
|
613
|
+
{
|
|
614
|
+
path: "flowTemplateConfig",
|
|
615
|
+
displayName: "Flow Template Config",
|
|
616
|
+
type: "object",
|
|
617
|
+
description: "Selected templates grouped by their protocol DID for later import"
|
|
618
|
+
}
|
|
619
|
+
],
|
|
620
|
+
pendingDisplayFields: ["flowTemplateConfig.templateCount", "flowTemplateConfig.protocolCount"]
|
|
621
|
+
}
|
|
622
|
+
],
|
|
580
623
|
run: async (inputs) => {
|
|
581
|
-
const
|
|
582
|
-
|
|
624
|
+
const selectedProtocolTemplates = normalizeSelectedTemplates(inputs.selectedProtocolTemplates);
|
|
625
|
+
const selectedFlowDids = selectedProtocolTemplates.length > 0 ? selectedProtocolTemplates.map((template) => template.sourceRoomId) : Array.isArray(inputs.selectedFlowDids) ? inputs.selectedFlowDids : [];
|
|
626
|
+
const protocolCount = new Set(selectedProtocolTemplates.map((template) => template.protocolDid)).size;
|
|
627
|
+
const flowTemplateConfig = {
|
|
628
|
+
selectedTemplates: selectedProtocolTemplates,
|
|
629
|
+
templateCount: selectedProtocolTemplates.length,
|
|
630
|
+
protocolCount
|
|
631
|
+
};
|
|
632
|
+
return {
|
|
633
|
+
output: { selectedProtocolTemplates, selectedFlowDids, flowTemplateConfig },
|
|
634
|
+
events: [{ name: "configured", payload: { flowTemplateConfig } }]
|
|
635
|
+
};
|
|
583
636
|
}
|
|
584
637
|
});
|
|
585
638
|
|
|
@@ -2669,6 +2722,77 @@ function parseContextInput(value) {
|
|
|
2669
2722
|
return key && val ? { key, val } : null;
|
|
2670
2723
|
}).filter((entry) => entry !== null);
|
|
2671
2724
|
}
|
|
2725
|
+
function getSelectedProtocolTemplates(flowTemplateConfig) {
|
|
2726
|
+
const raw = flowTemplateConfig?.selectedTemplates;
|
|
2727
|
+
if (!Array.isArray(raw)) return [];
|
|
2728
|
+
return raw.map((item) => {
|
|
2729
|
+
if (!item || typeof item !== "object") return null;
|
|
2730
|
+
const record = item;
|
|
2731
|
+
const protocolDid = String(record.protocolDid || "").trim();
|
|
2732
|
+
const sourceRoomId = String(record.sourceRoomId || "").trim();
|
|
2733
|
+
if (!protocolDid || !sourceRoomId) return null;
|
|
2734
|
+
const sourceLabel = String(record.sourceLabel || record.label || "").trim();
|
|
2735
|
+
return {
|
|
2736
|
+
protocolDid,
|
|
2737
|
+
sourceRoomId,
|
|
2738
|
+
...sourceLabel ? { sourceLabel } : {}
|
|
2739
|
+
};
|
|
2740
|
+
}).filter((item) => item !== null);
|
|
2741
|
+
}
|
|
2742
|
+
function groupTemplatesByProtocol(templates) {
|
|
2743
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
2744
|
+
for (const template of templates) {
|
|
2745
|
+
const existing = grouped.get(template.protocolDid) || [];
|
|
2746
|
+
existing.push({
|
|
2747
|
+
sourceRoomId: template.sourceRoomId,
|
|
2748
|
+
...template.sourceLabel ? { sourceLabel: template.sourceLabel } : {}
|
|
2749
|
+
});
|
|
2750
|
+
grouped.set(template.protocolDid, existing);
|
|
2751
|
+
}
|
|
2752
|
+
return grouped;
|
|
2753
|
+
}
|
|
2754
|
+
var DOMAIN_SIGN_CACHE_KEY = "domainSign";
|
|
2755
|
+
function getDomainSignCheckpointKey(inputs, ctx) {
|
|
2756
|
+
return String(ctx.pendingInvocation?.id || inputs.pendingInvocationId || inputs.invocationId || "manual");
|
|
2757
|
+
}
|
|
2758
|
+
function readDomainSignCheckpoint(ctx, key) {
|
|
2759
|
+
const cache = ctx.runtime?.get?.(ctx.nodeId)?.cache;
|
|
2760
|
+
const bucket = cache?.[DOMAIN_SIGN_CACHE_KEY];
|
|
2761
|
+
if (!bucket || typeof bucket !== "object") return void 0;
|
|
2762
|
+
const checkpoint = bucket[key];
|
|
2763
|
+
return checkpoint && typeof checkpoint === "object" ? checkpoint : void 0;
|
|
2764
|
+
}
|
|
2765
|
+
function writeDomainSignCheckpoint(ctx, key, checkpoint) {
|
|
2766
|
+
if (!ctx.runtime?.get || !ctx.runtime?.update || !ctx.nodeId) return;
|
|
2767
|
+
const current = ctx.runtime.get(ctx.nodeId) || {};
|
|
2768
|
+
const cache = current.cache && typeof current.cache === "object" ? current.cache : {};
|
|
2769
|
+
const bucket = cache[DOMAIN_SIGN_CACHE_KEY] && typeof cache[DOMAIN_SIGN_CACHE_KEY] === "object" ? cache[DOMAIN_SIGN_CACHE_KEY] : {};
|
|
2770
|
+
ctx.runtime.update(ctx.nodeId, {
|
|
2771
|
+
cache: {
|
|
2772
|
+
...cache,
|
|
2773
|
+
[DOMAIN_SIGN_CACHE_KEY]: {
|
|
2774
|
+
...bucket,
|
|
2775
|
+
[key]: checkpoint
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
});
|
|
2779
|
+
}
|
|
2780
|
+
function buildCompletedDomainSignResult(output) {
|
|
2781
|
+
return {
|
|
2782
|
+
output,
|
|
2783
|
+
events: [
|
|
2784
|
+
{
|
|
2785
|
+
name: "created",
|
|
2786
|
+
payload: {
|
|
2787
|
+
entityDid: output.entityDid,
|
|
2788
|
+
governanceGroupCoreAddress: output.governanceGroupCoreAddress || "",
|
|
2789
|
+
transactionHash: output.transactionHash || "",
|
|
2790
|
+
linkedResourceTransactionHash: output.linkedResourceTransactionHash || ""
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
]
|
|
2794
|
+
};
|
|
2795
|
+
}
|
|
2672
2796
|
function parseDuration(raw) {
|
|
2673
2797
|
const seconds = parseInt(raw, 10) || 0;
|
|
2674
2798
|
if (seconds % (7 * 86400) === 0) return { amount: seconds / (7 * 86400), unit: "weeks" };
|
|
@@ -2755,6 +2879,24 @@ registerAction({
|
|
|
2755
2879
|
displayName: "Linked Resource Transaction Hash",
|
|
2756
2880
|
type: "string",
|
|
2757
2881
|
description: "The on-chain transaction hash for adding the domain card linked resource"
|
|
2882
|
+
},
|
|
2883
|
+
{
|
|
2884
|
+
path: "flowTemplateConfig",
|
|
2885
|
+
displayName: "Flow Template Config",
|
|
2886
|
+
type: "object",
|
|
2887
|
+
description: "Selected protocol templates captured before POD creation"
|
|
2888
|
+
},
|
|
2889
|
+
{
|
|
2890
|
+
path: "domainSpaces",
|
|
2891
|
+
displayName: "Domain Spaces",
|
|
2892
|
+
type: "object",
|
|
2893
|
+
description: "Matrix space structure sourced for the new domain"
|
|
2894
|
+
},
|
|
2895
|
+
{
|
|
2896
|
+
path: "protocolTemplateImports",
|
|
2897
|
+
displayName: "Protocol Template Imports",
|
|
2898
|
+
type: "array",
|
|
2899
|
+
description: "Import results for selected protocol templates"
|
|
2758
2900
|
}
|
|
2759
2901
|
],
|
|
2760
2902
|
events: [
|
|
@@ -2782,16 +2924,7 @@ registerAction({
|
|
|
2782
2924
|
}
|
|
2783
2925
|
],
|
|
2784
2926
|
run: async (inputs, ctx) => {
|
|
2785
|
-
const handlers = ctx.handlers;
|
|
2786
|
-
if (!handlers) {
|
|
2787
|
-
throw new Error("Handlers not available");
|
|
2788
|
-
}
|
|
2789
|
-
if (!handlers.requestPin) throw new Error("requestPin handler not available");
|
|
2790
|
-
if (!handlers.signCredential) throw new Error("signCredential handler not implemented");
|
|
2791
|
-
if (!handlers.publicFileUpload) throw new Error("publicFileUpload handler not available");
|
|
2792
|
-
if (!handlers.createDomain) throw new Error("createDomain handler not implemented");
|
|
2793
|
-
if (!handlers.createAddLinkedResourceMessage) throw new Error("createAddLinkedResourceMessage handler not implemented");
|
|
2794
|
-
if (!handlers.executeTransaction) throw new Error("executeTransaction handler not implemented");
|
|
2927
|
+
const handlers = ctx.handlers || {};
|
|
2795
2928
|
let domainCardData;
|
|
2796
2929
|
if (typeof inputs.domainCardData === "string") {
|
|
2797
2930
|
try {
|
|
@@ -2814,99 +2947,238 @@ registerAction({
|
|
|
2814
2947
|
d.setFullYear(d.getFullYear() + 100);
|
|
2815
2948
|
return d.toISOString();
|
|
2816
2949
|
})();
|
|
2817
|
-
let governanceGroupLinkedEntities = [];
|
|
2818
|
-
let governanceGroupCoreAddress = "";
|
|
2819
2950
|
const govConfig = parseJsonInput(inputs.governanceConfig);
|
|
2820
2951
|
const memberConfig = parseJsonInput(inputs.memberConfig);
|
|
2952
|
+
const flowTemplateConfig = parseJsonInput(inputs.flowTemplateConfig);
|
|
2821
2953
|
const context = parseContextInput(inputs.context);
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2954
|
+
const selectedProtocolTemplates = getSelectedProtocolTemplates(flowTemplateConfig);
|
|
2955
|
+
const checkpointKey = getDomainSignCheckpointKey(inputs, ctx);
|
|
2956
|
+
let checkpoint = readDomainSignCheckpoint(ctx, checkpointKey) || {
|
|
2957
|
+
invocationId: checkpointKey,
|
|
2958
|
+
status: "running",
|
|
2959
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2960
|
+
completedSteps: {}
|
|
2961
|
+
};
|
|
2962
|
+
if (checkpoint.status === "completed" && checkpoint.output) {
|
|
2963
|
+
return buildCompletedDomainSignResult(checkpoint.output);
|
|
2964
|
+
}
|
|
2965
|
+
if (!ctx.handlers) {
|
|
2966
|
+
throw new Error("Handlers not available");
|
|
2967
|
+
}
|
|
2968
|
+
if (typeof handlers.requestPin !== "function") throw new Error("requestPin handler not available");
|
|
2969
|
+
if (typeof handlers.signCredential !== "function") throw new Error("signCredential handler not implemented");
|
|
2970
|
+
if (typeof handlers.publicFileUpload !== "function") throw new Error("publicFileUpload handler not available");
|
|
2971
|
+
if (typeof handlers.createDomain !== "function") throw new Error("createDomain handler not implemented");
|
|
2972
|
+
if (typeof handlers.createAddLinkedResourceMessage !== "function") throw new Error("createAddLinkedResourceMessage handler not implemented");
|
|
2973
|
+
if (typeof handlers.executeTransaction !== "function") throw new Error("executeTransaction handler not implemented");
|
|
2974
|
+
const saveCheckpoint = (updates) => {
|
|
2975
|
+
checkpoint = {
|
|
2976
|
+
...checkpoint,
|
|
2977
|
+
...updates,
|
|
2978
|
+
invocationId: checkpointKey,
|
|
2979
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2980
|
+
completedSteps: {
|
|
2981
|
+
...checkpoint.completedSteps || {},
|
|
2982
|
+
...updates.completedSteps || {}
|
|
2838
2983
|
}
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
const { entityDid: newEntityDid, transactionHash } = await handlers.createDomain({
|
|
2843
|
-
entityType,
|
|
2844
|
-
context: context.length > 0 ? context : void 0,
|
|
2845
|
-
linkedResource: [],
|
|
2846
|
-
linkedEntity: governanceGroupLinkedEntities.length > 0 ? governanceGroupLinkedEntities : void 0,
|
|
2847
|
-
startDate: validFrom,
|
|
2848
|
-
endDate
|
|
2849
|
-
});
|
|
2850
|
-
const issuerDid = handlers.getEntityDid?.() || handlers.getCurrentUser?.()?.address;
|
|
2851
|
-
if (!issuerDid) throw new Error("Unable to determine issuer DID");
|
|
2852
|
-
const credentialSubject = {
|
|
2853
|
-
...domainCardData.credentialSubject,
|
|
2854
|
-
id: newEntityDid
|
|
2984
|
+
};
|
|
2985
|
+
writeDomainSignCheckpoint(ctx, checkpointKey, checkpoint);
|
|
2986
|
+
return checkpoint;
|
|
2855
2987
|
};
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
validFrom,
|
|
2861
|
-
validUntil
|
|
2862
|
-
});
|
|
2863
|
-
const pin = await handlers.requestPin({
|
|
2864
|
-
title: "Sign Domain Card",
|
|
2865
|
-
description: "Enter your PIN to sign the Domain Card credential",
|
|
2866
|
-
submitText: "Sign"
|
|
2867
|
-
});
|
|
2868
|
-
const { signedCredential } = await handlers.signCredential({
|
|
2869
|
-
issuerDid,
|
|
2870
|
-
issuerType: "user",
|
|
2871
|
-
credential: unsignedCredential,
|
|
2872
|
-
pin
|
|
2873
|
-
});
|
|
2874
|
-
const credentialBlob = new Blob([JSON.stringify(signedCredential, null, 2)], {
|
|
2875
|
-
type: "application/json"
|
|
2876
|
-
});
|
|
2877
|
-
const credentialFile = new File([credentialBlob], "domainCard.json", {
|
|
2878
|
-
type: "application/json"
|
|
2879
|
-
});
|
|
2880
|
-
const uploadResult = await handlers.publicFileUpload(credentialFile);
|
|
2881
|
-
const domainCardLinkedResource = buildDomainCardLinkedResource({
|
|
2882
|
-
entityDid: newEntityDid,
|
|
2883
|
-
cid: uploadResult.cid,
|
|
2884
|
-
serviceEndpoint: uploadResult.url,
|
|
2885
|
-
description: `Domain Card for ${domainCardData.credentialSubject?.name || "Domain"}`
|
|
2886
|
-
});
|
|
2887
|
-
const addLinkedResourceMessage = await handlers.createAddLinkedResourceMessage({
|
|
2888
|
-
entityDid: newEntityDid,
|
|
2889
|
-
linkedResource: domainCardLinkedResource
|
|
2890
|
-
});
|
|
2891
|
-
const addLinkedResourceResult = await handlers.executeTransaction({
|
|
2892
|
-
messages: [addLinkedResourceMessage],
|
|
2893
|
-
memo: ""
|
|
2988
|
+
saveCheckpoint({
|
|
2989
|
+
status: "running",
|
|
2990
|
+
error: void 0,
|
|
2991
|
+
flowTemplateConfig
|
|
2894
2992
|
});
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2993
|
+
try {
|
|
2994
|
+
let governanceGroupLinkedEntities = checkpoint.governanceGroupLinkedEntities || [];
|
|
2995
|
+
let governanceGroupCoreAddress = checkpoint.governanceGroupCoreAddress || "";
|
|
2996
|
+
if (govConfig && handlers.createGovernanceGroup && !checkpoint.completedSteps?.createGovernanceGroup) {
|
|
2997
|
+
const groupType = govConfig.groupType;
|
|
2998
|
+
const governance = govConfig.governance || {};
|
|
2999
|
+
const config = buildGroupConfig(groupType, governance, memberConfig);
|
|
3000
|
+
const groupResult = await handlers.createGovernanceGroup({
|
|
3001
|
+
groupType,
|
|
3002
|
+
name: govConfig.groupName || domainCardData.credentialSubject?.name || "Governance Group",
|
|
3003
|
+
config
|
|
3004
|
+
});
|
|
3005
|
+
governanceGroupCoreAddress = groupResult.coreAddress;
|
|
3006
|
+
governanceGroupLinkedEntities = [
|
|
3007
|
+
{
|
|
3008
|
+
id: `{id}#${governanceGroupCoreAddress}`,
|
|
3009
|
+
type: "group",
|
|
3010
|
+
relationship: "governs",
|
|
3011
|
+
service: ""
|
|
3012
|
+
}
|
|
3013
|
+
];
|
|
3014
|
+
saveCheckpoint({
|
|
3015
|
+
governanceGroupCoreAddress,
|
|
3016
|
+
governanceGroupLinkedEntities,
|
|
3017
|
+
completedSteps: { createGovernanceGroup: true }
|
|
3018
|
+
});
|
|
3019
|
+
} else if (!govConfig) {
|
|
3020
|
+
saveCheckpoint({ completedSteps: { createGovernanceGroup: true } });
|
|
3021
|
+
}
|
|
3022
|
+
const issuerDid = handlers.getEntityDid?.() || handlers.getCurrentUser?.()?.address;
|
|
3023
|
+
if (!issuerDid) throw new Error("Unable to determine issuer DID");
|
|
3024
|
+
const signAndUploadDomainCard = async (entityDid) => {
|
|
3025
|
+
const credentialSubject = {
|
|
3026
|
+
...domainCardData.credentialSubject,
|
|
3027
|
+
id: entityDid
|
|
3028
|
+
};
|
|
3029
|
+
const unsignedCredential = buildVerifiableCredential({
|
|
3030
|
+
entityDid,
|
|
3031
|
+
issuerDid,
|
|
3032
|
+
credentialSubject,
|
|
3033
|
+
validFrom,
|
|
3034
|
+
validUntil
|
|
3035
|
+
});
|
|
3036
|
+
const pin = await handlers.requestPin({
|
|
3037
|
+
title: "Sign Domain Card",
|
|
3038
|
+
description: "Enter your PIN to sign the Domain Card credential",
|
|
3039
|
+
submitText: "Sign"
|
|
3040
|
+
});
|
|
3041
|
+
const { signedCredential } = await handlers.signCredential({
|
|
3042
|
+
issuerDid,
|
|
3043
|
+
issuerType: "user",
|
|
3044
|
+
credential: unsignedCredential,
|
|
3045
|
+
pin
|
|
3046
|
+
});
|
|
3047
|
+
const credentialBlob = new Blob([JSON.stringify(signedCredential, null, 2)], {
|
|
3048
|
+
type: "application/json"
|
|
3049
|
+
});
|
|
3050
|
+
const credentialFile = new File([credentialBlob], "domainCard.json", {
|
|
3051
|
+
type: "application/json"
|
|
3052
|
+
});
|
|
3053
|
+
const uploadResult = await handlers.publicFileUpload(credentialFile);
|
|
3054
|
+
return {
|
|
3055
|
+
...buildDomainCardLinkedResource({
|
|
3056
|
+
entityDid,
|
|
3057
|
+
cid: uploadResult.cid,
|
|
3058
|
+
serviceEndpoint: uploadResult.url,
|
|
3059
|
+
description: `Domain Card for ${domainCardData.credentialSubject?.name || "Domain"}`
|
|
3060
|
+
}),
|
|
3061
|
+
id: "{id}#dmn"
|
|
3062
|
+
};
|
|
3063
|
+
};
|
|
3064
|
+
const endDate = domainCardData.endDate || validUntil;
|
|
3065
|
+
let newEntityDid = checkpoint.entityDid || "";
|
|
3066
|
+
let transactionHash = checkpoint.transactionHash || "";
|
|
3067
|
+
let linkedResourceTransactionHash = checkpoint.linkedResourceTransactionHash || "";
|
|
3068
|
+
let domainCardLinkedResource = checkpoint.domainCardLinkedResource;
|
|
3069
|
+
if (!checkpoint.completedSteps?.createDomain || !newEntityDid || !transactionHash) {
|
|
3070
|
+
const createResult = await handlers.createDomain({
|
|
3071
|
+
entityType,
|
|
3072
|
+
context: context.length > 0 ? context : void 0,
|
|
3073
|
+
linkedResource: [],
|
|
3074
|
+
linkedEntity: governanceGroupLinkedEntities.length > 0 ? governanceGroupLinkedEntities : void 0,
|
|
3075
|
+
startDate: validFrom,
|
|
3076
|
+
endDate
|
|
3077
|
+
});
|
|
3078
|
+
newEntityDid = createResult.entityDid;
|
|
3079
|
+
transactionHash = createResult.transactionHash;
|
|
3080
|
+
saveCheckpoint({
|
|
3081
|
+
entityDid: newEntityDid,
|
|
3082
|
+
transactionHash,
|
|
3083
|
+
completedSteps: { createDomain: true }
|
|
3084
|
+
});
|
|
3085
|
+
}
|
|
3086
|
+
if (!checkpoint.completedSteps?.signAndUploadDomainCard || !domainCardLinkedResource) {
|
|
3087
|
+
domainCardLinkedResource = await signAndUploadDomainCard(newEntityDid);
|
|
3088
|
+
saveCheckpoint({
|
|
3089
|
+
domainCardLinkedResource,
|
|
3090
|
+
completedSteps: { signAndUploadDomainCard: true }
|
|
3091
|
+
});
|
|
3092
|
+
}
|
|
3093
|
+
if (!checkpoint.completedSteps?.addLinkedResource || !linkedResourceTransactionHash) {
|
|
3094
|
+
const addLinkedResourceMessage = await handlers.createAddLinkedResourceMessage({
|
|
3095
|
+
entityDid: newEntityDid,
|
|
3096
|
+
linkedResource: domainCardLinkedResource
|
|
3097
|
+
});
|
|
3098
|
+
const addLinkedResourceResult = await handlers.executeTransaction({
|
|
3099
|
+
messages: [addLinkedResourceMessage],
|
|
3100
|
+
memo: ""
|
|
3101
|
+
});
|
|
3102
|
+
linkedResourceTransactionHash = String(addLinkedResourceResult?.transactionHash || "");
|
|
3103
|
+
if (!linkedResourceTransactionHash) {
|
|
3104
|
+
throw new Error("Linked resource transaction completed but no transaction hash received");
|
|
3105
|
+
}
|
|
3106
|
+
saveCheckpoint({
|
|
3107
|
+
linkedResourceTransactionHash,
|
|
3108
|
+
completedSteps: { addLinkedResource: true }
|
|
3109
|
+
});
|
|
3110
|
+
}
|
|
3111
|
+
let domainSpaces = checkpoint.domainSpaces;
|
|
3112
|
+
let protocolTemplateImports = checkpoint.protocolTemplateImports || [];
|
|
3113
|
+
if (handlers.sourceDomainSpaces && (!checkpoint.completedSteps?.sourceDomainSpaces || !domainSpaces)) {
|
|
3114
|
+
domainSpaces = await handlers.sourceDomainSpaces({ entityDid: newEntityDid });
|
|
3115
|
+
if (!domainSpaces?.success) {
|
|
3116
|
+
throw new Error("Domain spaces could not be sourced for the newly created domain");
|
|
3117
|
+
}
|
|
3118
|
+
saveCheckpoint({
|
|
3119
|
+
domainSpaces,
|
|
3120
|
+
completedSteps: { sourceDomainSpaces: true }
|
|
3121
|
+
});
|
|
3122
|
+
} else if (!handlers.sourceDomainSpaces) {
|
|
3123
|
+
saveCheckpoint({ completedSteps: { sourceDomainSpaces: true } });
|
|
3124
|
+
}
|
|
3125
|
+
if (selectedProtocolTemplates.length > 0 && !checkpoint.completedSteps?.importTemplates) {
|
|
3126
|
+
if (!handlers.sourceDomainSpaces) {
|
|
3127
|
+
throw new Error("sourceDomainSpaces handler is required to import selected protocol templates");
|
|
3128
|
+
}
|
|
3129
|
+
if (!handlers.importProtocolTemplatesToSpace) {
|
|
3130
|
+
throw new Error("importProtocolTemplatesToSpace handler is required to import selected protocol templates");
|
|
3131
|
+
}
|
|
3132
|
+
const targetFlowsSubspaceId = domainSpaces?.subspaces?.["domain flows"]?.space_id;
|
|
3133
|
+
if (!targetFlowsSubspaceId) {
|
|
3134
|
+
throw new Error("Domain flows subspace was not returned by sourceDomainSpaces");
|
|
3135
|
+
}
|
|
3136
|
+
const groupedTemplates = groupTemplatesByProtocol(selectedProtocolTemplates);
|
|
3137
|
+
protocolTemplateImports = await Promise.all(
|
|
3138
|
+
Array.from(groupedTemplates.entries()).map(async ([protocolDid, templates]) => {
|
|
3139
|
+
const result = await handlers.importProtocolTemplatesToSpace({
|
|
3140
|
+
protocolDid,
|
|
3141
|
+
entityDid: newEntityDid,
|
|
3142
|
+
targetFlowsSubspaceId,
|
|
3143
|
+
templates
|
|
3144
|
+
});
|
|
3145
|
+
return { protocolDid, imported: result.imported };
|
|
3146
|
+
})
|
|
3147
|
+
);
|
|
3148
|
+
saveCheckpoint({
|
|
3149
|
+
protocolTemplateImports,
|
|
3150
|
+
completedSteps: { importTemplates: true }
|
|
3151
|
+
});
|
|
3152
|
+
} else if (selectedProtocolTemplates.length === 0) {
|
|
3153
|
+
saveCheckpoint({
|
|
3154
|
+
protocolTemplateImports,
|
|
3155
|
+
completedSteps: { importTemplates: true }
|
|
3156
|
+
});
|
|
3157
|
+
}
|
|
3158
|
+
const output = {
|
|
2901
3159
|
entityDid: newEntityDid,
|
|
2902
3160
|
governanceGroupCoreAddress,
|
|
2903
3161
|
linkedEntities: governanceGroupLinkedEntities,
|
|
2904
3162
|
linkedResources: [domainCardLinkedResource],
|
|
3163
|
+
flowTemplateConfig,
|
|
3164
|
+
domainSpaces,
|
|
3165
|
+
protocolTemplateImports,
|
|
2905
3166
|
transactionHash,
|
|
2906
3167
|
linkedResourceTransactionHash
|
|
2907
|
-
}
|
|
2908
|
-
|
|
2909
|
-
|
|
3168
|
+
};
|
|
3169
|
+
saveCheckpoint({
|
|
3170
|
+
status: "completed",
|
|
3171
|
+
output
|
|
3172
|
+
});
|
|
3173
|
+
return buildCompletedDomainSignResult(output);
|
|
3174
|
+
} catch (error) {
|
|
3175
|
+
const message = error instanceof Error ? error.message : "Domain sign failed";
|
|
3176
|
+
saveCheckpoint({
|
|
3177
|
+
status: "failed",
|
|
3178
|
+
error: message
|
|
3179
|
+
});
|
|
3180
|
+
throw error;
|
|
3181
|
+
}
|
|
2910
3182
|
}
|
|
2911
3183
|
});
|
|
2912
3184
|
|
|
@@ -3078,9 +3350,7 @@ registerAction({
|
|
|
3078
3350
|
}
|
|
3079
3351
|
const verb = String(inputs.verb || "").trim().toLowerCase();
|
|
3080
3352
|
if (verb !== "propose" && verb !== "execute" && verb !== "check") {
|
|
3081
|
-
throw new Error(
|
|
3082
|
-
'verb is required and must be one of: "propose", "execute", "check"'
|
|
3083
|
-
);
|
|
3353
|
+
throw new Error('verb is required and must be one of: "propose", "execute", "check"');
|
|
3084
3354
|
}
|
|
3085
3355
|
const paymentBlockId = String(inputs.paymentBlockId || "").trim();
|
|
3086
3356
|
if (!paymentBlockId) {
|
|
@@ -3108,6 +3378,15 @@ registerAction({
|
|
|
3108
3378
|
verb,
|
|
3109
3379
|
rowCount: rowIds.length,
|
|
3110
3380
|
paymentBlockId
|
|
3381
|
+
},
|
|
3382
|
+
completion: {
|
|
3383
|
+
state: "awaiting_readback",
|
|
3384
|
+
readBack: {
|
|
3385
|
+
kind: "paymentRows",
|
|
3386
|
+
paymentBlockId,
|
|
3387
|
+
rowIds,
|
|
3388
|
+
verb
|
|
3389
|
+
}
|
|
3111
3390
|
}
|
|
3112
3391
|
};
|
|
3113
3392
|
}
|
|
@@ -5275,6 +5554,7 @@ function toSupportedDID(did) {
|
|
|
5275
5554
|
}
|
|
5276
5555
|
function normalizeDid(did) {
|
|
5277
5556
|
if (did.startsWith("did:")) return did;
|
|
5557
|
+
if (did.startsWith("ixo1")) return `did:ixo:${did}`;
|
|
5278
5558
|
if (!did.startsWith("@did-")) return did;
|
|
5279
5559
|
const [localpart] = did.split(":");
|
|
5280
5560
|
const parts = localpart.split("-");
|
|
@@ -5363,7 +5643,7 @@ var createUcanService = (config) => {
|
|
|
5363
5643
|
const capabilities = [{ can: "flow/*", with: uri }];
|
|
5364
5644
|
if (handlers.createSignerSession && handlers.createDelegationWithSession) {
|
|
5365
5645
|
const session = await handlers.createSignerSession({
|
|
5366
|
-
did:
|
|
5646
|
+
did: normalizedOwnerDid,
|
|
5367
5647
|
didType: issuerType,
|
|
5368
5648
|
entityRoomId,
|
|
5369
5649
|
pin,
|
|
@@ -5371,15 +5651,15 @@ var createUcanService = (config) => {
|
|
|
5371
5651
|
});
|
|
5372
5652
|
const result = await handlers.createDelegationWithSession({
|
|
5373
5653
|
sessionId: session.sessionId,
|
|
5374
|
-
audience:
|
|
5654
|
+
audience: normalizedOwnerDid,
|
|
5375
5655
|
capabilities,
|
|
5376
5656
|
proofs: []
|
|
5377
5657
|
});
|
|
5378
5658
|
const storedDelegation2 = {
|
|
5379
5659
|
cid: result.cid,
|
|
5380
5660
|
delegation: result.delegation,
|
|
5381
|
-
issuerDid:
|
|
5382
|
-
audienceDid:
|
|
5661
|
+
issuerDid: normalizedOwnerDid,
|
|
5662
|
+
audienceDid: normalizedOwnerDid,
|
|
5383
5663
|
capabilities,
|
|
5384
5664
|
createdAt: Date.now(),
|
|
5385
5665
|
format: "car",
|
|
@@ -5420,7 +5700,7 @@ var createUcanService = (config) => {
|
|
|
5420
5700
|
const proofCids = proofs;
|
|
5421
5701
|
if (handlers.createSignerSession && handlers.createDelegationWithSession) {
|
|
5422
5702
|
const session = await handlers.createSignerSession({
|
|
5423
|
-
did:
|
|
5703
|
+
did: normalizedIssuerDid,
|
|
5424
5704
|
didType: issuerType,
|
|
5425
5705
|
entityRoomId,
|
|
5426
5706
|
pin,
|
|
@@ -5429,7 +5709,7 @@ var createUcanService = (config) => {
|
|
|
5429
5709
|
const proofCars = await getProofCars(proofCids);
|
|
5430
5710
|
const result = await handlers.createDelegationWithSession({
|
|
5431
5711
|
sessionId: session.sessionId,
|
|
5432
|
-
audience,
|
|
5712
|
+
audience: normalizedAudienceDid,
|
|
5433
5713
|
capabilities,
|
|
5434
5714
|
proofs: proofCars,
|
|
5435
5715
|
expiration: expiration ? Math.floor(expiration / 1e3) : void 0
|
|
@@ -5437,8 +5717,8 @@ var createUcanService = (config) => {
|
|
|
5437
5717
|
const storedDelegation2 = {
|
|
5438
5718
|
cid: result.cid,
|
|
5439
5719
|
delegation: result.delegation,
|
|
5440
|
-
issuerDid,
|
|
5441
|
-
audienceDid:
|
|
5720
|
+
issuerDid: normalizedIssuerDid,
|
|
5721
|
+
audienceDid: normalizedAudienceDid,
|
|
5442
5722
|
capabilities,
|
|
5443
5723
|
expiration,
|
|
5444
5724
|
createdAt: Date.now(),
|
|
@@ -5491,7 +5771,7 @@ var createUcanService = (config) => {
|
|
|
5491
5771
|
const delegations = delegationStore.getByAudience(audienceDid);
|
|
5492
5772
|
if (delegations.length === 0) {
|
|
5493
5773
|
const root = delegationStore.getRoot();
|
|
5494
|
-
if (root && root.audienceDid === audienceDid) {
|
|
5774
|
+
if (root && normalizeDid(root.audienceDid) === normalizeDid(audienceDid)) {
|
|
5495
5775
|
return { found: true, proofCids: [root.cid] };
|
|
5496
5776
|
}
|
|
5497
5777
|
return { found: false, error: "No delegations found for actor" };
|
|
@@ -5547,7 +5827,7 @@ var createUcanService = (config) => {
|
|
|
5547
5827
|
const isFlowScoped = capability.can === "flow/*" || capability.can.startsWith("flow/");
|
|
5548
5828
|
if (isFlowScoped) {
|
|
5549
5829
|
const root = proofChain[proofChain.length - 1];
|
|
5550
|
-
if (root.issuerDid !== flowOwnerDid) {
|
|
5830
|
+
if (normalizeDid(root.issuerDid) !== normalizeDid(flowOwnerDid)) {
|
|
5551
5831
|
return { valid: false, error: `Root issuer ${root.issuerDid} is not flow owner ${flowOwnerDid}` };
|
|
5552
5832
|
}
|
|
5553
5833
|
}
|
|
@@ -5555,7 +5835,8 @@ var createUcanService = (config) => {
|
|
|
5555
5835
|
};
|
|
5556
5836
|
const createAndValidateInvocation = async (params, _flowId, _blockId) => {
|
|
5557
5837
|
const { invokerDid, invokerType, entityRoomId, capability, proofs, pin } = params;
|
|
5558
|
-
const
|
|
5838
|
+
const normalizedInvokerDid = normalizeDid(invokerDid);
|
|
5839
|
+
const validation = await validateDelegationChain(normalizedInvokerDid, capability);
|
|
5559
5840
|
if (!validation.valid) {
|
|
5560
5841
|
return {
|
|
5561
5842
|
cid: "",
|
|
@@ -5564,11 +5845,11 @@ var createUcanService = (config) => {
|
|
|
5564
5845
|
error: validation.error
|
|
5565
5846
|
};
|
|
5566
5847
|
}
|
|
5567
|
-
const audience = params.audience ?? flowOwnerDid;
|
|
5848
|
+
const audience = normalizeDid(params.audience ?? flowOwnerDid);
|
|
5568
5849
|
if (handlers.createSignerSession && handlers.createInvocationWithSession) {
|
|
5569
5850
|
try {
|
|
5570
5851
|
const session = await handlers.createSignerSession({
|
|
5571
|
-
did:
|
|
5852
|
+
did: normalizedInvokerDid,
|
|
5572
5853
|
didType: invokerType,
|
|
5573
5854
|
entityRoomId,
|
|
5574
5855
|
pin,
|
|
@@ -6083,6 +6364,9 @@ var createRuntimeStateManager = (editor) => {
|
|
|
6083
6364
|
}
|
|
6084
6365
|
return createMemoryManager();
|
|
6085
6366
|
};
|
|
6367
|
+
var createYDocRuntimeManager = (yDoc) => {
|
|
6368
|
+
return createYMapManager(yDoc.getMap("runtime"));
|
|
6369
|
+
};
|
|
6086
6370
|
function clearRuntimeForTemplateClone(yDoc) {
|
|
6087
6371
|
const runtime = yDoc.getMap("runtime");
|
|
6088
6372
|
const invocations = yDoc.getMap("invocations");
|
|
@@ -6100,6 +6384,66 @@ function clearRuntimeForTemplateClone(yDoc) {
|
|
|
6100
6384
|
});
|
|
6101
6385
|
}
|
|
6102
6386
|
|
|
6387
|
+
// src/core/types/baseUcan.ts
|
|
6388
|
+
function isRuntimeRef(value) {
|
|
6389
|
+
return typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string";
|
|
6390
|
+
}
|
|
6391
|
+
|
|
6392
|
+
// src/core/lib/flowCompiler/resolveRefs.ts
|
|
6393
|
+
function resolveRuntimeRefs(nb, getNodeOutput2, triggerContext) {
|
|
6394
|
+
return resolveValue(nb, getNodeOutput2, triggerContext);
|
|
6395
|
+
}
|
|
6396
|
+
function resolveValue(value, getNodeOutput2, triggerContext) {
|
|
6397
|
+
if (isRuntimeRef(value)) {
|
|
6398
|
+
return resolveRef(value.$ref, getNodeOutput2, triggerContext);
|
|
6399
|
+
}
|
|
6400
|
+
if (Array.isArray(value)) {
|
|
6401
|
+
return value.map((item) => resolveValue(item, getNodeOutput2, triggerContext));
|
|
6402
|
+
}
|
|
6403
|
+
if (typeof value === "object" && value !== null) {
|
|
6404
|
+
const result = {};
|
|
6405
|
+
for (const [key, val] of Object.entries(value)) {
|
|
6406
|
+
result[key] = resolveValue(val, getNodeOutput2, triggerContext);
|
|
6407
|
+
}
|
|
6408
|
+
return result;
|
|
6409
|
+
}
|
|
6410
|
+
return value;
|
|
6411
|
+
}
|
|
6412
|
+
function resolveRef(ref, getNodeOutput2, triggerContext) {
|
|
6413
|
+
if (ref.startsWith("trigger.payload.")) {
|
|
6414
|
+
if (!triggerContext) {
|
|
6415
|
+
throw new Error(`Trigger ref "${ref}" used outside of a listener invocation context. trigger.payload.* refs are only valid on block.event-triggered blocks.`);
|
|
6416
|
+
}
|
|
6417
|
+
const fieldPath2 = ref.slice("trigger.payload.".length);
|
|
6418
|
+
return getNestedValue(triggerContext.payload, fieldPath2);
|
|
6419
|
+
}
|
|
6420
|
+
if (triggerContext && Object.prototype.hasOwnProperty.call(triggerContext.refSnapshots, ref)) {
|
|
6421
|
+
return triggerContext.refSnapshots[ref];
|
|
6422
|
+
}
|
|
6423
|
+
const outputIndex = ref.indexOf(".output.");
|
|
6424
|
+
if (outputIndex === -1) {
|
|
6425
|
+
throw new Error(`Invalid runtime reference "${ref}". Expected format: "nodeId.output.fieldPath" or "trigger.payload.fieldPath"`);
|
|
6426
|
+
}
|
|
6427
|
+
const nodeId = ref.slice(0, outputIndex);
|
|
6428
|
+
const fieldPath = ref.slice(outputIndex + ".output.".length);
|
|
6429
|
+
const output = getNodeOutput2(nodeId);
|
|
6430
|
+
if (!output) {
|
|
6431
|
+
return void 0;
|
|
6432
|
+
}
|
|
6433
|
+
return getNestedValue(output, fieldPath);
|
|
6434
|
+
}
|
|
6435
|
+
function getNestedValue(obj, path) {
|
|
6436
|
+
const parts = path.split(".");
|
|
6437
|
+
let current = obj;
|
|
6438
|
+
for (const part of parts) {
|
|
6439
|
+
if (current == null || typeof current !== "object") {
|
|
6440
|
+
return void 0;
|
|
6441
|
+
}
|
|
6442
|
+
current = current[part];
|
|
6443
|
+
}
|
|
6444
|
+
return current;
|
|
6445
|
+
}
|
|
6446
|
+
|
|
6103
6447
|
// src/core/lib/flowEngine/versionManifest.ts
|
|
6104
6448
|
var VERSION_MANIFEST = {
|
|
6105
6449
|
"0.3": {
|
|
@@ -6310,11 +6654,6 @@ var executeNode = async ({ node, actorDid, actorType, entityRoomId, context, act
|
|
|
6310
6654
|
}
|
|
6311
6655
|
};
|
|
6312
6656
|
|
|
6313
|
-
// src/core/types/baseUcan.ts
|
|
6314
|
-
function isRuntimeRef(value) {
|
|
6315
|
-
return typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string";
|
|
6316
|
-
}
|
|
6317
|
-
|
|
6318
6657
|
// src/core/lib/flowEngine/triggers.ts
|
|
6319
6658
|
import * as Y from "yjs";
|
|
6320
6659
|
var RUN_RECORD_AUDIT_TYPE = "block.run";
|
|
@@ -6323,15 +6662,15 @@ function computePendingInvocationId(args) {
|
|
|
6323
6662
|
const input = `${sourceBlockId}:${sourceRunId}:${listenerBlockId}:${eventName}:${eventIndex}`;
|
|
6324
6663
|
return `pi-${fnv1a32(input)}`;
|
|
6325
6664
|
}
|
|
6326
|
-
function snapshotInputRefs(inputs,
|
|
6665
|
+
function snapshotInputRefs(inputs, getNodeOutput2) {
|
|
6327
6666
|
const snapshots = {};
|
|
6328
6667
|
walkRefs(inputs, (ref) => {
|
|
6329
6668
|
if (ref.$ref.startsWith("trigger.")) return;
|
|
6330
6669
|
const parsed = parseOutputRef(ref.$ref);
|
|
6331
6670
|
if (!parsed) return;
|
|
6332
|
-
const output =
|
|
6671
|
+
const output = getNodeOutput2(parsed.nodeId);
|
|
6333
6672
|
if (!output) return;
|
|
6334
|
-
snapshots[ref.$ref] =
|
|
6673
|
+
snapshots[ref.$ref] = getNestedValue2(output, parsed.fieldPath);
|
|
6335
6674
|
});
|
|
6336
6675
|
return snapshots;
|
|
6337
6676
|
}
|
|
@@ -6356,7 +6695,7 @@ function parseOutputRef(ref) {
|
|
|
6356
6695
|
fieldPath: ref.slice(outputIndex + ".output.".length)
|
|
6357
6696
|
};
|
|
6358
6697
|
}
|
|
6359
|
-
function
|
|
6698
|
+
function getNestedValue2(obj, path) {
|
|
6360
6699
|
const parts = path.split(".");
|
|
6361
6700
|
let current = obj;
|
|
6362
6701
|
for (const part of parts) {
|
|
@@ -6584,7 +6923,7 @@ function _reconcilePendingInvocationsInner(editor) {
|
|
|
6584
6923
|
}
|
|
6585
6924
|
if (listenersBySource.size === 0 && barrierListenersBySource.size === 0) return;
|
|
6586
6925
|
const runtimeMap = editor._yRuntime;
|
|
6587
|
-
const
|
|
6926
|
+
const getNodeOutput2 = (nodeId) => {
|
|
6588
6927
|
if (!runtimeMap) return void 0;
|
|
6589
6928
|
const state = runtimeMap.get(nodeId);
|
|
6590
6929
|
if (!state || typeof state !== "object") return void 0;
|
|
@@ -6610,12 +6949,12 @@ function _reconcilePendingInvocationsInner(editor) {
|
|
|
6610
6949
|
if (!hasAnyListener) continue;
|
|
6611
6950
|
const records = readRunRecords(yDoc, sourceBlockId);
|
|
6612
6951
|
for (const record of records) {
|
|
6613
|
-
processRunRecord(yDoc, sourceBlockId, record, listenersBySource,
|
|
6614
|
-
processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBySource,
|
|
6952
|
+
processRunRecord(yDoc, sourceBlockId, record, listenersBySource, getNodeOutput2, runtimeMap);
|
|
6953
|
+
processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBySource, getNodeOutput2, runtimeMap);
|
|
6615
6954
|
}
|
|
6616
6955
|
}
|
|
6617
6956
|
}
|
|
6618
|
-
function processRunRecord(yDoc, sourceBlockId, record, listenersBySource,
|
|
6957
|
+
function processRunRecord(yDoc, sourceBlockId, record, listenersBySource, getNodeOutput2, runtimeMap) {
|
|
6619
6958
|
if (!Array.isArray(record.events)) return;
|
|
6620
6959
|
record.events.forEach((event, eventIndex) => {
|
|
6621
6960
|
if (!event?.name) return;
|
|
@@ -6634,7 +6973,7 @@ function processRunRecord(yDoc, sourceBlockId, record, listenersBySource, getNod
|
|
|
6634
6973
|
});
|
|
6635
6974
|
const assigneeDid = resolveAssignee(listenerBlock) || "unassigned";
|
|
6636
6975
|
const inputs = parseInputs(listenerBlock);
|
|
6637
|
-
const refSnapshots = snapshotInputRefs(inputs,
|
|
6976
|
+
const refSnapshots = snapshotInputRefs(inputs, getNodeOutput2);
|
|
6638
6977
|
const expiresAt = computeExpiry(listenerBlock, record.completedAt);
|
|
6639
6978
|
const invocation = {
|
|
6640
6979
|
id,
|
|
@@ -6659,7 +6998,7 @@ function processRunRecord(yDoc, sourceBlockId, record, listenersBySource, getNod
|
|
|
6659
6998
|
}
|
|
6660
6999
|
});
|
|
6661
7000
|
}
|
|
6662
|
-
function processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBySource,
|
|
7001
|
+
function processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBySource, getNodeOutput2, runtimeMap) {
|
|
6663
7002
|
if (!Array.isArray(record.events)) return;
|
|
6664
7003
|
for (const event of record.events) {
|
|
6665
7004
|
if (!event?.name) continue;
|
|
@@ -6694,7 +7033,7 @@ function processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBy
|
|
|
6694
7033
|
const id = computeBarrierInvocationId(currentState, listenerBlockId);
|
|
6695
7034
|
const mergedPayload = mergeBarrierPayloads(currentState);
|
|
6696
7035
|
const inputs = parseInputs(listenerBlock);
|
|
6697
|
-
const refSnapshots = snapshotInputRefs(inputs,
|
|
7036
|
+
const refSnapshots = snapshotInputRefs(inputs, getNodeOutput2);
|
|
6698
7037
|
const expiresAt = computeExpiry(listenerBlock, record.completedAt);
|
|
6699
7038
|
const invocation = {
|
|
6700
7039
|
id,
|
|
@@ -6804,6 +7143,553 @@ function writeRunRecordAndReconcile(editor, blockId, output, events, actorDid, d
|
|
|
6804
7143
|
reconcilePendingInvocations(editor);
|
|
6805
7144
|
}
|
|
6806
7145
|
|
|
7146
|
+
// src/core/lib/flowEngine/actionExecutor.ts
|
|
7147
|
+
import * as Y3 from "yjs";
|
|
7148
|
+
|
|
7149
|
+
// src/core/lib/flowEngine/readBackReconciler.ts
|
|
7150
|
+
import * as Y2 from "yjs";
|
|
7151
|
+
function isYDoc(value) {
|
|
7152
|
+
return value instanceof Y2.Doc;
|
|
7153
|
+
}
|
|
7154
|
+
function getYDoc(editorOrYDoc) {
|
|
7155
|
+
if (!editorOrYDoc) return void 0;
|
|
7156
|
+
if (isYDoc(editorOrYDoc)) return editorOrYDoc;
|
|
7157
|
+
return editorOrYDoc._yDoc;
|
|
7158
|
+
}
|
|
7159
|
+
function getEditor(editorOrYDoc) {
|
|
7160
|
+
return editorOrYDoc && !isYDoc(editorOrYDoc) ? editorOrYDoc : void 0;
|
|
7161
|
+
}
|
|
7162
|
+
function getRuntime(editorOrYDoc, runtime) {
|
|
7163
|
+
if (runtime) return runtime;
|
|
7164
|
+
const yDoc = getYDoc(editorOrYDoc);
|
|
7165
|
+
if (yDoc) return createYDocRuntimeManager(yDoc);
|
|
7166
|
+
return createRuntimeStateManager(!isYDoc(editorOrYDoc) ? editorOrYDoc : void 0);
|
|
7167
|
+
}
|
|
7168
|
+
function getReconcileEditor(params, yDoc, editor) {
|
|
7169
|
+
if (editor) return editor;
|
|
7170
|
+
if (!yDoc || !params.document) return void 0;
|
|
7171
|
+
return {
|
|
7172
|
+
_yDoc: yDoc,
|
|
7173
|
+
_yRuntime: yDoc.getMap("runtime"),
|
|
7174
|
+
document: params.document
|
|
7175
|
+
};
|
|
7176
|
+
}
|
|
7177
|
+
function makeRunId(now) {
|
|
7178
|
+
return `readback-${now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
7179
|
+
}
|
|
7180
|
+
function asOutput(value) {
|
|
7181
|
+
return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
|
|
7182
|
+
}
|
|
7183
|
+
function errorRecord(error) {
|
|
7184
|
+
if (!error) return void 0;
|
|
7185
|
+
return typeof error === "string" ? { message: error } : { message: error.message, code: error.code };
|
|
7186
|
+
}
|
|
7187
|
+
function normalizeActionReadBackMetadata(params) {
|
|
7188
|
+
const base = params.readBack && typeof params.readBack === "object" && !Array.isArray(params.readBack) ? { ...params.readBack } : {};
|
|
7189
|
+
const kind = typeof base.kind === "string" && base.kind.trim() ? base.kind.trim() : params.actionType;
|
|
7190
|
+
const normalized = {
|
|
7191
|
+
...base,
|
|
7192
|
+
kind,
|
|
7193
|
+
status: "pending",
|
|
7194
|
+
requestedAt: typeof base.requestedAt === "string" ? base.requestedAt : new Date(params.requestedAt).toISOString(),
|
|
7195
|
+
blockId: params.blockId,
|
|
7196
|
+
actionType: params.actionType,
|
|
7197
|
+
actorDid: params.actorDid,
|
|
7198
|
+
invocationCid: params.invocationCid,
|
|
7199
|
+
capabilityId: params.capabilityId
|
|
7200
|
+
};
|
|
7201
|
+
if (params.pendingInvocation) {
|
|
7202
|
+
normalized.pendingInvocation = {
|
|
7203
|
+
id: params.pendingInvocation.id,
|
|
7204
|
+
triggeringBlockId: params.pendingInvocation.triggeringBlockId,
|
|
7205
|
+
eventName: params.pendingInvocation.eventName,
|
|
7206
|
+
sourceRunId: params.pendingInvocation.sourceRunId
|
|
7207
|
+
};
|
|
7208
|
+
}
|
|
7209
|
+
return normalized;
|
|
7210
|
+
}
|
|
7211
|
+
function writeReconciliationRunRecord(params) {
|
|
7212
|
+
if (!params.yDoc) return void 0;
|
|
7213
|
+
const completedAt = params.now();
|
|
7214
|
+
const runId = makeRunId(params.now);
|
|
7215
|
+
const pendingInvocation = params.readBack.pendingInvocation;
|
|
7216
|
+
const details = {
|
|
7217
|
+
runId,
|
|
7218
|
+
output: params.output,
|
|
7219
|
+
events: params.events,
|
|
7220
|
+
startedAt: params.readBack.requestedAt || new Date(completedAt).toISOString(),
|
|
7221
|
+
completedAt: new Date(completedAt).toISOString(),
|
|
7222
|
+
actorDid: params.actorDid,
|
|
7223
|
+
invocationCid: params.readBack.invocationCid,
|
|
7224
|
+
capabilityId: params.readBack.capabilityId,
|
|
7225
|
+
error: params.error,
|
|
7226
|
+
readBack: params.readBack,
|
|
7227
|
+
reconciled: true
|
|
7228
|
+
};
|
|
7229
|
+
if (pendingInvocation) {
|
|
7230
|
+
details.fromPendingInvocationId = pendingInvocation.id;
|
|
7231
|
+
details.triggeredBy = {
|
|
7232
|
+
sourceBlockId: pendingInvocation.triggeringBlockId,
|
|
7233
|
+
eventName: pendingInvocation.eventName
|
|
7234
|
+
};
|
|
7235
|
+
details.sourceRunId = pendingInvocation.sourceRunId;
|
|
7236
|
+
}
|
|
7237
|
+
appendRunRecord(params.yDoc, params.blockId, details, params.actorDid);
|
|
7238
|
+
if (params.editor && params.events.length > 0) {
|
|
7239
|
+
reconcilePendingInvocations(params.editor);
|
|
7240
|
+
}
|
|
7241
|
+
return runId;
|
|
7242
|
+
}
|
|
7243
|
+
async function reconcileActionReadBack(params) {
|
|
7244
|
+
const now = params.now || Date.now;
|
|
7245
|
+
const yDoc = getYDoc(params.editorOrYDoc);
|
|
7246
|
+
const editor = getEditor(params.editorOrYDoc);
|
|
7247
|
+
const runtime = getRuntime(params.editorOrYDoc, params.runtime);
|
|
7248
|
+
const current = runtime.get(params.blockId);
|
|
7249
|
+
const output = asOutput(current.output);
|
|
7250
|
+
const readBack = current.readBack;
|
|
7251
|
+
if (current.state !== "awaiting_readback" || !readBack?.kind) {
|
|
7252
|
+
return {
|
|
7253
|
+
success: false,
|
|
7254
|
+
blockId: params.blockId,
|
|
7255
|
+
state: current.state === "failed" ? "failed" : "pending",
|
|
7256
|
+
output,
|
|
7257
|
+
events: [],
|
|
7258
|
+
error: `Block "${params.blockId}" is not awaiting read-back`,
|
|
7259
|
+
pendingInvocationRemoved: false,
|
|
7260
|
+
readBack
|
|
7261
|
+
};
|
|
7262
|
+
}
|
|
7263
|
+
const resolver = params.resolver || params.resolvers?.[readBack.kind];
|
|
7264
|
+
if (!resolver) {
|
|
7265
|
+
return {
|
|
7266
|
+
success: false,
|
|
7267
|
+
blockId: params.blockId,
|
|
7268
|
+
state: "pending",
|
|
7269
|
+
output,
|
|
7270
|
+
events: [],
|
|
7271
|
+
error: `No read-back resolver registered for "${readBack.kind}"`,
|
|
7272
|
+
pendingInvocationRemoved: false,
|
|
7273
|
+
readBack
|
|
7274
|
+
};
|
|
7275
|
+
}
|
|
7276
|
+
const resolution = await resolver({
|
|
7277
|
+
blockId: params.blockId,
|
|
7278
|
+
runtime: current,
|
|
7279
|
+
output,
|
|
7280
|
+
readBack
|
|
7281
|
+
});
|
|
7282
|
+
const checkedAt = now();
|
|
7283
|
+
const checkedIso = new Date(checkedAt).toISOString();
|
|
7284
|
+
const nextReadBack = {
|
|
7285
|
+
...readBack,
|
|
7286
|
+
...resolution.readBack || {},
|
|
7287
|
+
status: resolution.state,
|
|
7288
|
+
lastCheckedAt: checkedIso
|
|
7289
|
+
};
|
|
7290
|
+
if (resolution.state === "pending") {
|
|
7291
|
+
runtime.update(params.blockId, {
|
|
7292
|
+
readBack: nextReadBack
|
|
7293
|
+
});
|
|
7294
|
+
return {
|
|
7295
|
+
success: true,
|
|
7296
|
+
blockId: params.blockId,
|
|
7297
|
+
state: "pending",
|
|
7298
|
+
output,
|
|
7299
|
+
events: resolution.events || [],
|
|
7300
|
+
pendingInvocationRemoved: false,
|
|
7301
|
+
readBack: nextReadBack
|
|
7302
|
+
};
|
|
7303
|
+
}
|
|
7304
|
+
const events = resolution.events || [];
|
|
7305
|
+
const finalOutput = {
|
|
7306
|
+
...output,
|
|
7307
|
+
...resolution.output || {}
|
|
7308
|
+
};
|
|
7309
|
+
const actorDid = params.actorDid || readBack.actorDid || current.executedByDid || "system:readback";
|
|
7310
|
+
if (resolution.state === "failed") {
|
|
7311
|
+
const error = errorRecord(resolution.error) || { message: "External read-back failed" };
|
|
7312
|
+
const failedReadBack = {
|
|
7313
|
+
...nextReadBack,
|
|
7314
|
+
terminalAt: checkedIso
|
|
7315
|
+
};
|
|
7316
|
+
runtime.update(params.blockId, {
|
|
7317
|
+
state: "failed",
|
|
7318
|
+
output: finalOutput,
|
|
7319
|
+
error: { ...error, at: checkedAt },
|
|
7320
|
+
readBack: failedReadBack
|
|
7321
|
+
});
|
|
7322
|
+
const runId2 = writeReconciliationRunRecord({
|
|
7323
|
+
yDoc,
|
|
7324
|
+
editor: getReconcileEditor(params, yDoc, editor),
|
|
7325
|
+
blockId: params.blockId,
|
|
7326
|
+
actorDid,
|
|
7327
|
+
output: finalOutput,
|
|
7328
|
+
events,
|
|
7329
|
+
readBack: failedReadBack,
|
|
7330
|
+
error,
|
|
7331
|
+
now
|
|
7332
|
+
});
|
|
7333
|
+
return {
|
|
7334
|
+
success: false,
|
|
7335
|
+
blockId: params.blockId,
|
|
7336
|
+
state: "failed",
|
|
7337
|
+
output: finalOutput,
|
|
7338
|
+
events,
|
|
7339
|
+
error: error.message,
|
|
7340
|
+
runId: runId2,
|
|
7341
|
+
pendingInvocationRemoved: false,
|
|
7342
|
+
readBack: failedReadBack
|
|
7343
|
+
};
|
|
7344
|
+
}
|
|
7345
|
+
const completedReadBack = {
|
|
7346
|
+
...nextReadBack,
|
|
7347
|
+
terminalAt: checkedIso
|
|
7348
|
+
};
|
|
7349
|
+
runtime.update(params.blockId, {
|
|
7350
|
+
state: "completed",
|
|
7351
|
+
output: finalOutput,
|
|
7352
|
+
executedAt: checkedAt,
|
|
7353
|
+
error: void 0,
|
|
7354
|
+
readBack: completedReadBack
|
|
7355
|
+
});
|
|
7356
|
+
const runId = writeReconciliationRunRecord({
|
|
7357
|
+
yDoc,
|
|
7358
|
+
editor: getReconcileEditor(params, yDoc, editor),
|
|
7359
|
+
blockId: params.blockId,
|
|
7360
|
+
actorDid,
|
|
7361
|
+
output: finalOutput,
|
|
7362
|
+
events,
|
|
7363
|
+
readBack: completedReadBack,
|
|
7364
|
+
now
|
|
7365
|
+
});
|
|
7366
|
+
const pendingInvocationRemoved = Boolean(yDoc && completedReadBack.pendingInvocation?.id) && removePendingInvocation(yDoc, params.blockId, completedReadBack.pendingInvocation.id);
|
|
7367
|
+
return {
|
|
7368
|
+
success: true,
|
|
7369
|
+
blockId: params.blockId,
|
|
7370
|
+
state: "completed",
|
|
7371
|
+
output: finalOutput,
|
|
7372
|
+
events,
|
|
7373
|
+
runId,
|
|
7374
|
+
pendingInvocationRemoved,
|
|
7375
|
+
readBack: completedReadBack
|
|
7376
|
+
};
|
|
7377
|
+
}
|
|
7378
|
+
|
|
7379
|
+
// src/core/lib/flowEngine/actionExecutor.ts
|
|
7380
|
+
function isYDoc2(value) {
|
|
7381
|
+
return value instanceof Y3.Doc;
|
|
7382
|
+
}
|
|
7383
|
+
function getYDoc2(editorOrYDoc) {
|
|
7384
|
+
if (!editorOrYDoc) return void 0;
|
|
7385
|
+
if (isYDoc2(editorOrYDoc)) return editorOrYDoc;
|
|
7386
|
+
return editorOrYDoc._yDoc;
|
|
7387
|
+
}
|
|
7388
|
+
function parseInputs2(value) {
|
|
7389
|
+
if (value == null || value === "") return {};
|
|
7390
|
+
if (typeof value === "object" && !Array.isArray(value)) return { ...value };
|
|
7391
|
+
if (typeof value !== "string") return {};
|
|
7392
|
+
try {
|
|
7393
|
+
const parsed = JSON.parse(value);
|
|
7394
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
7395
|
+
} catch {
|
|
7396
|
+
return {};
|
|
7397
|
+
}
|
|
7398
|
+
}
|
|
7399
|
+
function getRuntime2(editorOrYDoc, runtime) {
|
|
7400
|
+
if (runtime) return runtime;
|
|
7401
|
+
const yDoc = getYDoc2(editorOrYDoc);
|
|
7402
|
+
if (yDoc) return createYDocRuntimeManager(yDoc);
|
|
7403
|
+
return createRuntimeStateManager(!isYDoc2(editorOrYDoc) ? editorOrYDoc : void 0);
|
|
7404
|
+
}
|
|
7405
|
+
function getEditor2(editorOrYDoc) {
|
|
7406
|
+
return editorOrYDoc && !isYDoc2(editorOrYDoc) ? editorOrYDoc : void 0;
|
|
7407
|
+
}
|
|
7408
|
+
function findBlock(params) {
|
|
7409
|
+
if (params.block) return params.block;
|
|
7410
|
+
const blockId = params.blockId;
|
|
7411
|
+
if (!blockId) return void 0;
|
|
7412
|
+
const editor = getEditor2(params.editorOrYDoc);
|
|
7413
|
+
return (params.document || editor?.document || []).find((block) => block?.id === blockId);
|
|
7414
|
+
}
|
|
7415
|
+
function getFlowMetadata(editor) {
|
|
7416
|
+
const metadata = editor?.getFlowMetadata?.();
|
|
7417
|
+
const flowId = metadata?.doc_id || "";
|
|
7418
|
+
return {
|
|
7419
|
+
flowId,
|
|
7420
|
+
flowUri: flowId ? `ixo:flow:${flowId}` : "",
|
|
7421
|
+
flowOwnerDid: editor?.getFlowOwnerDid?.() || metadata?.flowOwnerDid || "",
|
|
7422
|
+
schemaVersion: metadata?.schema_version || "0.3"
|
|
7423
|
+
};
|
|
7424
|
+
}
|
|
7425
|
+
function getPendingInvocation(yDoc, blockId, pendingInvocationId) {
|
|
7426
|
+
if (!pendingInvocationId) return void 0;
|
|
7427
|
+
if (!yDoc) {
|
|
7428
|
+
throw new Error(`Cannot load pending invocation "${pendingInvocationId}" without a Y.Doc`);
|
|
7429
|
+
}
|
|
7430
|
+
if (!blockId) {
|
|
7431
|
+
throw new Error(`Cannot load pending invocation "${pendingInvocationId}" without a block id`);
|
|
7432
|
+
}
|
|
7433
|
+
const pending = readPendingInvocations(yDoc, blockId).find((invocation) => invocation.id === pendingInvocationId);
|
|
7434
|
+
if (!pending) {
|
|
7435
|
+
throw new Error(`Pending invocation "${pendingInvocationId}" was not found for block "${blockId}"`);
|
|
7436
|
+
}
|
|
7437
|
+
return pending;
|
|
7438
|
+
}
|
|
7439
|
+
function getNodeOutput(runtime, nodeId) {
|
|
7440
|
+
const state = runtime.get(nodeId);
|
|
7441
|
+
const output = state.output;
|
|
7442
|
+
return output && typeof output === "object" && !Array.isArray(output) ? output : void 0;
|
|
7443
|
+
}
|
|
7444
|
+
function buildActionRunInputs(params) {
|
|
7445
|
+
const blockId = params.blockId || params.block?.id;
|
|
7446
|
+
const yDoc = getYDoc2(params.editorOrYDoc);
|
|
7447
|
+
const runtime = getRuntime2(params.editorOrYDoc, params.runtime);
|
|
7448
|
+
const savedInputs = parseInputs2(params.savedInputs ?? params.block?.props?.inputs);
|
|
7449
|
+
const pendingInvocation = getPendingInvocation(yDoc, blockId, params.pendingInvocationId);
|
|
7450
|
+
const triggerContext = pendingInvocation ? {
|
|
7451
|
+
payload: pendingInvocation.payload || {},
|
|
7452
|
+
refSnapshots: pendingInvocation.refSnapshots || {}
|
|
7453
|
+
} : void 0;
|
|
7454
|
+
const mergedInputs = {
|
|
7455
|
+
...savedInputs,
|
|
7456
|
+
...pendingInvocation?.payload || {},
|
|
7457
|
+
...pendingInvocation?.refSnapshots || {},
|
|
7458
|
+
...params.runtimeInputs || {}
|
|
7459
|
+
};
|
|
7460
|
+
return {
|
|
7461
|
+
inputs: resolveRuntimeRefs(mergedInputs, (nodeId) => getNodeOutput(runtime, nodeId), triggerContext),
|
|
7462
|
+
savedInputs,
|
|
7463
|
+
mergedInputs,
|
|
7464
|
+
pendingInvocation,
|
|
7465
|
+
triggerContext
|
|
7466
|
+
};
|
|
7467
|
+
}
|
|
7468
|
+
function buildFailureResult(params) {
|
|
7469
|
+
return {
|
|
7470
|
+
success: false,
|
|
7471
|
+
stage: params.stage,
|
|
7472
|
+
blockId: params.blockId,
|
|
7473
|
+
actionType: params.actionType,
|
|
7474
|
+
events: [],
|
|
7475
|
+
error: params.error,
|
|
7476
|
+
completionState: "failed",
|
|
7477
|
+
pendingInvocation: params.pendingInvocation
|
|
7478
|
+
};
|
|
7479
|
+
}
|
|
7480
|
+
function updateRuntimeFailure(runtime, blockId, message, now) {
|
|
7481
|
+
runtime.update(blockId, {
|
|
7482
|
+
state: "failed",
|
|
7483
|
+
error: { message, at: now() }
|
|
7484
|
+
});
|
|
7485
|
+
}
|
|
7486
|
+
function makeRunId2(now) {
|
|
7487
|
+
return `run-${now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
7488
|
+
}
|
|
7489
|
+
function getReconcileEditor2(params, yDoc, editor) {
|
|
7490
|
+
if (editor) return editor;
|
|
7491
|
+
if (!yDoc || !params.document) return void 0;
|
|
7492
|
+
return {
|
|
7493
|
+
_yDoc: yDoc,
|
|
7494
|
+
_yRuntime: yDoc.getMap("runtime"),
|
|
7495
|
+
document: params.document
|
|
7496
|
+
};
|
|
7497
|
+
}
|
|
7498
|
+
function persistEvents(params) {
|
|
7499
|
+
if (!params.yDoc || params.events.length === 0) return void 0;
|
|
7500
|
+
const runId = makeRunId2(params.now);
|
|
7501
|
+
const details = {
|
|
7502
|
+
runId,
|
|
7503
|
+
output: params.output,
|
|
7504
|
+
events: params.events,
|
|
7505
|
+
startedAt: new Date(params.startedAt).toISOString(),
|
|
7506
|
+
completedAt: new Date(params.completedAt).toISOString(),
|
|
7507
|
+
actorDid: params.actorDid,
|
|
7508
|
+
invocationCid: params.invocationCid,
|
|
7509
|
+
capabilityId: params.capabilityId
|
|
7510
|
+
};
|
|
7511
|
+
if (params.pendingInvocation) {
|
|
7512
|
+
details.fromPendingInvocationId = params.pendingInvocation.id;
|
|
7513
|
+
details.triggeredBy = {
|
|
7514
|
+
sourceBlockId: params.pendingInvocation.triggeringBlockId,
|
|
7515
|
+
eventName: params.pendingInvocation.eventName
|
|
7516
|
+
};
|
|
7517
|
+
details.sourceRunId = params.pendingInvocation.sourceRunId;
|
|
7518
|
+
}
|
|
7519
|
+
appendRunRecord(params.yDoc, params.blockId, details, params.actorDid);
|
|
7520
|
+
if (params.editor) {
|
|
7521
|
+
reconcilePendingInvocations(params.editor);
|
|
7522
|
+
}
|
|
7523
|
+
return runId;
|
|
7524
|
+
}
|
|
7525
|
+
function cleanupCompletedPendingInvocation(yDoc, blockId, pendingInvocation) {
|
|
7526
|
+
if (!yDoc || !pendingInvocation) return false;
|
|
7527
|
+
return removePendingInvocation(yDoc, blockId, pendingInvocation.id);
|
|
7528
|
+
}
|
|
7529
|
+
async function executeActionBlock(params) {
|
|
7530
|
+
const block = findBlock(params);
|
|
7531
|
+
const blockId = params.blockId || block?.id;
|
|
7532
|
+
const editor = getEditor2(params.editorOrYDoc);
|
|
7533
|
+
const yDoc = getYDoc2(params.editorOrYDoc);
|
|
7534
|
+
const runtime = getRuntime2(params.editorOrYDoc, params.runtime);
|
|
7535
|
+
const now = params.now || Date.now;
|
|
7536
|
+
if (!block || !blockId) {
|
|
7537
|
+
return buildFailureResult({
|
|
7538
|
+
blockId: blockId || "",
|
|
7539
|
+
stage: "input",
|
|
7540
|
+
error: blockId ? `Block "${blockId}" was not found` : "executeActionBlock requires a blockId or block"
|
|
7541
|
+
});
|
|
7542
|
+
}
|
|
7543
|
+
const actionType = typeof block.props?.actionType === "string" ? block.props.actionType : void 0;
|
|
7544
|
+
if (!actionType) {
|
|
7545
|
+
updateRuntimeFailure(runtime, blockId, "Action block is missing props.actionType", now);
|
|
7546
|
+
return buildFailureResult({
|
|
7547
|
+
blockId,
|
|
7548
|
+
stage: "input",
|
|
7549
|
+
error: "Action block is missing props.actionType"
|
|
7550
|
+
});
|
|
7551
|
+
}
|
|
7552
|
+
const action = getAction(actionType);
|
|
7553
|
+
if (!action) {
|
|
7554
|
+
const message = `No registered action found for ${actionType}`;
|
|
7555
|
+
updateRuntimeFailure(runtime, blockId, message, now);
|
|
7556
|
+
return buildFailureResult({ blockId, actionType, stage: "action_lookup", error: message });
|
|
7557
|
+
}
|
|
7558
|
+
let inputBuild;
|
|
7559
|
+
try {
|
|
7560
|
+
inputBuild = buildActionRunInputs({ ...params, block, blockId, runtime });
|
|
7561
|
+
} catch (error) {
|
|
7562
|
+
const message = error instanceof Error ? error.message : "Failed to build action inputs";
|
|
7563
|
+
updateRuntimeFailure(runtime, blockId, message, now);
|
|
7564
|
+
return buildFailureResult({ blockId, actionType, stage: "input", error: message });
|
|
7565
|
+
}
|
|
7566
|
+
const flowNode = buildFlowNodeFromBlock(block);
|
|
7567
|
+
const metadata = getFlowMetadata(editor);
|
|
7568
|
+
const flowId = params.flowId || metadata.flowId || blockId;
|
|
7569
|
+
const flowUri = params.flowUri || metadata.flowUri || `ixo:flow:${flowId}`;
|
|
7570
|
+
const flowOwnerDid = params.flowOwnerDid || metadata.flowOwnerDid;
|
|
7571
|
+
const schemaVersion = params.schemaVersion || metadata.schemaVersion;
|
|
7572
|
+
const events = [];
|
|
7573
|
+
let completionState = "completed";
|
|
7574
|
+
let readBack;
|
|
7575
|
+
let rawReadBack;
|
|
7576
|
+
let requestedAwaitingReadBack = false;
|
|
7577
|
+
const startedAt = now();
|
|
7578
|
+
runtime.update(blockId, {
|
|
7579
|
+
state: "running",
|
|
7580
|
+
output: void 0,
|
|
7581
|
+
error: void 0,
|
|
7582
|
+
executedByDid: params.actorDid
|
|
7583
|
+
});
|
|
7584
|
+
const outcome = await executeNode({
|
|
7585
|
+
node: flowNode,
|
|
7586
|
+
actorDid: params.actorDid,
|
|
7587
|
+
actorType: params.actorType,
|
|
7588
|
+
entityRoomId: params.entityRoomId,
|
|
7589
|
+
context: {
|
|
7590
|
+
runtime,
|
|
7591
|
+
ucanService: params.ucanService || editor?.getUcanService?.() || void 0,
|
|
7592
|
+
invocationStore: params.invocationStore || editor?._invocationStore,
|
|
7593
|
+
flowUri,
|
|
7594
|
+
flowId,
|
|
7595
|
+
flowOwnerDid,
|
|
7596
|
+
schemaVersion,
|
|
7597
|
+
now
|
|
7598
|
+
},
|
|
7599
|
+
action: async () => {
|
|
7600
|
+
const result = await action.run(inputBuild.inputs, {
|
|
7601
|
+
actorDid: params.actorDid,
|
|
7602
|
+
flowId,
|
|
7603
|
+
flowUri,
|
|
7604
|
+
nodeId: blockId,
|
|
7605
|
+
flowNode,
|
|
7606
|
+
runtime,
|
|
7607
|
+
services: params.services || {},
|
|
7608
|
+
handlers: params.handlers,
|
|
7609
|
+
editor,
|
|
7610
|
+
pendingInvocation: inputBuild.pendingInvocation
|
|
7611
|
+
});
|
|
7612
|
+
if (result.events?.length) events.push(...result.events);
|
|
7613
|
+
if (result.completion?.state === "awaiting_readback") {
|
|
7614
|
+
requestedAwaitingReadBack = true;
|
|
7615
|
+
rawReadBack = result.completion.readBack;
|
|
7616
|
+
}
|
|
7617
|
+
return {
|
|
7618
|
+
payload: result.output,
|
|
7619
|
+
submittedByDid: params.actorDid || void 0
|
|
7620
|
+
};
|
|
7621
|
+
},
|
|
7622
|
+
pin: params.pin || ""
|
|
7623
|
+
});
|
|
7624
|
+
if (!outcome.success) {
|
|
7625
|
+
const message = outcome.error || "Action execution failed";
|
|
7626
|
+
updateRuntimeFailure(runtime, blockId, message, now);
|
|
7627
|
+
return {
|
|
7628
|
+
...buildFailureResult({
|
|
7629
|
+
blockId,
|
|
7630
|
+
actionType,
|
|
7631
|
+
stage: outcome.stage,
|
|
7632
|
+
error: message,
|
|
7633
|
+
pendingInvocation: inputBuild.pendingInvocation
|
|
7634
|
+
}),
|
|
7635
|
+
invocationCid: outcome.invocationCid,
|
|
7636
|
+
capabilityId: outcome.capabilityId
|
|
7637
|
+
};
|
|
7638
|
+
}
|
|
7639
|
+
const output = outcome.result?.payload || {};
|
|
7640
|
+
const completedAt = now();
|
|
7641
|
+
if (requestedAwaitingReadBack) {
|
|
7642
|
+
completionState = "awaiting_readback";
|
|
7643
|
+
readBack = normalizeActionReadBackMetadata({
|
|
7644
|
+
readBack: rawReadBack,
|
|
7645
|
+
blockId,
|
|
7646
|
+
actionType,
|
|
7647
|
+
actorDid: params.actorDid,
|
|
7648
|
+
invocationCid: outcome.invocationCid,
|
|
7649
|
+
capabilityId: outcome.capabilityId,
|
|
7650
|
+
requestedAt: startedAt,
|
|
7651
|
+
pendingInvocation: inputBuild.pendingInvocation
|
|
7652
|
+
});
|
|
7653
|
+
}
|
|
7654
|
+
runtime.update(blockId, {
|
|
7655
|
+
state: completionState,
|
|
7656
|
+
output,
|
|
7657
|
+
executedByDid: params.actorDid,
|
|
7658
|
+
executedAt: completedAt,
|
|
7659
|
+
lastInvocationCid: outcome.invocationCid || outcome.capabilityId,
|
|
7660
|
+
readBack
|
|
7661
|
+
});
|
|
7662
|
+
const runId = persistEvents({
|
|
7663
|
+
yDoc,
|
|
7664
|
+
editor: getReconcileEditor2(params, yDoc, editor),
|
|
7665
|
+
blockId,
|
|
7666
|
+
actorDid: params.actorDid,
|
|
7667
|
+
output,
|
|
7668
|
+
events,
|
|
7669
|
+
invocationCid: outcome.invocationCid,
|
|
7670
|
+
capabilityId: outcome.capabilityId,
|
|
7671
|
+
pendingInvocation: inputBuild.pendingInvocation,
|
|
7672
|
+
startedAt,
|
|
7673
|
+
completedAt,
|
|
7674
|
+
now
|
|
7675
|
+
});
|
|
7676
|
+
const pendingInvocationRemoved = completionState === "completed" ? cleanupCompletedPendingInvocation(yDoc, blockId, inputBuild.pendingInvocation) : false;
|
|
7677
|
+
return {
|
|
7678
|
+
success: true,
|
|
7679
|
+
stage: outcome.stage,
|
|
7680
|
+
blockId,
|
|
7681
|
+
actionType,
|
|
7682
|
+
output,
|
|
7683
|
+
events,
|
|
7684
|
+
invocationCid: outcome.invocationCid,
|
|
7685
|
+
capabilityId: outcome.capabilityId,
|
|
7686
|
+
runId,
|
|
7687
|
+
pendingInvocationRemoved,
|
|
7688
|
+
completionState,
|
|
7689
|
+
pendingInvocation: inputBuild.pendingInvocation
|
|
7690
|
+
};
|
|
7691
|
+
}
|
|
7692
|
+
|
|
6807
7693
|
// src/core/lib/flowEngine/migration.ts
|
|
6808
7694
|
var MIGRATION_REGISTRY = {};
|
|
6809
7695
|
function registerMigration(definition) {
|
|
@@ -7251,13 +8137,13 @@ function detectTriggerCycles(triggerEdges) {
|
|
|
7251
8137
|
}
|
|
7252
8138
|
|
|
7253
8139
|
// src/core/lib/flowCompiler/readFlow.ts
|
|
7254
|
-
import * as
|
|
8140
|
+
import * as Y4 from "yjs";
|
|
7255
8141
|
function readCompiledFlowFromYDoc(yDoc) {
|
|
7256
8142
|
const flowMeta = yDoc.getMap("qi.flow.meta");
|
|
7257
8143
|
const flowNodes = yDoc.getMap("qi.flow.nodes");
|
|
7258
8144
|
const nodes = {};
|
|
7259
8145
|
flowNodes.forEach((value, nodeId) => {
|
|
7260
|
-
if (value instanceof
|
|
8146
|
+
if (value instanceof Y4.Map) {
|
|
7261
8147
|
nodes[nodeId] = yMapToFlowNode(value);
|
|
7262
8148
|
}
|
|
7263
8149
|
});
|
|
@@ -7277,7 +8163,7 @@ function readCompiledFlowFromYDoc(yDoc) {
|
|
|
7277
8163
|
const flowEdges = yDoc.getMap("qi.flow.edges");
|
|
7278
8164
|
const edges = [];
|
|
7279
8165
|
flowEdges.forEach((value) => {
|
|
7280
|
-
if (value instanceof
|
|
8166
|
+
if (value instanceof Y4.Map) {
|
|
7281
8167
|
edges.push(yMapToEdge(value));
|
|
7282
8168
|
}
|
|
7283
8169
|
});
|
|
@@ -7458,11 +8344,11 @@ function nodeToCapability(node) {
|
|
|
7458
8344
|
}
|
|
7459
8345
|
|
|
7460
8346
|
// src/core/lib/flowCompiler/setup.ts
|
|
7461
|
-
import * as
|
|
8347
|
+
import * as Y7 from "yjs";
|
|
7462
8348
|
import { MatrixProvider } from "@ixo/matrix-crdt";
|
|
7463
8349
|
|
|
7464
8350
|
// src/core/lib/flowCompiler/hydrate.ts
|
|
7465
|
-
import * as
|
|
8351
|
+
import * as Y5 from "yjs";
|
|
7466
8352
|
function hydrateYDocFromCompiledFlow(yDoc, compiled) {
|
|
7467
8353
|
yDoc.transact(() => {
|
|
7468
8354
|
const flowMeta = yDoc.getMap("qi.flow.meta");
|
|
@@ -7477,7 +8363,7 @@ function hydrateYDocFromCompiledFlow(yDoc, compiled) {
|
|
|
7477
8363
|
}
|
|
7478
8364
|
const flowEdges = yDoc.getMap("qi.flow.edges");
|
|
7479
8365
|
for (const edge of compiled.edges) {
|
|
7480
|
-
const yEdge = new
|
|
8366
|
+
const yEdge = new Y5.Map();
|
|
7481
8367
|
yEdge.set("id", edge.id);
|
|
7482
8368
|
yEdge.set("source", edge.source);
|
|
7483
8369
|
yEdge.set("target", edge.target);
|
|
@@ -7531,7 +8417,7 @@ function hydrateYDocFromMergeResult(yDoc, mergeResult) {
|
|
|
7531
8417
|
const flowEdges = yDoc.getMap("qi.flow.edges");
|
|
7532
8418
|
flowEdges.forEach((_, key) => flowEdges.delete(key));
|
|
7533
8419
|
for (const edge of merged.edges) {
|
|
7534
|
-
const yEdge = new
|
|
8420
|
+
const yEdge = new Y5.Map();
|
|
7535
8421
|
yEdge.set("id", edge.id);
|
|
7536
8422
|
yEdge.set("source", edge.source);
|
|
7537
8423
|
yEdge.set("target", edge.target);
|
|
@@ -7566,7 +8452,7 @@ function initializeRuntimeForNodes(runtimeMap, compiled, nodeIds) {
|
|
|
7566
8452
|
}
|
|
7567
8453
|
}
|
|
7568
8454
|
function createYMapFromNode(node) {
|
|
7569
|
-
const yNode = new
|
|
8455
|
+
const yNode = new Y5.Map();
|
|
7570
8456
|
yNode.set("id", node.id);
|
|
7571
8457
|
yNode.set("blockId", node.blockId);
|
|
7572
8458
|
yNode.set("can", node.can);
|
|
@@ -7581,7 +8467,7 @@ function createYMapFromNode(node) {
|
|
|
7581
8467
|
}
|
|
7582
8468
|
|
|
7583
8469
|
// src/core/lib/flowCompiler/documentFragment.ts
|
|
7584
|
-
import * as
|
|
8470
|
+
import * as Y6 from "yjs";
|
|
7585
8471
|
function writeCompiledBlocksToFragment(fragment, blocks) {
|
|
7586
8472
|
const documentBlockGroup = getOrCreateDocumentBlockGroup(fragment);
|
|
7587
8473
|
for (const block of blocks) {
|
|
@@ -7600,7 +8486,7 @@ function replaceBlockInFragment(fragment, block) {
|
|
|
7600
8486
|
if (!blockGroup) return false;
|
|
7601
8487
|
for (let i = 0; i < blockGroup.length; i++) {
|
|
7602
8488
|
const container = blockGroup.get(i);
|
|
7603
|
-
if (container instanceof
|
|
8489
|
+
if (container instanceof Y6.XmlElement && container.getAttribute("id") === block.id) {
|
|
7604
8490
|
blockGroup.delete(i, 1);
|
|
7605
8491
|
const newContainer = createBlockContainer(block);
|
|
7606
8492
|
blockGroup.insert(i, [newContainer]);
|
|
@@ -7634,12 +8520,12 @@ function applyMergeResultToFragment(fragment, mergeResult) {
|
|
|
7634
8520
|
}
|
|
7635
8521
|
}
|
|
7636
8522
|
function createBlockContainer(block) {
|
|
7637
|
-
const blockContainer = new
|
|
8523
|
+
const blockContainer = new Y6.XmlElement("blockContainer");
|
|
7638
8524
|
const { backgroundColor: rawBackgroundColor, textColor: rawTextColor, ...contentProps } = block.props;
|
|
7639
8525
|
blockContainer.setAttribute("id", block.id);
|
|
7640
8526
|
blockContainer.setAttribute("textColor", rawTextColor || "default");
|
|
7641
8527
|
blockContainer.setAttribute("backgroundColor", rawBackgroundColor || "default");
|
|
7642
|
-
const blockContent = new
|
|
8528
|
+
const blockContent = new Y6.XmlElement(block.type);
|
|
7643
8529
|
for (const [key, value] of Object.entries(contentProps)) {
|
|
7644
8530
|
if (value !== "") {
|
|
7645
8531
|
blockContent.setAttribute(key, value);
|
|
@@ -7654,13 +8540,13 @@ function appendBlockToGroup(blockGroup, block) {
|
|
|
7654
8540
|
}
|
|
7655
8541
|
function getOrCreateDocumentBlockGroup(fragment) {
|
|
7656
8542
|
if (fragment.length === 0) {
|
|
7657
|
-
const blockGroup = new
|
|
8543
|
+
const blockGroup = new Y6.XmlElement("blockGroup");
|
|
7658
8544
|
fragment.insert(0, [blockGroup]);
|
|
7659
8545
|
return blockGroup;
|
|
7660
8546
|
}
|
|
7661
8547
|
if (fragment.length === 1) {
|
|
7662
8548
|
const rootNode = fragment.get(0);
|
|
7663
|
-
if (rootNode instanceof
|
|
8549
|
+
if (rootNode instanceof Y6.XmlElement && rootNode.nodeName === "blockGroup") {
|
|
7664
8550
|
return rootNode;
|
|
7665
8551
|
}
|
|
7666
8552
|
}
|
|
@@ -7670,7 +8556,7 @@ function getExistingBlockGroup(fragment) {
|
|
|
7670
8556
|
if (fragment.length === 0) return null;
|
|
7671
8557
|
if (fragment.length === 1) {
|
|
7672
8558
|
const rootNode = fragment.get(0);
|
|
7673
|
-
if (rootNode instanceof
|
|
8559
|
+
if (rootNode instanceof Y6.XmlElement && rootNode.nodeName === "blockGroup") {
|
|
7674
8560
|
return rootNode;
|
|
7675
8561
|
}
|
|
7676
8562
|
}
|
|
@@ -7773,7 +8659,7 @@ async function setupFlowFromBaseUcan(options) {
|
|
|
7773
8659
|
};
|
|
7774
8660
|
}
|
|
7775
8661
|
async function connectToRoom(roomId, matrixClient) {
|
|
7776
|
-
const yDoc = new
|
|
8662
|
+
const yDoc = new Y7.Doc();
|
|
7777
8663
|
const client = matrixClient;
|
|
7778
8664
|
client.canSupportVoip = false;
|
|
7779
8665
|
client.clientOpts = { lazyLoadMembers: true };
|
|
@@ -7828,7 +8714,7 @@ function setRootMetadata(yDoc, root, plan, creatorDid, docId) {
|
|
|
7828
8714
|
}
|
|
7829
8715
|
|
|
7830
8716
|
// src/core/lib/flowAgent/store.ts
|
|
7831
|
-
import * as
|
|
8717
|
+
import * as Y8 from "yjs";
|
|
7832
8718
|
|
|
7833
8719
|
// src/core/lib/flowAgent/utils.ts
|
|
7834
8720
|
function stableStringify(value) {
|
|
@@ -8009,7 +8895,7 @@ function appendAgentLedgerEvent(yDoc, event) {
|
|
|
8009
8895
|
const auditMap = yDoc.getMap("auditTrail");
|
|
8010
8896
|
let arr = auditMap.get(FLOW_AGENT_AUDIT_SCOPE);
|
|
8011
8897
|
if (!arr) {
|
|
8012
|
-
arr = new
|
|
8898
|
+
arr = new Y8.Array();
|
|
8013
8899
|
auditMap.set(FLOW_AGENT_AUDIT_SCOPE, arr);
|
|
8014
8900
|
}
|
|
8015
8901
|
const fullEvent = {
|
|
@@ -8273,12 +9159,88 @@ function snapshotNode(block, runtime, now, pendingInvocationCount = 0) {
|
|
|
8273
9159
|
return snapshot;
|
|
8274
9160
|
}
|
|
8275
9161
|
|
|
9162
|
+
// src/core/lib/flowAgent/actionExecutionPolicy.ts
|
|
9163
|
+
var RUNTIME_INPUT_REQUIRED_ACTIONS = /* @__PURE__ */ new Set(["qi/form.submit", "qi/human.form.submit", "qi/human.checkbox.set", "qi/protocol.select"]);
|
|
9164
|
+
function isRecord(value) {
|
|
9165
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
9166
|
+
}
|
|
9167
|
+
function parseStringList(value) {
|
|
9168
|
+
const parsed = parseJsonProp(value, []);
|
|
9169
|
+
if (!Array.isArray(parsed)) return [];
|
|
9170
|
+
return parsed.filter((item) => typeof item === "string" && item.length > 0);
|
|
9171
|
+
}
|
|
9172
|
+
function normalizeMode(value) {
|
|
9173
|
+
if (value === "saved-input" || value === "saved_input" || value === "savedInput") return "saved-input";
|
|
9174
|
+
if (value === "runtime-input-required" || value === "runtime_input_required" || value === "runtimeInputRequired") return "runtime-input-required";
|
|
9175
|
+
if (value === "human-only" || value === "human_only" || value === "humanOnly") return "human-only";
|
|
9176
|
+
return void 0;
|
|
9177
|
+
}
|
|
9178
|
+
function parseExecutionConfig(value) {
|
|
9179
|
+
if (value == null || value === "") return {};
|
|
9180
|
+
if (typeof value === "string") {
|
|
9181
|
+
const directMode = normalizeMode(value);
|
|
9182
|
+
if (directMode) return { mode: directMode };
|
|
9183
|
+
}
|
|
9184
|
+
const parsed = parseJsonProp(value, {});
|
|
9185
|
+
if (!isRecord(parsed)) return {};
|
|
9186
|
+
return {
|
|
9187
|
+
mode: normalizeMode(parsed.mode),
|
|
9188
|
+
requiredRuntimeInputs: parseStringList(parsed.requiredRuntimeInputs)
|
|
9189
|
+
};
|
|
9190
|
+
}
|
|
9191
|
+
function inferDefaultMode(actionType, requiredRuntimeInputs) {
|
|
9192
|
+
if (requiredRuntimeInputs.length > 0) return "runtime-input-required";
|
|
9193
|
+
if (actionType && RUNTIME_INPUT_REQUIRED_ACTIONS.has(actionType)) return "runtime-input-required";
|
|
9194
|
+
return "saved-input";
|
|
9195
|
+
}
|
|
9196
|
+
function getFlowAgentActionExecutionPolicy(block) {
|
|
9197
|
+
const props = getBlockProps(block);
|
|
9198
|
+
const actionType = getBlockActionType(block);
|
|
9199
|
+
const config = parseExecutionConfig(props.flowAgentExecution || props.flowAgentExecutionMode || props.agentExecutionMode);
|
|
9200
|
+
const requiredRuntimeInputs = [
|
|
9201
|
+
...config.requiredRuntimeInputs || [],
|
|
9202
|
+
...parseStringList(props.requiredRuntimeInputs || props.runtimeRequiredInputs || props.flowAgentRequiredRuntimeInputs)
|
|
9203
|
+
];
|
|
9204
|
+
return {
|
|
9205
|
+
mode: config.mode || inferDefaultMode(actionType, requiredRuntimeInputs),
|
|
9206
|
+
requiredRuntimeInputs: Array.from(new Set(requiredRuntimeInputs))
|
|
9207
|
+
};
|
|
9208
|
+
}
|
|
9209
|
+
function getCommandRuntimeInputs(payload) {
|
|
9210
|
+
return isRecord(payload.runtimeInputs) ? payload.runtimeInputs : void 0;
|
|
9211
|
+
}
|
|
9212
|
+
function validateFlowAgentExecuteActionPayload(block, payload) {
|
|
9213
|
+
const policy = getFlowAgentActionExecutionPolicy(block);
|
|
9214
|
+
if (policy.mode === "human-only") {
|
|
9215
|
+
return {
|
|
9216
|
+
valid: false,
|
|
9217
|
+
mode: policy.mode,
|
|
9218
|
+
missingRuntimeInputs: [],
|
|
9219
|
+
reason: "Action requires human execution and cannot be run by the Flow Agent"
|
|
9220
|
+
};
|
|
9221
|
+
}
|
|
9222
|
+
if (policy.mode !== "runtime-input-required") {
|
|
9223
|
+
return { valid: true, mode: policy.mode, missingRuntimeInputs: [] };
|
|
9224
|
+
}
|
|
9225
|
+
const runtimeInputs = getCommandRuntimeInputs(payload);
|
|
9226
|
+
const missingRuntimeInputs = policy.requiredRuntimeInputs.length > 0 ? policy.requiredRuntimeInputs.filter((key) => runtimeInputs?.[key] == null || runtimeInputs[key] === "") : runtimeInputs ? [] : ["runtimeInputs"];
|
|
9227
|
+
if (missingRuntimeInputs.length > 0) {
|
|
9228
|
+
return {
|
|
9229
|
+
valid: false,
|
|
9230
|
+
mode: policy.mode,
|
|
9231
|
+
missingRuntimeInputs,
|
|
9232
|
+
reason: policy.requiredRuntimeInputs.length > 0 ? `Missing required runtimeInputs: ${missingRuntimeInputs.join(", ")}` : "Action requires runtimeInputs before the Flow Agent can execute it"
|
|
9233
|
+
};
|
|
9234
|
+
}
|
|
9235
|
+
return { valid: true, mode: policy.mode, missingRuntimeInputs: [] };
|
|
9236
|
+
}
|
|
9237
|
+
|
|
8276
9238
|
// src/core/lib/flowAgent/orchestrator.ts
|
|
8277
9239
|
var BLOCKER_DIAGNOSIS_VERSION = 2;
|
|
8278
9240
|
function getBlocks(context) {
|
|
8279
9241
|
return context.blocks || context.editor?.document || [];
|
|
8280
9242
|
}
|
|
8281
|
-
function
|
|
9243
|
+
function getRuntime3(yDoc, nodeId) {
|
|
8282
9244
|
const runtime = yDoc.getMap("runtime");
|
|
8283
9245
|
const value = runtime.get(nodeId);
|
|
8284
9246
|
return value && typeof value === "object" ? value : {};
|
|
@@ -8373,6 +9335,11 @@ function queueIfAuthorized(context, options, type, nodeId, reason, payload) {
|
|
|
8373
9335
|
}
|
|
8374
9336
|
return queueAgentCommand(context.yDoc, command).created ? command : null;
|
|
8375
9337
|
}
|
|
9338
|
+
function statusForResult(result) {
|
|
9339
|
+
if (result.status) return result.status;
|
|
9340
|
+
if (!result.success) return "failed";
|
|
9341
|
+
return result.confirmed === false ? "awaiting_readback" : "confirmed";
|
|
9342
|
+
}
|
|
8376
9343
|
function planForSnapshot(context, options, block, snapshot) {
|
|
8377
9344
|
const queued = [];
|
|
8378
9345
|
const actionType = getBlockActionType(block);
|
|
@@ -8432,8 +9399,25 @@ function planForSnapshot(context, options, block, snapshot) {
|
|
|
8432
9399
|
return queued;
|
|
8433
9400
|
}
|
|
8434
9401
|
if (actionType && canQueueCommand("execute_action", snapshot.nodeId, context, options)) {
|
|
9402
|
+
const pendingInvocation = readPendingInvocations(context.yDoc, snapshot.nodeId)[0];
|
|
9403
|
+
const payload = {
|
|
9404
|
+
actionType,
|
|
9405
|
+
...pendingInvocation ? { pendingInvocationId: pendingInvocation.id } : {}
|
|
9406
|
+
};
|
|
9407
|
+
const actionValidation = validateFlowAgentExecuteActionPayload(block, payload);
|
|
9408
|
+
if (!actionValidation.valid) {
|
|
9409
|
+
const commandType = actionValidation.mode === "human-only" ? "notify_actor" : "diagnose_blocker";
|
|
9410
|
+
const command2 = queueIfAuthorized(context, options, commandType, snapshot.nodeId, actionValidation.reason || "Action node cannot be executed by Flow Agent yet", {
|
|
9411
|
+
cause: actionValidation.mode === "runtime-input-required" ? "missing_input" : "unknown",
|
|
9412
|
+
requiredActionType: actionType,
|
|
9413
|
+
requiredRuntimeInputs: actionValidation.missingRuntimeInputs,
|
|
9414
|
+
severity: actionValidation.mode === "human-only" ? "attention" : void 0
|
|
9415
|
+
});
|
|
9416
|
+
if (command2) queued.push(command2);
|
|
9417
|
+
return queued;
|
|
9418
|
+
}
|
|
8435
9419
|
const command = queueIfAuthorized(context, options, "execute_action", snapshot.nodeId, "Action node is pending and executable", {
|
|
8436
|
-
|
|
9420
|
+
...payload
|
|
8437
9421
|
});
|
|
8438
9422
|
if (command) queued.push(command);
|
|
8439
9423
|
return queued;
|
|
@@ -8455,7 +9439,7 @@ function planRalphLoopCommands(context, options = {}) {
|
|
|
8455
9439
|
const nodeId = getBlockId(block);
|
|
8456
9440
|
if (!nodeId) continue;
|
|
8457
9441
|
const pendingInvocationCount = readPendingInvocations(context.yDoc, nodeId).length;
|
|
8458
|
-
const snapshot = snapshotNode(block,
|
|
9442
|
+
const snapshot = snapshotNode(block, getRuntime3(context.yDoc, nodeId), now, pendingInvocationCount);
|
|
8459
9443
|
snapshots.push(snapshot);
|
|
8460
9444
|
queuedCommands.push(...planForSnapshot(context, options, block, snapshot));
|
|
8461
9445
|
}
|
|
@@ -8538,7 +9522,7 @@ async function executeQueuedAgentCommands(context, options = {}) {
|
|
|
8538
9522
|
continue;
|
|
8539
9523
|
}
|
|
8540
9524
|
updateAgentCommand(context.yDoc, command.id, {
|
|
8541
|
-
status: result
|
|
9525
|
+
status: statusForResult(result),
|
|
8542
9526
|
error: result.error,
|
|
8543
9527
|
updatedAt: context.now?.() || Date.now()
|
|
8544
9528
|
});
|
|
@@ -8587,7 +9571,7 @@ function safeAppendAgentLedgerEvent2(yDoc, event) {
|
|
|
8587
9571
|
throw error;
|
|
8588
9572
|
}
|
|
8589
9573
|
}
|
|
8590
|
-
function
|
|
9574
|
+
function createYDocRuntimeManager2(yDoc) {
|
|
8591
9575
|
const runtime = yDoc.getMap("runtime");
|
|
8592
9576
|
return {
|
|
8593
9577
|
get: (nodeId) => {
|
|
@@ -8618,19 +9602,16 @@ function clearRuntimeBlocker(yDoc, nodeId, updates) {
|
|
|
8618
9602
|
});
|
|
8619
9603
|
}
|
|
8620
9604
|
function findContextBlock(context, nodeId) {
|
|
8621
|
-
const block = (context.blocks || []).find((entry) => getBlockId(entry) === nodeId);
|
|
9605
|
+
const block = (context.blocks || context.editor?.document || []).find((entry) => getBlockId(entry) === nodeId);
|
|
8622
9606
|
return block && typeof block === "object" ? block : null;
|
|
8623
9607
|
}
|
|
8624
|
-
function parseInputs2(value) {
|
|
8625
|
-
return parseJsonProp(value, {});
|
|
8626
|
-
}
|
|
8627
9608
|
function getXmlAttribute(element, key) {
|
|
8628
9609
|
return element.getAttribute(key);
|
|
8629
9610
|
}
|
|
8630
9611
|
function setXmlAttribute(element, key, value) {
|
|
8631
9612
|
element.setAttribute(key, value);
|
|
8632
9613
|
}
|
|
8633
|
-
function
|
|
9614
|
+
function isRecord2(value) {
|
|
8634
9615
|
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
8635
9616
|
}
|
|
8636
9617
|
function isYXmlContainerLike(value) {
|
|
@@ -8643,13 +9624,13 @@ function getElementBlockId(element) {
|
|
|
8643
9624
|
const directId = getXmlAttribute(element, "id");
|
|
8644
9625
|
if (typeof directId === "string" && directId.length > 0) return directId;
|
|
8645
9626
|
const attrs = getXmlAttribute(element, "attrs");
|
|
8646
|
-
const attrsId =
|
|
9627
|
+
const attrsId = isRecord2(attrs) ? attrs.id : void 0;
|
|
8647
9628
|
return typeof attrsId === "string" && attrsId.length > 0 ? attrsId : void 0;
|
|
8648
9629
|
}
|
|
8649
9630
|
function updateXmlElementProps(element, blockId, propsPatch) {
|
|
8650
9631
|
const attrs = getXmlAttribute(element, "attrs");
|
|
8651
|
-
if (
|
|
8652
|
-
const existingProps =
|
|
9632
|
+
if (isRecord2(attrs)) {
|
|
9633
|
+
const existingProps = isRecord2(attrs.props) ? attrs.props : {};
|
|
8653
9634
|
setXmlAttribute(element, "attrs", {
|
|
8654
9635
|
...attrs,
|
|
8655
9636
|
id: typeof attrs.id === "string" ? attrs.id : blockId,
|
|
@@ -8706,7 +9687,7 @@ function assignActorInYDoc(yDoc, command, context) {
|
|
|
8706
9687
|
if (!updatedDocument) {
|
|
8707
9688
|
throw new Error(`Block ${command.nodeId} was not found for assignment`);
|
|
8708
9689
|
}
|
|
8709
|
-
const runtime =
|
|
9690
|
+
const runtime = createYDocRuntimeManager2(yDoc);
|
|
8710
9691
|
runtime.update(command.nodeId, {
|
|
8711
9692
|
assignedActorDid: targetActorDid,
|
|
8712
9693
|
assignedByDid: context.actor.did,
|
|
@@ -8751,76 +9732,69 @@ async function executeActionCommand(command, context, options) {
|
|
|
8751
9732
|
if (!actionType) {
|
|
8752
9733
|
return { commandId: command.id, success: false, error: "execute_action command is missing payload.actionType" };
|
|
8753
9734
|
}
|
|
8754
|
-
const action = getAction(actionType);
|
|
8755
|
-
if (!action) {
|
|
8756
|
-
return { commandId: command.id, success: false, error: `No registered action found for ${actionType}` };
|
|
8757
|
-
}
|
|
8758
9735
|
const block = findContextBlock(context, command.nodeId);
|
|
8759
9736
|
if (!block) {
|
|
8760
9737
|
return { commandId: command.id, success: false, error: `Block ${command.nodeId} was not found in runtime context` };
|
|
8761
9738
|
}
|
|
8762
9739
|
const props = getBlockProps(block);
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
9740
|
+
if (typeof props.actionType === "string" && props.actionType !== actionType) {
|
|
9741
|
+
return {
|
|
9742
|
+
commandId: command.id,
|
|
9743
|
+
success: false,
|
|
9744
|
+
error: `execute_action payload.actionType ${actionType} does not match block actionType ${props.actionType}`
|
|
9745
|
+
};
|
|
9746
|
+
}
|
|
9747
|
+
const runtimeInputs = command.payload.runtimeInputs;
|
|
9748
|
+
if (runtimeInputs != null && !isRecord2(runtimeInputs)) {
|
|
9749
|
+
return { commandId: command.id, success: false, error: "execute_action payload.runtimeInputs must be an object when provided" };
|
|
9750
|
+
}
|
|
9751
|
+
const inputValidation = validateFlowAgentExecuteActionPayload(block, command.payload);
|
|
9752
|
+
if (!inputValidation.valid) {
|
|
9753
|
+
return {
|
|
9754
|
+
commandId: command.id,
|
|
9755
|
+
success: false,
|
|
9756
|
+
confirmed: false,
|
|
9757
|
+
status: inputValidation.mode === "human-only" ? "skipped" : "failed",
|
|
9758
|
+
error: inputValidation.reason
|
|
9759
|
+
};
|
|
9760
|
+
}
|
|
9761
|
+
const pendingInvocationId = typeof command.payload.pendingInvocationId === "string" ? command.payload.pendingInvocationId : void 0;
|
|
9762
|
+
const outcome = await executeActionBlock({
|
|
9763
|
+
editorOrYDoc: context.editor || context.yDoc,
|
|
9764
|
+
block,
|
|
9765
|
+
blockId: command.nodeId,
|
|
9766
|
+
document: context.blocks || context.editor?.document || [],
|
|
8768
9767
|
actorDid: context.actor.did,
|
|
8769
9768
|
actorType: options.actorType,
|
|
8770
9769
|
entityRoomId: options.entityRoomId,
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
actorDid: context.actor.did,
|
|
8784
|
-
flowId: context.flowId,
|
|
8785
|
-
flowUri: context.flowUri,
|
|
8786
|
-
nodeId: command.nodeId,
|
|
8787
|
-
flowNode,
|
|
8788
|
-
runtime,
|
|
8789
|
-
services: options.actionServices || {}
|
|
8790
|
-
});
|
|
8791
|
-
return { payload: result.output };
|
|
8792
|
-
},
|
|
8793
|
-
pin: options.pin
|
|
9770
|
+
ucanService: options.ucanService,
|
|
9771
|
+
invocationStore: options.invocationStore,
|
|
9772
|
+
services: options.actionServices || {},
|
|
9773
|
+
handlers: options.actionHandlers,
|
|
9774
|
+
runtimeInputs: getCommandRuntimeInputs(command.payload),
|
|
9775
|
+
pendingInvocationId,
|
|
9776
|
+
pin: options.pin,
|
|
9777
|
+
flowUri: context.flowUri,
|
|
9778
|
+
flowId: context.flowId,
|
|
9779
|
+
flowOwnerDid: options.flowOwnerDid || "",
|
|
9780
|
+
schemaVersion: options.schemaVersion || DEFAULT_SCHEMA_VERSION,
|
|
9781
|
+
now: options.now || context.now
|
|
8794
9782
|
});
|
|
8795
|
-
if (outcome.success && outcome.result) {
|
|
8796
|
-
runtime.update(command.nodeId, {
|
|
8797
|
-
state: "completed",
|
|
8798
|
-
output: outcome.result.payload || {},
|
|
8799
|
-
executedByDid: context.actor.did,
|
|
8800
|
-
executedAt: options.now?.() || context.now?.() || Date.now(),
|
|
8801
|
-
lastInvocationCid: outcome.invocationCid || outcome.capabilityId,
|
|
8802
|
-
lastCommandId: command.id
|
|
8803
|
-
});
|
|
8804
|
-
} else if (!outcome.success) {
|
|
8805
|
-
runtime.update(command.nodeId, {
|
|
8806
|
-
state: "failed",
|
|
8807
|
-
error: {
|
|
8808
|
-
message: outcome.error || "Unknown execution error",
|
|
8809
|
-
at: options.now?.() || context.now?.() || Date.now(),
|
|
8810
|
-
commandId: command.id
|
|
8811
|
-
},
|
|
8812
|
-
lastCommandId: command.id
|
|
8813
|
-
});
|
|
8814
|
-
}
|
|
8815
9783
|
return {
|
|
8816
9784
|
commandId: command.id,
|
|
8817
9785
|
success: outcome.success,
|
|
8818
|
-
confirmed: outcome.success,
|
|
9786
|
+
confirmed: outcome.success && outcome.completionState === "completed",
|
|
8819
9787
|
output: {
|
|
8820
|
-
...outcome.
|
|
8821
|
-
...outcome.invocationCid ? { invocationCid: outcome.invocationCid } : {}
|
|
9788
|
+
...outcome.output && typeof outcome.output === "object" ? outcome.output : {},
|
|
9789
|
+
...outcome.invocationCid ? { invocationCid: outcome.invocationCid } : {},
|
|
9790
|
+
...outcome.capabilityId ? { capabilityId: outcome.capabilityId } : {},
|
|
9791
|
+
...outcome.runId ? { runId: outcome.runId } : {},
|
|
9792
|
+
...outcome.events.length > 0 ? { events: outcome.events } : {},
|
|
9793
|
+
...pendingInvocationId ? { pendingInvocationId, pendingInvocationRemoved: outcome.pendingInvocationRemoved } : {},
|
|
9794
|
+
completionState: outcome.completionState
|
|
8822
9795
|
},
|
|
8823
|
-
error: outcome.error
|
|
9796
|
+
error: outcome.error,
|
|
9797
|
+
completionState: outcome.completionState
|
|
8824
9798
|
};
|
|
8825
9799
|
}
|
|
8826
9800
|
function getRecoverableBlockerReason(runtime) {
|
|
@@ -8915,6 +9889,11 @@ async function callConfiguredExecutor(command, context, options) {
|
|
|
8915
9889
|
return void 0;
|
|
8916
9890
|
}
|
|
8917
9891
|
}
|
|
9892
|
+
function statusForResult2(result) {
|
|
9893
|
+
if (result.status) return result.status;
|
|
9894
|
+
if (!result.success) return "failed";
|
|
9895
|
+
return result.confirmed === false ? "awaiting_readback" : "confirmed";
|
|
9896
|
+
}
|
|
8918
9897
|
async function executeQueuedFlowAgentCoreCommands(context, options) {
|
|
8919
9898
|
const now = options.now?.() || context.now?.() || Date.now();
|
|
8920
9899
|
const { leases } = getFlowAgentMaps(context.yDoc);
|
|
@@ -8968,7 +9947,7 @@ async function executeQueuedFlowAgentCoreCommands(context, options) {
|
|
|
8968
9947
|
continue;
|
|
8969
9948
|
}
|
|
8970
9949
|
updateAgentCommand(context.yDoc, command.id, {
|
|
8971
|
-
status: normalized
|
|
9950
|
+
status: statusForResult2(normalized),
|
|
8972
9951
|
error: normalized.error,
|
|
8973
9952
|
updatedAt: options.now?.() || context.now?.() || Date.now()
|
|
8974
9953
|
});
|
|
@@ -9085,9 +10064,10 @@ export {
|
|
|
9085
10064
|
buildFlowNodeFromBlock,
|
|
9086
10065
|
createRuntimeStateManager,
|
|
9087
10066
|
clearRuntimeForTemplateClone,
|
|
10067
|
+
isRuntimeRef,
|
|
10068
|
+
resolveRuntimeRefs,
|
|
9088
10069
|
isAuthorized,
|
|
9089
10070
|
executeNode,
|
|
9090
|
-
isRuntimeRef,
|
|
9091
10071
|
RUN_RECORD_AUDIT_TYPE,
|
|
9092
10072
|
computePendingInvocationId,
|
|
9093
10073
|
snapshotInputRefs,
|
|
@@ -9102,6 +10082,9 @@ export {
|
|
|
9102
10082
|
replayFailedListenerRun,
|
|
9103
10083
|
reconcilePendingInvocations,
|
|
9104
10084
|
getActionForBlock,
|
|
10085
|
+
reconcileActionReadBack,
|
|
10086
|
+
buildActionRunInputs,
|
|
10087
|
+
executeActionBlock,
|
|
9105
10088
|
writeRunRecordAndReconcile,
|
|
9106
10089
|
compileBaseUcanFlow,
|
|
9107
10090
|
readCompiledFlowFromYDoc,
|
|
@@ -9143,4 +10126,4 @@ export {
|
|
|
9143
10126
|
executeQueuedFlowAgentCoreCommands,
|
|
9144
10127
|
FlowAgentService
|
|
9145
10128
|
};
|
|
9146
|
-
//# sourceMappingURL=chunk-
|
|
10129
|
+
//# sourceMappingURL=chunk-XGQRYGA3.mjs.map
|