@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.
@@ -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
- if (this.rows.length === 0) {
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 rows.`
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
- const workflow2 = await this.workflowService.getWorkflow(input.workflowName);
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,