@oomol-lab/open-flow 0.1.0-beta.54 → 0.1.0-beta.55

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.
Files changed (38) hide show
  1. package/dist/browser/{createResourceDialog-BsaBMf7_.js → createResourceDialog-4H5_lZ6s.js} +3 -3
  2. package/dist/browser/{main-BPABKzwN.js → dist-BFmpkX4P.js} +9 -1
  3. package/dist/browser/flow-authoring-node.d.ts +5 -0
  4. package/dist/browser/flow-authoring.d.ts +1 -1
  5. package/dist/browser/flow-authoring.js +9434 -9187
  6. package/dist/browser/flow-change.d.ts +6 -1
  7. package/dist/browser/flow-change.js +3108 -141
  8. package/dist/browser/{flowChanges-CcscgZsW.js → flowChanges-ZzG-f9cg.js} +1978 -5437
  9. package/dist/browser/{flowWorkspace-CoT_ewLX.js → flowWorkspace-ChpRaTMX.js} +3197 -310
  10. package/dist/browser/{icons-0s-Q_3lp.js → icons-CdAB9wyS.js} +4294 -54
  11. package/dist/browser/{markdownContent-D3FFc-u_.js → markdownContent-frwDfQQU.js} +1 -2
  12. package/dist/browser/preview.css +375 -322
  13. package/dist/browser/preview.js +5458 -1888
  14. package/dist/browser/theme.css +1 -0
  15. package/dist/browser/ui.css +30 -0
  16. package/dist/browser/ui.js +4 -3
  17. package/dist/browser/workbench.css +375 -322
  18. package/dist/browser/workbench.js +8 -8
  19. package/dist/browser/{workbenchSelect-BqUPacsr.js → workbenchSelect-BRZN4ish.js} +1 -1
  20. package/dist/common/authoringExamples.d.ts +3 -2
  21. package/dist/common/control-api-conformance.js +3410 -3285
  22. package/dist/common/control-api.js +3680 -3531
  23. package/dist/common/control-requests.js +2132 -1860
  24. package/dist/common/decision.d.ts +47 -0
  25. package/dist/common/decision.js +10153 -0
  26. package/dist/common/flow-encoding.js +3105 -124
  27. package/dist/common/flow-semantics.js +276 -2
  28. package/dist/common/integration-trigger.js +202 -1
  29. package/dist/common/mcp.js +3748 -3623
  30. package/dist/common/openapi.js +202 -1
  31. package/dist/common/poll-trigger.js +226 -1
  32. package/dist/common/run-events.js +1 -0
  33. package/dist/common/runtime-contract.d.ts +8 -0
  34. package/dist/common/scheduler.d.ts +1 -1
  35. package/dist/common/scheduler.js +2137 -1936
  36. package/dist/common/webhook-trigger.js +202 -1
  37. package/package.json +5 -1
  38. package/dist/browser/dist-BDBTOgS5.js +0 -9
@@ -6072,6 +6072,70 @@ var $ZodUnion = /*@__PURE__*/ $constructor("$ZodUnion", (inst, def) => {
6072
6072
  });
6073
6073
  };
6074
6074
  });
