@stndrds/schema 1.0.0-alpha.85 → 1.0.0-alpha.87
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-UGWL4KQR.js → chunk-B23XC4L2.js} +820 -237
- package/dist/{chunk-HKT7LEYM.mjs → chunk-IFJJT3JZ.mjs} +591 -8
- package/dist/index.d.mts +303 -6
- package/dist/index.d.ts +303 -6
- package/dist/index.js +27 -5
- package/dist/index.mjs +23 -1
- package/dist/{runtime-DSh9YK1-.d.ts → runtime-Cg0Rwnwx.d.ts} +766 -362
- package/dist/{runtime-Dz1KblvE.d.mts → runtime-Dz1JEYu7.d.mts} +766 -362
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +12 -2
- package/dist/runtime.mjs +11 -1
- package/package.json +2 -2
|
@@ -1390,6 +1390,9 @@ function isConditionNode(node) {
|
|
|
1390
1390
|
function isAssignNode(node) {
|
|
1391
1391
|
return node.type === "assign";
|
|
1392
1392
|
}
|
|
1393
|
+
function isAINode(node) {
|
|
1394
|
+
return node.type === "ai";
|
|
1395
|
+
}
|
|
1393
1396
|
function isEndNode(node) {
|
|
1394
1397
|
return node.type === "end";
|
|
1395
1398
|
}
|
|
@@ -1530,6 +1533,47 @@ var assignNodeType = {
|
|
|
1530
1533
|
};
|
|
1531
1534
|
nodeTypeRegistry.register(assignNodeType);
|
|
1532
1535
|
|
|
1536
|
+
// src/types/workflows/node-types/ai.node-type.ts
|
|
1537
|
+
var aiNodeType = {
|
|
1538
|
+
type: "ai",
|
|
1539
|
+
isLinear: true,
|
|
1540
|
+
structural: false,
|
|
1541
|
+
getOutputs(node) {
|
|
1542
|
+
return node.next ? [node.next] : [];
|
|
1543
|
+
},
|
|
1544
|
+
setNext(node, targetId) {
|
|
1545
|
+
return { ...node, next: targetId };
|
|
1546
|
+
},
|
|
1547
|
+
getSlotIds(node) {
|
|
1548
|
+
const slotIds = /* @__PURE__ */ new Set();
|
|
1549
|
+
const action = node.action;
|
|
1550
|
+
if (action.type === "document-generation") {
|
|
1551
|
+
for (const id of action.inputSlotIds) slotIds.add(id);
|
|
1552
|
+
for (const id of action.targetSlotIds) slotIds.add(id);
|
|
1553
|
+
} else if (action.type === "code-execution") {
|
|
1554
|
+
for (const id of action.inputSlotIds ?? []) slotIds.add(id);
|
|
1555
|
+
}
|
|
1556
|
+
return [...slotIds];
|
|
1557
|
+
},
|
|
1558
|
+
validate(node) {
|
|
1559
|
+
const errors = [];
|
|
1560
|
+
if (!node.label) errors.push("AINode must have a label");
|
|
1561
|
+
if (!node.action) errors.push("AINode must have an action");
|
|
1562
|
+
if (!node.next) errors.push("AINode must have a 'next' target");
|
|
1563
|
+
if (node.action?.type === "document-generation") {
|
|
1564
|
+
if (!node.action.templateId) errors.push("Document generation must have a templateId");
|
|
1565
|
+
if (!node.action.inputSlotIds?.length)
|
|
1566
|
+
errors.push("Document generation must have input slots");
|
|
1567
|
+
if (!node.action.targetSlotIds?.length)
|
|
1568
|
+
errors.push("Document generation must have target slots");
|
|
1569
|
+
} else if (node.action?.type === "code-execution") {
|
|
1570
|
+
if (!node.action.code) errors.push("Code execution must have code");
|
|
1571
|
+
}
|
|
1572
|
+
return errors;
|
|
1573
|
+
}
|
|
1574
|
+
};
|
|
1575
|
+
nodeTypeRegistry.register(aiNodeType);
|
|
1576
|
+
|
|
1533
1577
|
// src/types/workflows/node-types/end.node-type.ts
|
|
1534
1578
|
var endNodeType = {
|
|
1535
1579
|
type: "end",
|
|
@@ -1742,14 +1786,15 @@ function isInvitationOrGrantEvent(event) {
|
|
|
1742
1786
|
var ZONE_ORDER = ["collect", "actions"];
|
|
1743
1787
|
var ZONE_CONFIG = {
|
|
1744
1788
|
collect: { allowedNodeTypes: ["form", "condition"] },
|
|
1745
|
-
actions: { allowedNodeTypes: ["condition", "assign"] }
|
|
1789
|
+
actions: { allowedNodeTypes: ["condition", "assign", "ai"] }
|
|
1746
1790
|
};
|
|
1747
1791
|
var TERMINAL_NODE_TYPES = /* @__PURE__ */ new Set(["start", "end"]);
|
|
1748
1792
|
var NODE_TYPE_ZONE = {
|
|
1749
1793
|
form: "collect",
|
|
1750
1794
|
condition: "collect",
|
|
1751
1795
|
// default — overridden by assignNodeZones logic
|
|
1752
|
-
assign: "actions"
|
|
1796
|
+
assign: "actions",
|
|
1797
|
+
ai: "actions"
|
|
1753
1798
|
};
|
|
1754
1799
|
function assignNodeZones(orderedNodes) {
|
|
1755
1800
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -1834,9 +1879,14 @@ var StartNodeSchema = z.object({
|
|
|
1834
1879
|
id: z.string().min(1),
|
|
1835
1880
|
next: z.string().nullish()
|
|
1836
1881
|
});
|
|
1882
|
+
var RelationFieldConfigSchema = z.object({
|
|
1883
|
+
visibleProperties: z.array(z.string()).optional(),
|
|
1884
|
+
allowCreate: z.boolean().optional()
|
|
1885
|
+
}).optional();
|
|
1837
1886
|
var FormFieldRefSchema = z.object({
|
|
1838
1887
|
slotId: z.string().min(1, "slotId is required"),
|
|
1839
|
-
attribute: z.string().min(1, "attribute is required")
|
|
1888
|
+
attribute: z.string().min(1, "attribute is required"),
|
|
1889
|
+
relationConfig: RelationFieldConfigSchema
|
|
1840
1890
|
});
|
|
1841
1891
|
var FlowRowFieldSchema = z.object({
|
|
1842
1892
|
id: z.string().min(1),
|
|
@@ -1844,7 +1894,8 @@ var FlowRowFieldSchema = z.object({
|
|
|
1844
1894
|
attribute: z.string().min(1),
|
|
1845
1895
|
label: z.string().max(200).optional(),
|
|
1846
1896
|
tooltip: z.string().max(1e3).optional(),
|
|
1847
|
-
required: z.boolean().optional()
|
|
1897
|
+
required: z.boolean().optional(),
|
|
1898
|
+
relationConfig: RelationFieldConfigSchema
|
|
1848
1899
|
});
|
|
1849
1900
|
var FlowFieldsRowSchema = z.object({
|
|
1850
1901
|
id: z.string().min(1),
|
|
@@ -1925,6 +1976,35 @@ var AssignNodeSchema = z.object({
|
|
|
1925
1976
|
assignments: z.array(AssignmentMappingSchema).min(1),
|
|
1926
1977
|
next: z.string().nullish()
|
|
1927
1978
|
});
|
|
1979
|
+
var DocumentGenerationActionSchema = z.object({
|
|
1980
|
+
type: z.literal("document-generation"),
|
|
1981
|
+
templateId: z.string().min(1, "Template ID is required"),
|
|
1982
|
+
inputSlotIds: z.array(z.string().min(1)).min(1, "At least one input slot is required"),
|
|
1983
|
+
targetSlotIds: z.array(z.string().min(1)).min(1, "At least one target slot is required"),
|
|
1984
|
+
outputFormat: z.enum(["pdf", "docx"]),
|
|
1985
|
+
aiInstructions: z.string().nullish()
|
|
1986
|
+
});
|
|
1987
|
+
var CodeExecutionActionSchema = z.object({
|
|
1988
|
+
type: z.literal("code-execution"),
|
|
1989
|
+
code: z.string().min(1, "Code is required"),
|
|
1990
|
+
language: z.enum(["javascript", "typescript", "python"]),
|
|
1991
|
+
inputSlotIds: z.array(z.string().min(1)).optional(),
|
|
1992
|
+
outputVariable: z.string().optional(),
|
|
1993
|
+
packages: z.array(z.string()).optional()
|
|
1994
|
+
});
|
|
1995
|
+
var AIActionConfigSchema = z.discriminatedUnion("type", [
|
|
1996
|
+
DocumentGenerationActionSchema,
|
|
1997
|
+
CodeExecutionActionSchema
|
|
1998
|
+
]);
|
|
1999
|
+
var AINodeSchema = z.object({
|
|
2000
|
+
type: z.literal("ai"),
|
|
2001
|
+
id: z.string().min(1),
|
|
2002
|
+
label: z.string().min(1),
|
|
2003
|
+
description: z.string().nullish(),
|
|
2004
|
+
action: AIActionConfigSchema,
|
|
2005
|
+
timeoutMs: z.number().positive().optional(),
|
|
2006
|
+
next: z.string().nullish()
|
|
2007
|
+
});
|
|
1928
2008
|
var EndNodeSchema = z.object({
|
|
1929
2009
|
type: z.literal("end"),
|
|
1930
2010
|
id: z.string().min(1),
|
|
@@ -1936,6 +2016,7 @@ var WorkflowNodeSchema = z.discriminatedUnion("type", [
|
|
|
1936
2016
|
FormNodeSchema,
|
|
1937
2017
|
ConditionNodeSchema,
|
|
1938
2018
|
AssignNodeSchema,
|
|
2019
|
+
AINodeSchema,
|
|
1939
2020
|
EndNodeSchema
|
|
1940
2021
|
]);
|
|
1941
2022
|
var SlotModeSchema = z.enum(["create", "select", "optional"]);
|
|
@@ -2899,6 +2980,214 @@ function resolveSource(source, slotValues) {
|
|
|
2899
2980
|
}
|
|
2900
2981
|
}
|
|
2901
2982
|
|
|
2983
|
+
// src/runtime/executors/ai.executor.ts
|
|
2984
|
+
var AIExecutor = class {
|
|
2985
|
+
constructor(actionRegistry) {
|
|
2986
|
+
this.actionRegistry = actionRegistry;
|
|
2987
|
+
this.nodeType = "ai";
|
|
2988
|
+
}
|
|
2989
|
+
async execute(node, ctx) {
|
|
2990
|
+
if (!node.next) {
|
|
2991
|
+
return error("MISSING_NEXT", "AINode must have a 'next' target");
|
|
2992
|
+
}
|
|
2993
|
+
const handler = this.actionRegistry.get(node.action.type);
|
|
2994
|
+
if (!handler) {
|
|
2995
|
+
return error(
|
|
2996
|
+
"UNKNOWN_AI_ACTION",
|
|
2997
|
+
`No handler registered for AI action type: ${node.action.type}`
|
|
2998
|
+
);
|
|
2999
|
+
}
|
|
3000
|
+
const result = await handler.execute(node.action, ctx);
|
|
3001
|
+
if (!result.success) {
|
|
3002
|
+
return error("AI_ACTION_FAILED", result.error ?? "AI action failed", true);
|
|
3003
|
+
}
|
|
3004
|
+
return success(node.next, result.contextUpdates);
|
|
3005
|
+
}
|
|
3006
|
+
validate(node) {
|
|
3007
|
+
const errors = [];
|
|
3008
|
+
if (!node.label) errors.push("AINode must have a label");
|
|
3009
|
+
if (!node.action) errors.push("AINode must have an action");
|
|
3010
|
+
if (!node.next) errors.push("AINode must have a 'next' target");
|
|
3011
|
+
return errors;
|
|
3012
|
+
}
|
|
3013
|
+
};
|
|
3014
|
+
|
|
3015
|
+
// src/runtime/executors/ai-actions/types.ts
|
|
3016
|
+
var AIActionRegistry = class {
|
|
3017
|
+
constructor() {
|
|
3018
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
3019
|
+
}
|
|
3020
|
+
register(handler) {
|
|
3021
|
+
this.handlers.set(handler.actionType, handler);
|
|
3022
|
+
}
|
|
3023
|
+
get(actionType) {
|
|
3024
|
+
return this.handlers.get(actionType);
|
|
3025
|
+
}
|
|
3026
|
+
has(actionType) {
|
|
3027
|
+
return this.handlers.has(actionType);
|
|
3028
|
+
}
|
|
3029
|
+
};
|
|
3030
|
+
|
|
3031
|
+
// src/runtime/executors/ai-actions/document-generation.handler.ts
|
|
3032
|
+
var DocumentGenerationHandler = class {
|
|
3033
|
+
constructor(deps = null) {
|
|
3034
|
+
this.deps = deps;
|
|
3035
|
+
this.actionType = "document-generation";
|
|
3036
|
+
}
|
|
3037
|
+
async execute(action, ctx) {
|
|
3038
|
+
if (!this.deps) {
|
|
3039
|
+
return {
|
|
3040
|
+
success: false,
|
|
3041
|
+
error: "Document generation not configured. Provide sandbox, fileService, and storage in SchemaModule."
|
|
3042
|
+
};
|
|
3043
|
+
}
|
|
3044
|
+
const { sandbox, fileService, storage } = this.deps;
|
|
3045
|
+
const file2 = await fileService.getFile(action.templateId);
|
|
3046
|
+
if (!file2) {
|
|
3047
|
+
return {
|
|
3048
|
+
success: false,
|
|
3049
|
+
error: `Template file not found: ${action.templateId}`
|
|
3050
|
+
};
|
|
3051
|
+
}
|
|
3052
|
+
if (!storage.download) {
|
|
3053
|
+
return {
|
|
3054
|
+
success: false,
|
|
3055
|
+
error: "StorageAdapter.download() not implemented. Required for document generation."
|
|
3056
|
+
};
|
|
3057
|
+
}
|
|
3058
|
+
let templateContent;
|
|
3059
|
+
try {
|
|
3060
|
+
const buffer = await storage.download(file2.storagePath);
|
|
3061
|
+
templateContent = new Uint8Array(buffer);
|
|
3062
|
+
} catch (err) {
|
|
3063
|
+
return {
|
|
3064
|
+
success: false,
|
|
3065
|
+
error: `Failed to download template "${file2.name}": ${err instanceof Error ? err.message : "unknown error"}`
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
const slotData = {};
|
|
3069
|
+
for (const slotId of action.inputSlotIds) {
|
|
3070
|
+
slotData[slotId] = ctx.executionContext.slots[slotId] ?? {};
|
|
3071
|
+
}
|
|
3072
|
+
const instructions = [
|
|
3073
|
+
"Generate a professional document based on the provided template and data.",
|
|
3074
|
+
action.aiInstructions ?? "",
|
|
3075
|
+
"",
|
|
3076
|
+
"## Data Context",
|
|
3077
|
+
"```json",
|
|
3078
|
+
JSON.stringify(slotData, null, 2),
|
|
3079
|
+
"```",
|
|
3080
|
+
"",
|
|
3081
|
+
"## Instructions",
|
|
3082
|
+
"1. Unpack the template: python3 /workspace/scripts/office/unpack.py /workspace/template.docx /workspace/unpacked/",
|
|
3083
|
+
"2. Analyze the XML structure in /workspace/unpacked/word/document.xml",
|
|
3084
|
+
"3. Read the data from /workspace/data.json",
|
|
3085
|
+
"4. Modify the XML content using the provided data \u2014 replace placeholders, fill tables, update fields",
|
|
3086
|
+
"5. Pack: python3 /workspace/scripts/office/pack.py /workspace/unpacked/ /workspace/output.docx",
|
|
3087
|
+
"6. Validate: python3 /workspace/scripts/office/validate.py /workspace/output.docx",
|
|
3088
|
+
action.outputFormat === "pdf" ? "7. Convert to PDF: python3 /workspace/scripts/office/convert.py /workspace/output.docx pdf /workspace/" : ""
|
|
3089
|
+
].filter(Boolean).join("\n");
|
|
3090
|
+
const outputPath = action.outputFormat === "pdf" ? "/workspace/output.pdf" : "/workspace/output.docx";
|
|
3091
|
+
try {
|
|
3092
|
+
const result = await sandbox.executeAgent({
|
|
3093
|
+
instructions,
|
|
3094
|
+
template: "stndrds-pdf",
|
|
3095
|
+
inputFiles: [
|
|
3096
|
+
{
|
|
3097
|
+
path: "/workspace/template.docx",
|
|
3098
|
+
content: templateContent
|
|
3099
|
+
},
|
|
3100
|
+
{
|
|
3101
|
+
path: "/workspace/data.json",
|
|
3102
|
+
content: JSON.stringify(slotData, null, 2)
|
|
3103
|
+
}
|
|
3104
|
+
],
|
|
3105
|
+
expectedOutputs: [outputPath],
|
|
3106
|
+
timeoutMs: 6e5,
|
|
3107
|
+
maxIterations: 20
|
|
3108
|
+
});
|
|
3109
|
+
if (!result.success || result.artifacts.length === 0) {
|
|
3110
|
+
return {
|
|
3111
|
+
success: false,
|
|
3112
|
+
error: result.summary ?? "Agent failed to generate document"
|
|
3113
|
+
};
|
|
3114
|
+
}
|
|
3115
|
+
const contextUpdates = {};
|
|
3116
|
+
for (const slotId of action.targetSlotIds) {
|
|
3117
|
+
contextUpdates[slotId] = {
|
|
3118
|
+
...ctx.executionContext.slots[slotId] ?? {},
|
|
3119
|
+
_generatedDocuments: result.artifacts.map((a) => ({
|
|
3120
|
+
path: a.path,
|
|
3121
|
+
mimeType: a.mimeType
|
|
3122
|
+
}))
|
|
3123
|
+
};
|
|
3124
|
+
}
|
|
3125
|
+
return { success: true, contextUpdates };
|
|
3126
|
+
} catch (err) {
|
|
3127
|
+
return {
|
|
3128
|
+
success: false,
|
|
3129
|
+
error: err instanceof Error ? err.message : "Document generation failed"
|
|
3130
|
+
};
|
|
3131
|
+
}
|
|
3132
|
+
}
|
|
3133
|
+
};
|
|
3134
|
+
|
|
3135
|
+
// src/runtime/executors/ai-actions/code-execution.handler.ts
|
|
3136
|
+
var CodeExecutionHandler = class {
|
|
3137
|
+
constructor(sandbox = null) {
|
|
3138
|
+
this.sandbox = sandbox;
|
|
3139
|
+
this.actionType = "code-execution";
|
|
3140
|
+
}
|
|
3141
|
+
async execute(action, ctx) {
|
|
3142
|
+
if (!this.sandbox) {
|
|
3143
|
+
return {
|
|
3144
|
+
success: false,
|
|
3145
|
+
error: "Code execution handler not configured. Inject a SandboxExecutor via constructor."
|
|
3146
|
+
};
|
|
3147
|
+
}
|
|
3148
|
+
const env = {};
|
|
3149
|
+
for (const slotId of action.inputSlotIds ?? []) {
|
|
3150
|
+
const slotData = ctx.executionContext.slots[slotId] ?? {};
|
|
3151
|
+
env[`SLOT_${slotId.toUpperCase()}`] = JSON.stringify(slotData);
|
|
3152
|
+
}
|
|
3153
|
+
try {
|
|
3154
|
+
const result = await this.sandbox.executeCode({
|
|
3155
|
+
code: action.code,
|
|
3156
|
+
language: action.language,
|
|
3157
|
+
env,
|
|
3158
|
+
packages: action.packages,
|
|
3159
|
+
timeoutMs: 3e4
|
|
3160
|
+
// 30s for code mode
|
|
3161
|
+
});
|
|
3162
|
+
if (result.exitCode !== 0) {
|
|
3163
|
+
return {
|
|
3164
|
+
success: false,
|
|
3165
|
+
error: `Code execution failed (exit ${result.exitCode}): ${result.stderr}`
|
|
3166
|
+
};
|
|
3167
|
+
}
|
|
3168
|
+
const contextUpdates = {};
|
|
3169
|
+
if (action.outputVariable) {
|
|
3170
|
+
contextUpdates[action.outputVariable] = result.stdout.trim();
|
|
3171
|
+
}
|
|
3172
|
+
return { success: true, contextUpdates };
|
|
3173
|
+
} catch (err) {
|
|
3174
|
+
return {
|
|
3175
|
+
success: false,
|
|
3176
|
+
error: err instanceof Error ? err.message : "Code execution failed"
|
|
3177
|
+
};
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
};
|
|
3181
|
+
|
|
3182
|
+
// src/runtime/executors/ai-actions/index.ts
|
|
3183
|
+
function createDefaultAIActionRegistry(deps) {
|
|
3184
|
+
const registry2 = new AIActionRegistry();
|
|
3185
|
+
const docGenDeps = deps?.sandbox && deps?.fileService && deps?.storage ? { sandbox: deps.sandbox, fileService: deps.fileService, storage: deps.storage } : null;
|
|
3186
|
+
registry2.register(new DocumentGenerationHandler(docGenDeps));
|
|
3187
|
+
registry2.register(new CodeExecutionHandler(deps?.sandbox ?? null));
|
|
3188
|
+
return registry2;
|
|
3189
|
+
}
|
|
3190
|
+
|
|
2902
3191
|
// src/runtime/executors/start.executor.ts
|
|
2903
3192
|
var StartExecutor = class {
|
|
2904
3193
|
constructor() {
|
|
@@ -7898,7 +8187,10 @@ var ListViewBuilder = class {
|
|
|
7898
8187
|
groupByAttribute: tab.groupByAttribute,
|
|
7899
8188
|
cardUserAttribute: tab.cardUserAttribute,
|
|
7900
8189
|
cardDateAttribute: tab.cardDateAttribute,
|
|
7901
|
-
createMode: tab.createMode
|
|
8190
|
+
createMode: tab.createMode,
|
|
8191
|
+
kanbanColumnOrder: tab.kanbanColumnOrder,
|
|
8192
|
+
kanbanColumnVisibility: tab.kanbanColumnVisibility,
|
|
8193
|
+
kanbanPinnedColumns: tab.kanbanPinnedColumns
|
|
7902
8194
|
}))
|
|
7903
8195
|
};
|
|
7904
8196
|
return {
|
|
@@ -7987,6 +8279,34 @@ var ListViewTabConfigBuilder = class _ListViewTabConfigBuilder {
|
|
|
7987
8279
|
this.tabData.cardDateAttribute = attributeName;
|
|
7988
8280
|
return this;
|
|
7989
8281
|
}
|
|
8282
|
+
/**
|
|
8283
|
+
* Set the order of kanban columns by option values (for kanban layout only)
|
|
8284
|
+
* @param order - Array of option values in desired order
|
|
8285
|
+
* @example .kanbanColumnOrder(["new", "in_progress", "done"])
|
|
8286
|
+
*/
|
|
8287
|
+
kanbanColumnOrder(order) {
|
|
8288
|
+
this.tabData.kanbanColumnOrder = order;
|
|
8289
|
+
return this;
|
|
8290
|
+
}
|
|
8291
|
+
/**
|
|
8292
|
+
* Set the visibility of kanban columns by option values (for kanban layout only)
|
|
8293
|
+
* @param visibility - Record mapping option values to visibility (true = visible, false = hidden)
|
|
8294
|
+
* @example .kanbanColumnVisibility({ "new": true, "archived": false })
|
|
8295
|
+
*/
|
|
8296
|
+
kanbanColumnVisibility(visibility) {
|
|
8297
|
+
this.tabData.kanbanColumnVisibility = visibility;
|
|
8298
|
+
return this;
|
|
8299
|
+
}
|
|
8300
|
+
/**
|
|
8301
|
+
* Set pinned kanban columns by option values (for kanban layout only)
|
|
8302
|
+
* Pinned columns remain fixed during horizontal scrolling
|
|
8303
|
+
* @param pinnedColumns - Array of option values to pin
|
|
8304
|
+
* @example .kanbanPinnedColumns(["new", "done"])
|
|
8305
|
+
*/
|
|
8306
|
+
kanbanPinnedColumns(pinnedColumns) {
|
|
8307
|
+
this.tabData.kanbanPinnedColumns = pinnedColumns;
|
|
8308
|
+
return this;
|
|
8309
|
+
}
|
|
7990
8310
|
/**
|
|
7991
8311
|
* Set creation behavior when clicking "+"
|
|
7992
8312
|
* @param mode - "redirect" (navigate to detail), "inline" (empty row), or "modal" (stacked modal)
|
|
@@ -8103,12 +8423,55 @@ var WorkflowFormRowBuilder = class {
|
|
|
8103
8423
|
this.rowData.fields.push(field);
|
|
8104
8424
|
return this;
|
|
8105
8425
|
}
|
|
8426
|
+
/**
|
|
8427
|
+
* Add a relation field to the current row.
|
|
8428
|
+
* Use this for relation attributes that need specific configuration
|
|
8429
|
+
* (e.g., which qualified properties to display).
|
|
8430
|
+
*
|
|
8431
|
+
* @param slotId - The slot containing the relation attribute
|
|
8432
|
+
* @param attribute - The relation attribute name
|
|
8433
|
+
* @param options - Optional label, required flag, and relation config
|
|
8434
|
+
*/
|
|
8435
|
+
relationField(slotId, attribute, options) {
|
|
8436
|
+
const relationConfig = options?.visibleProperties || options?.allowCreate !== void 0 ? {
|
|
8437
|
+
visibleProperties: options?.visibleProperties,
|
|
8438
|
+
allowCreate: options?.allowCreate
|
|
8439
|
+
} : void 0;
|
|
8440
|
+
const field = {
|
|
8441
|
+
id: `${this.rowData.id}-${slotId}-${attribute}`,
|
|
8442
|
+
slotId,
|
|
8443
|
+
attribute,
|
|
8444
|
+
label: options?.label,
|
|
8445
|
+
required: options?.required,
|
|
8446
|
+
relationConfig
|
|
8447
|
+
};
|
|
8448
|
+
this.rowData.fields.push(field);
|
|
8449
|
+
return this;
|
|
8450
|
+
}
|
|
8106
8451
|
/**
|
|
8107
8452
|
* Start a new row
|
|
8108
8453
|
*/
|
|
8109
8454
|
row(id) {
|
|
8110
8455
|
return this.formBuilder._finalizeRow(this.rowData).row(id);
|
|
8111
8456
|
}
|
|
8457
|
+
/**
|
|
8458
|
+
* Add a heading row (finalizes the current field row first)
|
|
8459
|
+
*/
|
|
8460
|
+
heading(content, level) {
|
|
8461
|
+
return this.formBuilder._finalizeRow(this.rowData).heading(content, level);
|
|
8462
|
+
}
|
|
8463
|
+
/**
|
|
8464
|
+
* Add a visual separator (finalizes the current field row first)
|
|
8465
|
+
*/
|
|
8466
|
+
separator() {
|
|
8467
|
+
return this.formBuilder._finalizeRow(this.rowData).separator();
|
|
8468
|
+
}
|
|
8469
|
+
/**
|
|
8470
|
+
* Add a static text row (finalizes the current field row first)
|
|
8471
|
+
*/
|
|
8472
|
+
text(content) {
|
|
8473
|
+
return this.formBuilder._finalizeRow(this.rowData).text(content);
|
|
8474
|
+
}
|
|
8112
8475
|
/**
|
|
8113
8476
|
* Set the next node and finish this form
|
|
8114
8477
|
*/
|
|
@@ -8139,13 +8502,56 @@ var WorkflowFormBuilder = class {
|
|
|
8139
8502
|
this.rowOrder++;
|
|
8140
8503
|
return new WorkflowFormRowBuilder(this, id, this.rowOrder);
|
|
8141
8504
|
}
|
|
8505
|
+
/**
|
|
8506
|
+
* Add a heading row to the form
|
|
8507
|
+
*/
|
|
8508
|
+
heading(content, level) {
|
|
8509
|
+
this.rowOrder++;
|
|
8510
|
+
const row = {
|
|
8511
|
+
id: `heading-${this.rowOrder}`,
|
|
8512
|
+
order: this.rowOrder,
|
|
8513
|
+
type: "heading",
|
|
8514
|
+
content,
|
|
8515
|
+
level
|
|
8516
|
+
};
|
|
8517
|
+
this.rows.push(row);
|
|
8518
|
+
return this;
|
|
8519
|
+
}
|
|
8520
|
+
/**
|
|
8521
|
+
* Add a visual separator row to the form
|
|
8522
|
+
*/
|
|
8523
|
+
separator() {
|
|
8524
|
+
this.rowOrder++;
|
|
8525
|
+
const row = {
|
|
8526
|
+
id: `separator-${this.rowOrder}`,
|
|
8527
|
+
order: this.rowOrder,
|
|
8528
|
+
type: "separator"
|
|
8529
|
+
};
|
|
8530
|
+
this.rows.push(row);
|
|
8531
|
+
return this;
|
|
8532
|
+
}
|
|
8533
|
+
/**
|
|
8534
|
+
* Add a static text row to the form
|
|
8535
|
+
*/
|
|
8536
|
+
text(content) {
|
|
8537
|
+
this.rowOrder++;
|
|
8538
|
+
const row = {
|
|
8539
|
+
id: `text-${this.rowOrder}`,
|
|
8540
|
+
order: this.rowOrder,
|
|
8541
|
+
type: "text",
|
|
8542
|
+
content
|
|
8543
|
+
};
|
|
8544
|
+
this.rows.push(row);
|
|
8545
|
+
return this;
|
|
8546
|
+
}
|
|
8142
8547
|
/**
|
|
8143
8548
|
* Set the next node and complete the form definition
|
|
8144
8549
|
*/
|
|
8145
8550
|
next(nodeId) {
|
|
8146
|
-
|
|
8551
|
+
const hasFieldRows = this.rows.some((r) => !r.type || r.type === "fields");
|
|
8552
|
+
if (!hasFieldRows) {
|
|
8147
8553
|
throw new Error(
|
|
8148
|
-
`[WorkflowBuilder] Form "${this.nodeId}" has no rows. Use .row() to add
|
|
8554
|
+
`[WorkflowBuilder] Form "${this.nodeId}" has no field rows. Use .row() to add fields.`
|
|
8149
8555
|
);
|
|
8150
8556
|
}
|
|
8151
8557
|
return this.workflowBuilder._addFormNode({
|
|
@@ -8196,6 +8602,22 @@ var WorkflowSimpleFormBuilder = class {
|
|
|
8196
8602
|
}
|
|
8197
8603
|
return this;
|
|
8198
8604
|
}
|
|
8605
|
+
/**
|
|
8606
|
+
* Add a relation field with optional configuration.
|
|
8607
|
+
* Use this for relation attributes that need specific configuration
|
|
8608
|
+
* (e.g., which qualified properties to display).
|
|
8609
|
+
*/
|
|
8610
|
+
relationField(slotId, attribute, options) {
|
|
8611
|
+
this.fieldList.push({
|
|
8612
|
+
slotId,
|
|
8613
|
+
attribute,
|
|
8614
|
+
relationConfig: options ? {
|
|
8615
|
+
visibleProperties: options.visibleProperties,
|
|
8616
|
+
allowCreate: options.allowCreate
|
|
8617
|
+
} : void 0
|
|
8618
|
+
});
|
|
8619
|
+
return this;
|
|
8620
|
+
}
|
|
8199
8621
|
/**
|
|
8200
8622
|
* Set the next node and complete the form definition
|
|
8201
8623
|
*/
|
|
@@ -8337,6 +8759,68 @@ var WorkflowAssignBuilder = class {
|
|
|
8337
8759
|
});
|
|
8338
8760
|
}
|
|
8339
8761
|
};
|
|
8762
|
+
var WorkflowAIBuilder = class {
|
|
8763
|
+
/** @internal */
|
|
8764
|
+
constructor(workflowBuilder, nodeId, label) {
|
|
8765
|
+
this.action = null;
|
|
8766
|
+
this.workflowBuilder = workflowBuilder;
|
|
8767
|
+
this.nodeId = nodeId;
|
|
8768
|
+
this.label = label;
|
|
8769
|
+
}
|
|
8770
|
+
/**
|
|
8771
|
+
* Set the description for this AI node
|
|
8772
|
+
*/
|
|
8773
|
+
describe(description) {
|
|
8774
|
+
this.nodeDescription = description;
|
|
8775
|
+
return this;
|
|
8776
|
+
}
|
|
8777
|
+
/**
|
|
8778
|
+
* Set a custom timeout (default: 120_000ms)
|
|
8779
|
+
*/
|
|
8780
|
+
timeout(ms) {
|
|
8781
|
+
this.nodeTimeoutMs = ms;
|
|
8782
|
+
return this;
|
|
8783
|
+
}
|
|
8784
|
+
/**
|
|
8785
|
+
* Configure document generation action
|
|
8786
|
+
*/
|
|
8787
|
+
documentGeneration(config) {
|
|
8788
|
+
this.action = {
|
|
8789
|
+
type: "document-generation",
|
|
8790
|
+
...config
|
|
8791
|
+
};
|
|
8792
|
+
return this;
|
|
8793
|
+
}
|
|
8794
|
+
/**
|
|
8795
|
+
* Configure code execution action
|
|
8796
|
+
*/
|
|
8797
|
+
codeExecution(config) {
|
|
8798
|
+
this.action = {
|
|
8799
|
+
type: "code-execution",
|
|
8800
|
+
...config
|
|
8801
|
+
};
|
|
8802
|
+
return this;
|
|
8803
|
+
}
|
|
8804
|
+
/**
|
|
8805
|
+
* Set the next node and complete the AI node definition
|
|
8806
|
+
*/
|
|
8807
|
+
next(nodeId) {
|
|
8808
|
+
if (!this.action) {
|
|
8809
|
+
throw new Error(
|
|
8810
|
+
`[WorkflowBuilder] AI node "${this.nodeId}" must have an action. Use .documentGeneration() or .codeExecution() first.`
|
|
8811
|
+
);
|
|
8812
|
+
}
|
|
8813
|
+
return this.workflowBuilder._addNode({
|
|
8814
|
+
type: "ai",
|
|
8815
|
+
id: this.nodeId,
|
|
8816
|
+
label: this.label,
|
|
8817
|
+
description: this.nodeDescription,
|
|
8818
|
+
action: this.action,
|
|
8819
|
+
timeoutMs: this.nodeTimeoutMs,
|
|
8820
|
+
next: nodeId
|
|
8821
|
+
});
|
|
8822
|
+
}
|
|
8823
|
+
};
|
|
8340
8824
|
var WorkflowEndBuilder = class {
|
|
8341
8825
|
/** @internal */
|
|
8342
8826
|
constructor(workflowBuilder, nodeId) {
|
|
@@ -8508,6 +8992,12 @@ var WorkflowBuilder = class {
|
|
|
8508
8992
|
assign(id, label, targetSlotId) {
|
|
8509
8993
|
return new WorkflowAssignBuilder(this, id, label, targetSlotId);
|
|
8510
8994
|
}
|
|
8995
|
+
/**
|
|
8996
|
+
* Define an AI node (run an AI action like document generation or code execution)
|
|
8997
|
+
*/
|
|
8998
|
+
ai(id, label) {
|
|
8999
|
+
return new WorkflowAIBuilder(this, id, label);
|
|
9000
|
+
}
|
|
8511
9001
|
/**
|
|
8512
9002
|
* Define an end node
|
|
8513
9003
|
*/
|
|
@@ -13630,7 +14120,7 @@ var WorkflowInstanceService = class extends BaseService {
|
|
|
13630
14120
|
* Start a new workflow instance
|
|
13631
14121
|
*/
|
|
13632
14122
|
async startWorkflow(input) {
|
|
13633
|
-
|
|
14123
|
+
let workflow2 = await this.workflowService.getWorkflow(input.workflowName);
|
|
13634
14124
|
if (!workflow2) {
|
|
13635
14125
|
throw new SchemaError(
|
|
13636
14126
|
`Workflow "${input.workflowName}" not found`,
|
|
@@ -13643,6 +14133,20 @@ var WorkflowInstanceService = class extends BaseService {
|
|
|
13643
14133
|
SchemaErrorCode.VALIDATION_FAILED
|
|
13644
14134
|
);
|
|
13645
14135
|
}
|
|
14136
|
+
if (workflow2.system && this.adapter.workflows) {
|
|
14137
|
+
const dbWorkflow = await this.adapter.workflows.upsert({
|
|
14138
|
+
name: workflow2.name,
|
|
14139
|
+
label: workflow2.label ?? workflow2.name,
|
|
14140
|
+
description: workflow2.description,
|
|
14141
|
+
status: "published",
|
|
14142
|
+
version: workflow2.version,
|
|
14143
|
+
slots: workflow2.slots ?? [],
|
|
14144
|
+
nodes: workflow2.nodes,
|
|
14145
|
+
startNodeId: workflow2.startNodeId,
|
|
14146
|
+
system: true
|
|
14147
|
+
});
|
|
14148
|
+
workflow2 = { ...workflow2, id: dbWorkflow.id };
|
|
14149
|
+
}
|
|
13646
14150
|
const context = createEmptyContext();
|
|
13647
14151
|
if (input.initialSlots) {
|
|
13648
14152
|
for (const [slotId, data] of Object.entries(input.initialSlots)) {
|
|
@@ -17060,6 +17564,74 @@ var PermissionService = class extends BaseService {
|
|
|
17060
17564
|
// ============================================================================
|
|
17061
17565
|
// INITIALIZATION
|
|
17062
17566
|
// ============================================================================
|
|
17567
|
+
/**
|
|
17568
|
+
* Reset all roles and permissions to their default configuration.
|
|
17569
|
+
*
|
|
17570
|
+
* This will:
|
|
17571
|
+
* 1. Delete all custom (non-system) roles and reassign their users to the default member role
|
|
17572
|
+
* 2. Reset permissions on the default roles (owner, member) back to defaults
|
|
17573
|
+
* 3. Invalidate all permission caches
|
|
17574
|
+
*
|
|
17575
|
+
* @example
|
|
17576
|
+
* ```typescript
|
|
17577
|
+
* const service = new PermissionService(adapter);
|
|
17578
|
+
* await service.resetToDefaults();
|
|
17579
|
+
* ```
|
|
17580
|
+
*/
|
|
17581
|
+
async resetToDefaults() {
|
|
17582
|
+
const { DEFAULT_ROLES, DEFAULT_ROLE_PERMISSIONS } = await import("./default-roles-6D3HQ3DQ.mjs");
|
|
17583
|
+
await this.initializeDefaultRoles();
|
|
17584
|
+
const allRoles = await this.getRoles();
|
|
17585
|
+
const memberRole = allRoles.find((r) => r.name === DEFAULT_ROLES.MEMBER);
|
|
17586
|
+
if (!memberRole) {
|
|
17587
|
+
throw new Error("Default member role not found after initialization");
|
|
17588
|
+
}
|
|
17589
|
+
const customRoles = allRoles.filter(
|
|
17590
|
+
(r) => !Object.values(DEFAULT_ROLES).includes(
|
|
17591
|
+
r.name
|
|
17592
|
+
)
|
|
17593
|
+
);
|
|
17594
|
+
for (const role of customRoles) {
|
|
17595
|
+
const usersWithRole = await this.permissionsRepo.countUsersWithRole(role.name);
|
|
17596
|
+
if (usersWithRole > 0) {
|
|
17597
|
+
}
|
|
17598
|
+
await this.permissionsRepo.deleteRole(role.id);
|
|
17599
|
+
}
|
|
17600
|
+
for (const roleName of Object.values(DEFAULT_ROLES)) {
|
|
17601
|
+
const role = allRoles.find((r) => r.name === roleName);
|
|
17602
|
+
if (!role) continue;
|
|
17603
|
+
const permConfig = DEFAULT_ROLE_PERMISSIONS[roleName];
|
|
17604
|
+
const permissionInputs = [];
|
|
17605
|
+
for (const perm of permConfig.system) {
|
|
17606
|
+
permissionInputs.push({
|
|
17607
|
+
scope: "system",
|
|
17608
|
+
target: perm.target,
|
|
17609
|
+
actions: perm.actions
|
|
17610
|
+
});
|
|
17611
|
+
}
|
|
17612
|
+
for (const perm of permConfig.object) {
|
|
17613
|
+
permissionInputs.push({
|
|
17614
|
+
scope: "object",
|
|
17615
|
+
target: perm.target,
|
|
17616
|
+
actions: perm.actions
|
|
17617
|
+
});
|
|
17618
|
+
}
|
|
17619
|
+
await this.permissionsRepo.setPermissions(role.id, permissionInputs);
|
|
17620
|
+
}
|
|
17621
|
+
await this.invalidateAllCache();
|
|
17622
|
+
if (this.auditService && this.userId) {
|
|
17623
|
+
await this.auditService.logRoleAction({
|
|
17624
|
+
action: "role.updated",
|
|
17625
|
+
actorId: this.userId,
|
|
17626
|
+
roleId: "all",
|
|
17627
|
+
roleLabel: "All roles",
|
|
17628
|
+
metadata: {
|
|
17629
|
+
resetToDefaults: true,
|
|
17630
|
+
customRolesDeleted: customRoles.length
|
|
17631
|
+
}
|
|
17632
|
+
});
|
|
17633
|
+
}
|
|
17634
|
+
}
|
|
17063
17635
|
/**
|
|
17064
17636
|
* Initialize default roles for the tenant if they don't exist.
|
|
17065
17637
|
*
|
|
@@ -18136,6 +18708,7 @@ export {
|
|
|
18136
18708
|
isFormNode,
|
|
18137
18709
|
isConditionNode,
|
|
18138
18710
|
isAssignNode,
|
|
18711
|
+
isAINode,
|
|
18139
18712
|
isEndNode,
|
|
18140
18713
|
isConditionRule,
|
|
18141
18714
|
isConditionGroup,
|
|
@@ -18186,6 +18759,10 @@ export {
|
|
|
18186
18759
|
AssignmentSourceSchema,
|
|
18187
18760
|
AssignmentMappingSchema,
|
|
18188
18761
|
AssignNodeSchema,
|
|
18762
|
+
DocumentGenerationActionSchema,
|
|
18763
|
+
CodeExecutionActionSchema,
|
|
18764
|
+
AIActionConfigSchema,
|
|
18765
|
+
AINodeSchema,
|
|
18189
18766
|
EndNodeSchema,
|
|
18190
18767
|
WorkflowNodeSchema,
|
|
18191
18768
|
SlotModeSchema,
|
|
@@ -18283,6 +18860,7 @@ export {
|
|
|
18283
18860
|
WorkflowSimpleFormBuilder,
|
|
18284
18861
|
WorkflowConditionBuilder,
|
|
18285
18862
|
WorkflowAssignBuilder,
|
|
18863
|
+
WorkflowAIBuilder,
|
|
18286
18864
|
WorkflowEndBuilder,
|
|
18287
18865
|
WorkflowStartBuilder,
|
|
18288
18866
|
WorkflowBuilder,
|
|
@@ -18336,6 +18914,11 @@ export {
|
|
|
18336
18914
|
EndExecutor,
|
|
18337
18915
|
FormExecutor,
|
|
18338
18916
|
AssignExecutor,
|
|
18917
|
+
AIExecutor,
|
|
18918
|
+
AIActionRegistry,
|
|
18919
|
+
DocumentGenerationHandler,
|
|
18920
|
+
CodeExecutionHandler,
|
|
18921
|
+
createDefaultAIActionRegistry,
|
|
18339
18922
|
StartExecutor,
|
|
18340
18923
|
createDefaultExecutorRegistry,
|
|
18341
18924
|
getDefaultExecutorRegistry,
|