6075
+ function discriminatorMap(def) {
6076
+ const map = /* @__PURE__ */ new Map();
6077
+ for (const option of def.options) {
6078
+ const values = option._zod.propValues?.[def.discriminator];
6079
+ if (!values || values.size === 0) throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`);
6080
+ for (const value of values) if (map.has(value)) {
6081
+ if (value !== void 0) throw new Error(`Duplicate discriminator value "${String(value)}"`);
6082
+ map.set(value, null);
6083
+ } else map.set(value, option);
6084
+ }
6085
+ return map;
6086
+ }
6087
+ var $ZodDiscriminatedUnion = /*@__PURE__*/ $constructor("$ZodDiscriminatedUnion", (inst, def) => {
6088
+ def.inclusive = false;
6089
+ $ZodUnion.init(inst, def);
6090
+ const _super = inst._zod.parse;
6091
+ defineLazyInternal(inst, "propValues", (zod) => {
6092
+ const propValues = {};
6093
+ let undefinedCount = 0;
6094
+ for (const option of zod.def.options) {
6095
+ const pv = option._zod.propValues;
6096
+ if (!pv || Object.keys(pv).length === 0) throw new Error(`Invalid discriminated union option at index "${zod.def.options.indexOf(option)}"`);
6097
+ if (pv[zod.def.discriminator]?.has(void 0)) undefinedCount++;
6098
+ for (const [k, v] of Object.entries(pv)) {
6099
+ if (!Object.prototype.hasOwnProperty.call(propValues, k)) assignProp(propValues, k, /* @__PURE__ */ new Set());
6100
+ for (const val of v) propValues[k].add(val);
6101
+ }
6102
+ }
6103
+ if (!zod.def.unionFallback && undefinedCount > 1) propValues[zod.def.discriminator]?.delete(void 0);
6104
+ return propValues;
6105
+ });
6106
+ def.options.forEach((option, i) => {
6107
+ const propShape = rawShape(option._zod.def);
6108
+ if (propShape && !Object.prototype.hasOwnProperty.call(propShape, def.discriminator)) throw new Error(`Invalid discriminated union option at index "${i}"`);
6109
+ });
6110
+ const disc = cached(() => discriminatorMap(def));
6111
+ inst._zod.parse = (payload, ctx) => {
6112
+ const input = payload.value;
6113
+ if (!isObject(input)) {
6114
+ payload.issues.push({
6115
+ code: "invalid_type",
6116
+ expected: "object",
6117
+ input,
6118
+ inst
6119
+ });
6120
+ return payload;
6121
+ }
6122
+ const value = input?.[def.discriminator];
6123
+ const opt = disc.value.get(value);
6124
+ if (opt && (value !== void 0 || ctx.direction !== "backward")) return opt._zod.run(payload, ctx);
6125
+ if (def.unionFallback || ctx.direction === "backward") return _super(payload, ctx);
6126
+ payload.issues.push({
6127
+ code: "invalid_union",
6128
+ errors: [],
6129
+ note: "No matching discriminator",
6130
+ discriminator: def.discriminator,
6131
+ options: Array.from(disc.value.keys()).filter((value) => disc.value.get(value) !== null),
6132
+ input,
6133
+ path: [def.discriminator],
6134
+ inst
6135
+ });
6136
+ return payload;
6137
+ };
6138
+ });
6075
6139
  var $ZodIntersection = /*@__PURE__*/ $constructor("$ZodIntersection", (inst, def) => {
6076
6140
  $ZodType.init(inst, def);
6077
6141
  inst._zod.parse = (payload, ctx) => {
@@ -9120,6 +9184,18 @@ function union(options, params) {
9120
9184
  ...normalizeParams(params)
9121
9185
  });
9122
9186
  }
9187
+ var ZodDiscriminatedUnion = /*@__PURE__*/ $constructor("ZodDiscriminatedUnion", (inst, def) => {
9188
+ ZodUnion.init(inst, def);
9189
+ $ZodDiscriminatedUnion.init(inst, def);
9190
+ });
9191
+ function discriminatedUnion(discriminator, options, params) {
9192
+ return new ZodDiscriminatedUnion({
9193
+ type: "union",
9194
+ options,
9195
+ discriminator,
9196
+ ...normalizeParams(params)
9197
+ });
9198
+ }
9123
9199
  var ZodIntersection = /*@__PURE__*/ $constructor("ZodIntersection", (inst, def) => {
9124
9200
  $ZodIntersection.init(inst, def);
9125
9201
  ZodType.init(inst, def);
@@ -9521,6 +9597,32 @@ var agentValue = union([object$1({
9521
9597
  input: text
9522
9598
  })]);
9523
9599
  var agentInput$1 = union([agentValue, object$1({ kind: literal("model") })]);
9600
+ var decisionQuestion = discriminatedUnion("type", [
9601
+ strictObject({
9602
+ name: text,
9603
+ instructions: text,
9604
+ type: literal("noul"),
9605
+ criteria: strictObject({
9606
+ true: text.optional(),
9607
+ false: text.optional()
9608
+ }).optional()
9609
+ }),
9610
+ strictObject({
9611
+ name: text,
9612
+ instructions: text,
9613
+ type: literal("choice"),
9614
+ criteria: array(strictObject({
9615
+ name: text,
9616
+ description: text
9617
+ }))
9618
+ }),
9619
+ strictObject({
9620
+ name: text,
9621
+ instructions: text,
9622
+ type: literal("score"),
9623
+ criteria: strings
9624
+ })
9625
+ ]);
9524
9626
  var managed = object$1({
9525
9627
  ...ports,
9526
9628
  name: text,
@@ -9548,6 +9650,10 @@ var managed = object$1({
9548
9650
  in: _enum(["header", "query"]).optional()
9549
9651
  }))
9550
9652
  }),
9653
+ strictObject({
9654
+ kind: literal("decision"),
9655
+ questions: array(decisionQuestion)
9656
+ }),
9551
9657
  object$1({
9552
9658
  kind: literal("llm"),
9553
9659
  mode: _enum(["chat", "json"])
@@ -9574,7 +9680,7 @@ var managed = object$1({
9574
9680
  }).optional()
9575
9681
  })
9576
9682
  ])
9577
- });
9683
+ }).transform(limitDecisionTask);
9578
9684
  var operand = union([object$1({
9579
9685
  kind: literal("value"),
9580
9686
  value: json.optional(),
@@ -9968,6 +10074,11 @@ var shapes = {
9968
10074
  before: text.optional(),
9969
10075
  value: text.optional()
9970
10076
  },
10077
+ "task.decision.set": {
10078
+ taskId: text,
10079
+ before: managed,
10080
+ value: managed
10081
+ },
9971
10082
  "task.openapi.set": {
9972
10083
  taskId: text,
9973
10084
  before: managed,
@@ -10403,6 +10514,162 @@ function hasRetiredRef(value) {
10403
10514
  return source.contentMediaType == "oomol/ref" || Object.values(source).some(hasRetiredRef);
10404
10515
  }
10405
10516
  //#endregion
10517
+ //#region src/decision/common/decision.ts
10518
+ var decisionLimits = {
10519
+ choice: 255,
10520
+ score: 10
10521
+ };
10522
+ /** Ordered prefixes are shared by authoring, schemas, validation, and execution. */
10523
+ function limitDecisionQuestion(question) {
10524
+ if (question.type === "noul" || question.criteria.length <= decisionLimits[question.type]) return question;
10525
+ if (question.type === "choice") return {
10526
+ ...question,
10527
+ criteria: question.criteria.slice(0, decisionLimits.choice)
10528
+ };
10529
+ return {
10530
+ ...question,
10531
+ criteria: question.criteria.slice(0, decisionLimits.score)
10532
+ };
10533
+ }
10534
+ function limitDecisionQuestions(questions) {
10535
+ const limited = questions.map(limitDecisionQuestion);
10536
+ return limited.every((question, i) => question === questions[i]) ? questions : limited;
10537
+ }
10538
+ /** Loading an oversized task also updates its previously generated output schemas. */
10539
+ function limitDecisionTask(task) {
10540
+ if (task.executor.kind !== "decision") return task;
10541
+ const original = task.executor.questions;
10542
+ const questions = limitDecisionQuestions(original);
10543
+ if (questions === original) return task;
10544
+ const outputs = task.outputs.map((port) => {
10545
+ if (!("handle" in port)) return port;
10546
+ const index = original.findIndex((question) => question.name === port.handle);
10547
+ if (index < 0 || original[index] === questions[index] || !dequal(port.jsonSchema, answerSchema(original[index]))) return port;
10548
+ return {
10549
+ ...port,
10550
+ jsonSchema: decisionAnswerSchema(questions[index])
10551
+ };
10552
+ });
10553
+ return {
10554
+ ...task,
10555
+ executor: {
10556
+ ...task.executor,
10557
+ questions
10558
+ },
10559
+ outputs
10560
+ };
10561
+ }
10562
+ var decisionStateSchema = { type: [
10563
+ "string",
10564
+ "object",
10565
+ "array"
10566
+ ] };
10567
+ var probability = {
10568
+ type: "number",
10569
+ minimum: 0,
10570
+ maximum: 1
10571
+ };
10572
+ var defaultDecisionQuestion = (name = "decision1") => ({
10573
+ name,
10574
+ type: "noul",
10575
+ instructions: ""
10576
+ });
10577
+ function decisionQuestionIssues(questions) {
10578
+ questions = limitDecisionQuestions(questions);
10579
+ const issues = [];
10580
+ if (!questions.length) issues.push({
10581
+ field: "questions",
10582
+ message: "Add at least one question."
10583
+ });
10584
+ questions.forEach((question, index) => {
10585
+ const add = (field, message) => issues.push({
10586
+ question: index,
10587
+ field,
10588
+ message
10589
+ });
10590
+ if (!question.name.trim() || question.name === "__proto__" || questions.some((other, i) => i !== index && other.name === question.name)) add("name", "Question names must be non-empty and unique; __proto__ is reserved.");
10591
+ if (!question.instructions.trim()) add("instructions", "Describe the question to evaluate.");
10592
+ if (question.type === "choice") {
10593
+ if (!question.criteria.length) add("criteria", "Provide between 1 and 255 choices.");
10594
+ const names = question.criteria.map((item) => item.name);
10595
+ if (names.some((name) => !name.trim() || name === "__proto__") || new Set(names).size !== names.length) add("criteria", "Choice names must be non-empty and unique; __proto__ is reserved.");
10596
+ }
10597
+ if (question.type === "score" && (question.criteria.length < 2 || question.criteria.some((level) => !level.trim()))) add("criteria", "Provide between 2 and 10 non-empty levels, in increasing order.");
10598
+ });
10599
+ return issues;
10600
+ }
10601
+ function decisionAnswerSchema(question) {
10602
+ return answerSchema(limitDecisionQuestion(question));
10603
+ }
10604
+ function answerSchema(question) {
10605
+ const properties = { type: { const: question.type } };
10606
+ if (question.type === "noul") properties.noul = probability;
10607
+ else {
10608
+ const keys = question.type === "choice" ? question.criteria.map((item) => item.name) : question.criteria.map((_, index) => String(index));
10609
+ properties.confidence = probability;
10610
+ properties.probabilities = {
10611
+ type: "object",
10612
+ properties: Object.fromEntries(keys.map((key) => [key, probability])),
10613
+ required: keys,
10614
+ additionalProperties: false
10615
+ };
10616
+ if (question.type === "choice") properties.choice = {
10617
+ type: "string",
10618
+ ...keys.length ? { enum: keys } : {}
10619
+ };
10620
+ else {
10621
+ properties.score = {
10622
+ type: "number",
10623
+ minimum: 0,
10624
+ maximum: Math.max(0, keys.length - 1)
10625
+ };
10626
+ properties.legend = {
10627
+ type: "object",
10628
+ properties: Object.fromEntries(keys.map((key) => [key, { type: "string" }])),
10629
+ required: keys,
10630
+ additionalProperties: false
10631
+ };
10632
+ }
10633
+ }
10634
+ return {
10635
+ type: "object",
10636
+ properties,
10637
+ required: Object.keys(properties)
10638
+ };
10639
+ }
10640
+ function decisionTask(questions = [defaultDecisionQuestion()], name = "AI Decision") {
10641
+ questions = limitDecisionQuestions(questions);
10642
+ const inputs = [{
10643
+ handle: "target",
10644
+ description: "Text, object, or array to evaluate across all questions.",
10645
+ jsonSchema: decisionStateSchema,
10646
+ nullable: false
10647
+ }];
10648
+ const outputs = questions.map((question) => ({
10649
+ handle: question.name,
10650
+ jsonSchema: decisionAnswerSchema(question),
10651
+ nullable: false
10652
+ }));
10653
+ return {
10654
+ name,
10655
+ executor: {
10656
+ kind: "decision",
10657
+ questions
10658
+ },
10659
+ inputs,
10660
+ outputs
10661
+ };
10662
+ }
10663
+ function decisionTaskIssues(task) {
10664
+ task = limitDecisionTask(task);
10665
+ if (task.executor.kind !== "decision") return [];
10666
+ const expected = decisionTask(task.executor.questions, task.name);
10667
+ return [...decisionQuestionIssues(task.executor.questions), ...!dequal(task.inputs, expected.inputs) || !dequal(task.outputs, expected.outputs) ? [{
10668
+ field: "ports",
10669
+ message: "AI Decision ports must match its questions."
10670
+ }] : []];
10671
+ }
10672
+ //#endregion
10406
10673
  //#region src/openapi/common/openapi.ts
10407
10674
  var methods = [
10408
10675
  "get",
@@ -24045,6 +24312,13 @@ async function validateFlow(revision, engine) {
24045
24312
  for (const taskId of [...closure.dependencies.tasks].toSorted()) {
24046
24313
  const task = revision.document.tasks[taskId];
24047
24314
  if (task == null) continue;
24315
+ for (const issue of decisionTaskIssues(task)) checked.diagnostics.push({
24316
+ code: "decision.config-invalid",
24317
+ column: 0,
24318
+ line: 1,
24319
+ message: issue.message,
24320
+ path: `/document/tasks/${taskId}/executor`
24321
+ });
24048
24322
  for (const message of openApiIssues(task)) checked.diagnostics.push({
24049
24323
  code: "openapi.config-invalid",
24050
24324
  column: 0,
@@ -24173,7 +24447,7 @@ async function prepareFlow(revision, engineContract, triggerId) {
24173
24447
  graph: revision.document.graph,
24174
24448
  modules: Object.fromEntries([...closure.dependencies.modules].toSorted().map((id) => [id, revision.modules[id]])),
24175
24449
  subflows: Object.fromEntries([...closure.dependencies.subflows].toSorted().map((id) => [id, revision.document.subflows[id]])),
24176
- tasks: Object.fromEntries([...closure.dependencies.tasks].toSorted().map((id) => [id, revision.document.tasks[id]]))
24450
+ tasks: Object.fromEntries([...closure.dependencies.tasks].toSorted().map((id) => [id, limitDecisionTask(revision.document.tasks[id])]))
24177
24451
  },
24178
24452
  kind: "prepared",
24179
24453
  validation
@@ -5918,6 +5918,70 @@ var $ZodUnion = /*@__PURE__*/ $constructor("$ZodUnion", (inst, def) => {
5918
5918
  });
5919
5919
  };
5920
5920
  });
5921
+ function discriminatorMap(def) {
5922
+ const map = /* @__PURE__ */ new Map();
5923
+ for (const option of def.options) {
5924
+ const values = option._zod.propValues?.[def.discriminator];
5925
+ if (!values || values.size === 0) throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`);
5926
+ for (const value of values) if (map.has(value)) {
5927
+ if (value !== void 0) throw new Error(`Duplicate discriminator value "${String(value)}"`);
5928
+ map.set(value, null);
5929
+ } else map.set(value, option);
5930
+ }
5931
+ return map;
5932
+ }
5933
+ var $ZodDiscriminatedUnion = /*@__PURE__*/ $constructor("$ZodDiscriminatedUnion", (inst, def) => {
5934
+ def.inclusive = false;
5935
+ $ZodUnion.init(inst, def);
5936
+ const _super = inst._zod.parse;
5937
+ defineLazyInternal(inst, "propValues", (zod) => {
5938
+ const propValues = {};
5939
+ let undefinedCount = 0;
5940
+ for (const option of zod.def.options) {
5941
+ const pv = option._zod.propValues;
5942
+ if (!pv || Object.keys(pv).length === 0) throw new Error(`Invalid discriminated union option at index "${zod.def.options.indexOf(option)}"`);
5943
+ if (pv[zod.def.discriminator]?.has(void 0)) undefinedCount++;
5944
+ for (const [k, v] of Object.entries(pv)) {
5945
+ if (!Object.prototype.hasOwnProperty.call(propValues, k)) assignProp(propValues, k, /* @__PURE__ */ new Set());
5946
+ for (const val of v) propValues[k].add(val);
5947
+ }
5948
+ }
5949
+ if (!zod.def.unionFallback && undefinedCount > 1) propValues[zod.def.discriminator]?.delete(void 0);
5950
+ return propValues;
5951
+ });
5952
+ def.options.forEach((option, i) => {
5953
+ const propShape = rawShape(option._zod.def);
5954
+ if (propShape && !Object.prototype.hasOwnProperty.call(propShape, def.discriminator)) throw new Error(`Invalid discriminated union option at index "${i}"`);
5955
+ });
5956
+ const disc = cached(() => discriminatorMap(def));
5957
+ inst._zod.parse = (payload, ctx) => {
5958
+ const input = payload.value;
5959
+ if (!isObject(input)) {
5960
+ payload.issues.push({
5961
+ code: "invalid_type",
5962
+ expected: "object",
5963
+ input,
5964
+ inst
5965
+ });
5966
+ return payload;
5967
+ }
5968
+ const value = input?.[def.discriminator];
5969
+ const opt = disc.value.get(value);
5970
+ if (opt && (value !== void 0 || ctx.direction !== "backward")) return opt._zod.run(payload, ctx);
5971
+ if (def.unionFallback || ctx.direction === "backward") return _super(payload, ctx);
5972
+ payload.issues.push({
5973
+ code: "invalid_union",
5974
+ errors: [],
5975
+ note: "No matching discriminator",
5976
+ discriminator: def.discriminator,
5977
+ options: Array.from(disc.value.keys()).filter((value) => disc.value.get(value) !== null),
5978
+ input,
5979
+ path: [def.discriminator],
5980
+ inst
5981
+ });
5982
+ return payload;
5983
+ };
5984
+ });
5921
5985
  var $ZodIntersection = /*@__PURE__*/ $constructor("$ZodIntersection", (inst, def) => {
5922
5986
  $ZodType.init(inst, def);
5923
5987
  inst._zod.parse = (payload, ctx) => {
@@ -8966,6 +9030,18 @@ function union(options, params) {
8966
9030
  ...normalizeParams(params)
8967
9031
  });
8968
9032
  }
9033
+ var ZodDiscriminatedUnion = /*@__PURE__*/ $constructor("ZodDiscriminatedUnion", (inst, def) => {
9034
+ ZodUnion.init(inst, def);
9035
+ $ZodDiscriminatedUnion.init(inst, def);
9036
+ });
9037
+ function discriminatedUnion(discriminator, options, params) {
9038
+ return new ZodDiscriminatedUnion({
9039
+ type: "union",
9040
+ options,
9041
+ discriminator,
9042
+ ...normalizeParams(params)
9043
+ });
9044
+ }
8969
9045
  var ZodIntersection = /*@__PURE__*/ $constructor("ZodIntersection", (inst, def) => {
8970
9046
  $ZodIntersection.init(inst, def);
8971
9047
  ZodType.init(inst, def);
@@ -9244,6 +9320,96 @@ function json$1(params) {
9244
9320
  return jsonSchema;
9245
9321
  }
9246
9322
  //#endregion
9323
+ //#region src/decision/common/decision.ts
9324
+ var decisionLimits = {
9325
+ choice: 255,
9326
+ score: 10
9327
+ };
9328
+ /** Ordered prefixes are shared by authoring, schemas, validation, and execution. */
9329
+ function limitDecisionQuestion(question) {
9330
+ if (question.type === "noul" || question.criteria.length <= decisionLimits[question.type]) return question;
9331
+ if (question.type === "choice") return {
9332
+ ...question,
9333
+ criteria: question.criteria.slice(0, decisionLimits.choice)
9334
+ };
9335
+ return {
9336
+ ...question,
9337
+ criteria: question.criteria.slice(0, decisionLimits.score)
9338
+ };
9339
+ }
9340
+ function limitDecisionQuestions(questions) {
9341
+ const limited = questions.map(limitDecisionQuestion);
9342
+ return limited.every((question, i) => question === questions[i]) ? questions : limited;
9343
+ }
9344
+ /** Loading an oversized task also updates its previously generated output schemas. */
9345
+ function limitDecisionTask(task) {
9346
+ if (task.executor.kind !== "decision") return task;
9347
+ const original = task.executor.questions;
9348
+ const questions = limitDecisionQuestions(original);
9349
+ if (questions === original) return task;
9350
+ const outputs = task.outputs.map((port) => {
9351
+ if (!("handle" in port)) return port;
9352
+ const index = original.findIndex((question) => question.name === port.handle);
9353
+ if (index < 0 || original[index] === questions[index] || !dequal(port.jsonSchema, answerSchema(original[index]))) return port;
9354
+ return {
9355
+ ...port,
9356
+ jsonSchema: decisionAnswerSchema(questions[index])
9357
+ };
9358
+ });
9359
+ return {
9360
+ ...task,
9361
+ executor: {
9362
+ ...task.executor,
9363
+ questions
9364
+ },
9365
+ outputs
9366
+ };
9367
+ }
9368
+ var probability = {
9369
+ type: "number",
9370
+ minimum: 0,
9371
+ maximum: 1
9372
+ };
9373
+ function decisionAnswerSchema(question) {
9374
+ return answerSchema(limitDecisionQuestion(question));
9375
+ }
9376
+ function answerSchema(question) {
9377
+ const properties = { type: { const: question.type } };
9378
+ if (question.type === "noul") properties.noul = probability;
9379
+ else {
9380
+ const keys = question.type === "choice" ? question.criteria.map((item) => item.name) : question.criteria.map((_, index) => String(index));
9381
+ properties.confidence = probability;
9382
+ properties.probabilities = {
9383
+ type: "object",
9384
+ properties: Object.fromEntries(keys.map((key) => [key, probability])),
9385
+ required: keys,
9386
+ additionalProperties: false
9387
+ };
9388
+ if (question.type === "choice") properties.choice = {
9389
+ type: "string",
9390
+ ...keys.length ? { enum: keys } : {}
9391
+ };
9392
+ else {
9393
+ properties.score = {
9394
+ type: "number",
9395
+ minimum: 0,
9396
+ maximum: Math.max(0, keys.length - 1)
9397
+ };
9398
+ properties.legend = {
9399
+ type: "object",
9400
+ properties: Object.fromEntries(keys.map((key) => [key, { type: "string" }])),
9401
+ required: keys,
9402
+ additionalProperties: false
9403
+ };
9404
+ }
9405
+ }
9406
+ return {
9407
+ type: "object",
9408
+ properties,
9409
+ required: Object.keys(properties)
9410
+ };
9411
+ }
9412
+ //#endregion
9247
9413
  //#region src/flow/common/triggerScheduleSchema.ts
9248
9414
  var triggerScheduleSchema = array(union([object({
9249
9415
  type: literal("cron"),
@@ -9360,6 +9526,32 @@ var agentValue = union([object({
9360
9526
  input: text
9361
9527
  })]);
9362
9528
  var agentInput = union([agentValue, object({ kind: literal("model") })]);
9529
+ var decisionQuestion = discriminatedUnion("type", [
9530
+ strictObject({
9531
+ name: text,
9532
+ instructions: text,
9533
+ type: literal("noul"),
9534
+ criteria: strictObject({
9535
+ true: text.optional(),
9536
+ false: text.optional()
9537
+ }).optional()
9538
+ }),
9539
+ strictObject({
9540
+ name: text,
9541
+ instructions: text,
9542
+ type: literal("choice"),
9543
+ criteria: array(strictObject({
9544
+ name: text,
9545
+ description: text
9546
+ }))
9547
+ }),
9548
+ strictObject({
9549
+ name: text,
9550
+ instructions: text,
9551
+ type: literal("score"),
9552
+ criteria: strings
9553
+ })
9554
+ ]);
9363
9555
  var managed = object({
9364
9556
  ...ports,
9365
9557
  name: text,
@@ -9387,6 +9579,10 @@ var managed = object({
9387
9579
  in: _enum(["header", "query"]).optional()
9388
9580
  }))
9389
9581
  }),
9582
+ strictObject({
9583
+ kind: literal("decision"),
9584
+ questions: array(decisionQuestion)
9585
+ }),
9390
9586
  object({
9391
9587
  kind: literal("llm"),
9392
9588
  mode: _enum(["chat", "json"])
@@ -9413,7 +9609,7 @@ var managed = object({
9413
9609
  }).optional()
9414
9610
  })
9415
9611
  ])
9416
- });
9612
+ }).transform(limitDecisionTask);
9417
9613
  var operand = union([object({
9418
9614
  kind: literal("value"),
9419
9615
  value: json.optional(),
@@ -9807,6 +10003,11 @@ var shapes = {
9807
10003
  before: text.optional(),
9808
10004
  value: text.optional()
9809
10005
  },
10006
+ "task.decision.set": {
10007
+ taskId: text,
10008
+ before: managed,
10009
+ value: managed
10010
+ },
9810
10011
  "task.openapi.set": {
9811
10012
  taskId: text,
9812
10013
  before: managed,