diff --git a/packages/client/src/promise/generated/types.ts b/packages/client/src/promise/generated/types.ts index bbca02f0c10..ff85364a14f 100644 --- a/packages/client/src/promise/generated/types.ts +++ b/packages/client/src/promise/generated/types.ts @@ -2705,97 +2705,190 @@ export type FormRequestListOutput = { readonly sessionID: string readonly title: string readonly metadata?: { readonly [x: string]: JsonValue } - readonly fields: ReadonlyArray< - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly fields: readonly [ + ( + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "string" - readonly format?: "email" | "uri" | "date" | "date-time" - readonly minLength?: number - readonly maxLength?: number - readonly pattern?: string - readonly placeholder?: string - readonly default?: string - readonly options?: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly custom?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "number" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "integer" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "boolean" - readonly default?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "multiselect" - readonly options: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly minItems?: number - readonly maxItems?: number - readonly custom?: boolean - readonly default?: ReadonlyArray - } - | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } - > + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + ), + ...Array< + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + >, + ] }> } @@ -2807,97 +2900,190 @@ export type FormListOutput = { readonly sessionID: string readonly title: string readonly metadata?: { readonly [x: string]: JsonValue } - readonly fields: ReadonlyArray< - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly fields: readonly [ + ( + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "string" - readonly format?: "email" | "uri" | "date" | "date-time" - readonly minLength?: number - readonly maxLength?: number - readonly pattern?: string - readonly placeholder?: string - readonly default?: string - readonly options?: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly custom?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "number" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "integer" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "boolean" - readonly default?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "multiselect" - readonly options: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly minItems?: number - readonly maxItems?: number - readonly custom?: boolean - readonly default?: ReadonlyArray - } - | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } - > + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + ), + ...Array< + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + >, + ] }> }["data"] @@ -2907,385 +3093,757 @@ export type FormCreateInput = { readonly id?: string | null readonly title: string readonly metadata?: { readonly [x: string]: JsonValue } - readonly fields: ReadonlyArray< - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly fields: readonly [ + ( + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "string" - readonly format?: "email" | "uri" | "date" | "date-time" - readonly minLength?: number - readonly maxLength?: number - readonly pattern?: string - readonly placeholder?: string - readonly default?: string - readonly options?: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly custom?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "number" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "integer" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "boolean" - readonly default?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "multiselect" - readonly options: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly minItems?: number - readonly maxItems?: number - readonly custom?: boolean - readonly default?: ReadonlyArray - } - | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } - > + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + ), + ...Array< + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + >, + ] }["id"] readonly title: { readonly id?: string | null readonly title: string readonly metadata?: { readonly [x: string]: JsonValue } - readonly fields: ReadonlyArray< - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly fields: readonly [ + ( + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "string" - readonly format?: "email" | "uri" | "date" | "date-time" - readonly minLength?: number - readonly maxLength?: number - readonly pattern?: string - readonly placeholder?: string - readonly default?: string - readonly options?: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly custom?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "number" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "integer" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "boolean" - readonly default?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "multiselect" - readonly options: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly minItems?: number - readonly maxItems?: number - readonly custom?: boolean - readonly default?: ReadonlyArray - } - | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } - > + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + ), + ...Array< + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + >, + ] }["title"] readonly metadata?: { readonly id?: string | null readonly title: string readonly metadata?: { readonly [x: string]: JsonValue } - readonly fields: ReadonlyArray< - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly fields: readonly [ + ( + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "string" - readonly format?: "email" | "uri" | "date" | "date-time" - readonly minLength?: number - readonly maxLength?: number - readonly pattern?: string - readonly placeholder?: string - readonly default?: string - readonly options?: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly custom?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "number" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "integer" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "boolean" - readonly default?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "multiselect" - readonly options: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly minItems?: number - readonly maxItems?: number - readonly custom?: boolean - readonly default?: ReadonlyArray - } - | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } - > + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + ), + ...Array< + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + >, + ] }["metadata"] readonly fields: { readonly id?: string | null readonly title: string readonly metadata?: { readonly [x: string]: JsonValue } - readonly fields: ReadonlyArray< - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly fields: readonly [ + ( + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "string" - readonly format?: "email" | "uri" | "date" | "date-time" - readonly minLength?: number - readonly maxLength?: number - readonly pattern?: string - readonly placeholder?: string - readonly default?: string - readonly options?: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly custom?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "number" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "integer" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "boolean" - readonly default?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "multiselect" - readonly options: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly minItems?: number - readonly maxItems?: number - readonly custom?: boolean - readonly default?: ReadonlyArray - } - | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } - > + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + ), + ...Array< + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + >, + ] }["fields"] } @@ -3295,97 +3853,190 @@ export type FormCreateOutput = { readonly sessionID: string readonly title: string readonly metadata?: { readonly [x: string]: JsonValue } - readonly fields: ReadonlyArray< - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly fields: readonly [ + ( + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "string" - readonly format?: "email" | "uri" | "date" | "date-time" - readonly minLength?: number - readonly maxLength?: number - readonly pattern?: string - readonly placeholder?: string - readonly default?: string - readonly options?: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly custom?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "number" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "integer" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "boolean" - readonly default?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "multiselect" - readonly options: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly minItems?: number - readonly maxItems?: number - readonly custom?: boolean - readonly default?: ReadonlyArray - } - | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } - > + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + ), + ...Array< + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + >, + ] } }["data"] @@ -3400,97 +4051,190 @@ export type FormGetOutput = { readonly sessionID: string readonly title: string readonly metadata?: { readonly [x: string]: JsonValue } - readonly fields: ReadonlyArray< - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly fields: readonly [ + ( + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "string" - readonly format?: "email" | "uri" | "date" | "date-time" - readonly minLength?: number - readonly maxLength?: number - readonly pattern?: string - readonly placeholder?: string - readonly default?: string - readonly options?: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly custom?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "number" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "integer" - readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" - readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" - readonly default?: number | "Infinity" | "-Infinity" | "NaN" - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "boolean" - readonly default?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean - }> - readonly type: "multiselect" - readonly options: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly minItems?: number - readonly maxItems?: number - readonly custom?: boolean - readonly default?: ReadonlyArray - } - | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } - > + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + ), + ...Array< + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "number" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "integer" + readonly minimum?: number | "Infinity" | "-Infinity" | "NaN" + readonly maximum?: number | "Infinity" | "-Infinity" | "NaN" + readonly default?: number | "Infinity" | "-Infinity" | "NaN" + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | "Infinity" | "-Infinity" | "NaN" | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + >, + ] } }["data"] @@ -5224,97 +5968,190 @@ export type EventSubscribeOutput = readonly sessionID: string readonly title: string readonly metadata?: { readonly [x: string]: unknown } - readonly fields: ReadonlyArray< - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly fields: readonly [ + ( + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | boolean - }> - readonly type: "string" - readonly format?: "email" | "uri" | "date" | "date-time" - readonly minLength?: number - readonly maxLength?: number - readonly pattern?: string - readonly placeholder?: string - readonly default?: string - readonly options?: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly custom?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | boolean - }> - readonly type: "number" - readonly minimum?: number - readonly maximum?: number - readonly default?: number - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | boolean - }> - readonly type: "integer" - readonly minimum?: number - readonly maximum?: number - readonly default?: number - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | boolean - }> - readonly type: "boolean" - readonly default?: boolean - } - | { - readonly key: string - readonly title?: string - readonly description?: string - readonly required?: boolean - readonly when?: ReadonlyArray<{ - readonly key: string - readonly op: "eq" | "neq" - readonly value: string | number | boolean - }> - readonly type: "multiselect" - readonly options: ReadonlyArray<{ - readonly value: string - readonly label: string + readonly title?: string readonly description?: string - }> - readonly minItems?: number - readonly maxItems?: number - readonly custom?: boolean - readonly default?: ReadonlyArray - } - | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } - > + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "number" + readonly minimum?: number + readonly maximum?: number + readonly default?: number + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "integer" + readonly minimum?: number + readonly maximum?: number + readonly default?: number + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + ), + ...Array< + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "string" + readonly format?: "email" | "uri" | "date" | "date-time" + readonly minLength?: number + readonly maxLength?: number + readonly pattern?: string + readonly placeholder?: string + readonly default?: string + readonly options?: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly custom?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "number" + readonly minimum?: number + readonly maximum?: number + readonly default?: number + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "integer" + readonly minimum?: number + readonly maximum?: number + readonly default?: number + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "boolean" + readonly default?: boolean + } + | { + readonly key: string + readonly title?: string + readonly description?: string + readonly required?: boolean + readonly when?: ReadonlyArray<{ + readonly key: string + readonly op: "eq" | "neq" + readonly value: string | number | boolean + }> + readonly type: "multiselect" + readonly options: ReadonlyArray<{ + readonly value: string + readonly label: string + readonly description?: string + }> + readonly minItems?: number + readonly maxItems?: number + readonly custom?: boolean + readonly default?: ReadonlyArray + } + | { readonly type: "link"; readonly url: string; readonly title?: string; readonly description?: string } + >, + ] } } } diff --git a/packages/core/src/form.ts b/packages/core/src/form.ts index 979b7b57097..6f7ab3f8b0a 100644 --- a/packages/core/src/form.ts +++ b/packages/core/src/form.ts @@ -16,6 +16,9 @@ export type Info = typeof Info.Type export const Field = Form.Field export type Field = Form.Field +export const Fields = Form.Fields +export type Fields = Form.Fields + export const When = Form.When export type When = Form.When @@ -259,6 +262,7 @@ function matches(when: Form.When, value: Form.Value | undefined) { // are closed. Rejecting these at creation surfaces authoring mistakes to the caller instead of // silently never matching. function validateFields(fields: ReadonlyArray) { + if (fields.length === 0) return "Form must have at least one field" const earlier = new Map() for (const field of fields) { if (field.type === "link") continue diff --git a/packages/core/src/mcp/index.ts b/packages/core/src/mcp/index.ts index 5cc9d8a24cb..370d6e6084c 100644 --- a/packages/core/src/mcp/index.ts +++ b/packages/core/src/mcp/index.ts @@ -324,14 +324,16 @@ export const layer = Layer.effect( ) } const params = input.params + const [field, ...fields] = Object.entries(params.requestedSchema.properties).map(([key, property]) => + toElicitationField(key, property, params.requestedSchema.required?.includes(key) === true), + ) + if (!field) return { action: "accept", content: {} } return yield* forms .ask({ sessionID: GLOBAL_ELICITATION_SESSION_ID, title: `${input.server} is requesting input`, metadata: { kind: "mcp-elicitation", server: input.server, message: params.message }, - fields: Object.entries(params.requestedSchema.properties).map(([key, property]) => - toElicitationField(key, property, params.requestedSchema.required?.includes(key) === true), - ), + fields: [field, ...fields], }) .pipe( Effect.raceFirst(waitForAbort(input.signal)), diff --git a/packages/core/src/tool/question.ts b/packages/core/src/tool/question.ts index 91a6d02afe0..ec2b1938a06 100644 --- a/packages/core/src/tool/question.ts +++ b/packages/core/src/tool/question.ts @@ -22,7 +22,7 @@ Usage notes: - If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label` export const Input = Schema.Struct({ - questions: Schema.Array(QuestionV2.Prompt).annotate({ description: "Questions to ask" }), + questions: Schema.NonEmptyArray(QuestionV2.Prompt).annotate({ description: "Questions to ask" }), }) export const Output = Schema.Struct({ @@ -86,20 +86,10 @@ export const Plugin = { kind: "question", tool: { messageID: context.assistantMessageID, callID: context.toolCallID }, }, - fields: input.questions.map( - (question, index): Form.Field => ({ - key: `q${index}`, - title: question.header, - description: question.question, - type: question.multiple === true ? "multiselect" : "string", - options: question.options.map((option) => ({ - value: option.label, - label: option.label, - description: option.description, - })), - custom: true, - }), - ), + fields: [ + toField(input.questions[0], 0), + ...input.questions.slice(1).map((question, index) => toField(question, index + 1)), + ], }) .pipe(Effect.orDie), ), @@ -121,3 +111,18 @@ export const Plugin = { .pipe(Effect.orDie) }), } + +function toField(question: QuestionV2.Prompt, index: number): Form.Field { + return { + key: `q${index}`, + title: question.header, + description: question.question, + type: question.multiple === true ? "multiselect" : "string", + options: question.options.map((option) => ({ + value: option.label, + label: option.label, + description: option.description, + })), + custom: true, + } +} diff --git a/packages/core/test/form.test.ts b/packages/core/test/form.test.ts index 4ee3c70b32b..0bce11000cf 100644 --- a/packages/core/test/form.test.ts +++ b/packages/core/test/form.test.ts @@ -231,7 +231,7 @@ describe("Form", () => { it.effect("rejects invalid when definitions at creation", () => Effect.gen(function* () { const service = yield* Form.Service - const flipCreate = (fields: ReadonlyArray) => + const flipCreate = (fields: Form.CreateInput["fields"]) => service.create({ sessionID: "global", title: "Invalid form", fields }).pipe(Effect.flip) expect( diff --git a/packages/core/test/mcp.test.ts b/packages/core/test/mcp.test.ts index 32a0f94d883..727247ba5c1 100644 --- a/packages/core/test/mcp.test.ts +++ b/packages/core/test/mcp.test.ts @@ -47,7 +47,7 @@ type ResourceTemplatePage = { nextCursor?: string } -function resourceServer(input: { resources?: boolean; listChanged?: boolean } = {}) { +function resourceServer(input: { resources?: boolean; listChanged?: boolean; emptyElicitation?: boolean } = {}) { return Effect.acquireRelease( Effect.promise(async () => { const state = { @@ -71,7 +71,26 @@ function resourceServer(input: { resources?: boolean; listChanged?: boolean } = }, }, ) - protocol.setRequestHandler(ListToolsRequestSchema, () => Promise.resolve({ tools: [] })) + protocol.setRequestHandler(ListToolsRequestSchema, () => + Promise.resolve({ + tools: input.emptyElicitation + ? [{ name: "empty-elicitation", inputSchema: { type: "object" as const, properties: {} } }] + : [], + }), + ) + if (input.emptyElicitation) { + protocol.setRequestHandler(CallToolRequestSchema, async () => { + const result = await protocol.elicitInput({ + mode: "form", + message: "Confirm", + requestedSchema: { type: "object", properties: {} }, + }) + return { + content: [{ type: "text", text: JSON.stringify(result) }], + structuredContent: result, + } + }) + } if (input.resources !== false) { protocol.setRequestHandler(ListResourcesRequestSchema, (request) => { state.resourceLists += 1 @@ -140,7 +159,9 @@ function resourceMcpLayer(url: string) { data, } as EventV2.Payload), }), - Layer.mock(Form.Service, {}), + Layer.mock(Form.Service, { + ask: () => Effect.die("Empty MCP elicitation must not create a form"), + }), Layer.mock(Integration.Service, { connection: { active: unusedIntegration, @@ -490,6 +511,22 @@ test("skips MCP resource requests when the capability is absent", async () => { ) }) +test("accepts empty MCP elicitations without creating forms", async () => { + await Effect.runPromise( + Effect.scoped( + Effect.gen(function* () { + const server = yield* resourceServer({ resources: false, emptyElicitation: true }) + const result = yield* Effect.gen(function* () { + const service = yield* MCP.Service + return yield* service.callTool({ server: "resources", name: "empty-elicitation" }) + }).pipe(Effect.provide(resourceMcpLayer(server.url))) + + expect(result.structured).toEqual({ action: "accept", content: {} }) + }), + ), + ) +}) + test("loads and reads MCP resources", async () => { await Effect.runPromise( Effect.scoped( diff --git a/packages/core/test/tool-question.test.ts b/packages/core/test/tool-question.test.ts index a763ac59e41..82b58fc8a82 100644 --- a/packages/core/test/tool-question.test.ts +++ b/packages/core/test/tool-question.test.ts @@ -18,6 +18,15 @@ let captured: Form.CreateInput | undefined let reject = false let deny = false const capturedInput = () => captured +const questionInput = { + questions: [ + { + question: "Continue?", + header: "Continue", + options: [{ label: "Yes", description: "Continue" }], + }, + ], +} const permission = Layer.succeed( PermissionV2.Service, PermissionV2.Service.of({ @@ -90,7 +99,7 @@ describe("QuestionTool", () => { yield* settleTool(registry, { sessionID, ...toolIdentity, - call: { type: "tool-call", id: "call-question-denied", name: "question", input: { questions: [] } }, + call: { type: "tool-call", id: "call-question-denied", name: "question", input: questionInput }, }), ).toEqual({ result: { type: "error", value: "Permission denied: question" }, @@ -198,13 +207,22 @@ describe("QuestionTool", () => { yield* executeTool(registryService, { sessionID, ...toolIdentity, - call: { type: "tool-call", id: "call-question", name: "question", input: { questions: [] } }, + call: { type: "tool-call", id: "call-question", name: "question", input: questionInput }, }) expect(capturedInput()).toEqual({ sessionID, title: "Questions", metadata: { kind: "question", tool: { messageID: toolIdentity.assistantMessageID, callID: "call-question" } }, - fields: [], + fields: [ + { + key: "q0", + title: "Continue", + description: "Continue?", + options: [{ value: "Yes", label: "Yes", description: "Continue" }], + custom: true, + type: "string", + }, + ], }) }), ) @@ -218,7 +236,7 @@ describe("QuestionTool", () => { const fiber = yield* executeTool(registryService, { sessionID, ...toolIdentity, - call: { type: "tool-call", id: "call-question", name: "question", input: { questions: [] } }, + call: { type: "tool-call", id: "call-question", name: "question", input: questionInput }, }).pipe(Effect.forkScoped) const exit = yield* Fiber.await(fiber) diff --git a/packages/schema/src/form.ts b/packages/schema/src/form.ts index 1fd6ad4466e..caae0c0c043 100644 --- a/packages/schema/src/form.ts +++ b/packages/schema/src/form.ts @@ -112,6 +112,9 @@ export const Field = Schema.Union([ ]).pipe(Schema.toTaggedUnion("type"), Schema.annotate({ identifier: "Form.Field" })) export type Field = StringField | NumberField | IntegerField | BooleanField | MultiselectField | LinkField +export const Fields = Schema.NonEmptyArray(Field).annotate({ identifier: "Form.Fields" }) +export type Fields = typeof Fields.Type + const InfoBase = { id: ID, // This should be typed as SessionID. It is a plain string only because MCP elicitation @@ -125,7 +128,7 @@ const InfoBase = { export const Info = Schema.Struct({ ...InfoBase, - fields: Schema.Array(Field), + fields: Fields, }).annotate({ identifier: "Form.Info" }) export interface Info extends Schema.Schema.Type {} diff --git a/packages/schema/test/contract-hygiene.test.ts b/packages/schema/test/contract-hygiene.test.ts index 6b3daaf2618..96d9afe0ebe 100644 --- a/packages/schema/test/contract-hygiene.test.ts +++ b/packages/schema/test/contract-hygiene.test.ts @@ -48,6 +48,25 @@ describe("contract hygiene", () => { ).toEqual({ text: "completed" }) }) + test("forms require at least one field", () => { + expect(() => + Schema.decodeUnknownSync(Form.Info)({ + id: Form.ID.create(), + sessionID: "global", + title: "Empty form", + fields: [], + }), + ).toThrow() + expect( + Schema.decodeUnknownSync(Form.Info)({ + id: Form.ID.create(), + sessionID: "global", + title: "Link form", + fields: [{ type: "link", url: "https://example.com" }], + }).fields, + ).toHaveLength(1) + }) + test("model defaults and provider overlays preserve public invariants", () => { const id = Model.ID.make("model") expect(Model.Info.empty(Provider.ID.make("provider"), id)).toMatchObject({ modelID: id, variants: [] }) @@ -71,6 +90,7 @@ describe("contract hygiene", () => { Agent.Color, FileSystem.Submatch, Form.Field, + Form.Fields, Form.Info, Form.LinkField, Mcp.Resource, diff --git a/packages/tui/test/cli/cmd/tui/notifications.test.ts b/packages/tui/test/cli/cmd/tui/notifications.test.ts index 2a1c7e09e8e..7f3bd29d7f1 100644 --- a/packages/tui/test/cli/cmd/tui/notifications.test.ts +++ b/packages/tui/test/cli/cmd/tui/notifications.test.ts @@ -78,7 +78,7 @@ function form(id: string, sessionID = "session"): Extract boolean, timeout = 2000) { const start = Date.now() while (!fn()) { @@ -1510,7 +1512,7 @@ test("adds, dismisses, and refreshes form requests", async () => { const calls = createFetch((url) => { if (url.pathname !== "/api/session/ses_1/form") return return json({ - data: [{ id: "frm_remote", sessionID: "ses_1", title: "Input requested", fields: [] }], + data: [{ id: "frm_remote", sessionID: "ses_1", title: "Input requested", fields: formFields }], }) }, events) let data!: ReturnType @@ -1540,13 +1542,13 @@ test("adds, dismisses, and refreshes form requests", async () => { id: "evt_form_created_1", created: 0, type: "form.created", - data: { form: { id: "frm_1", sessionID: "ses_1", title: "Input requested", fields: [] } }, + data: { form: { id: "frm_1", sessionID: "ses_1", title: "Input requested", fields: formFields } }, }) emitEvent(events, { id: "evt_form_created_duplicate", created: 1, type: "form.created", - data: { form: { id: "frm_1", sessionID: "ses_1", title: "Input requested", fields: [] } }, + data: { form: { id: "frm_1", sessionID: "ses_1", title: "Input requested", fields: formFields } }, }) await wait(() => data.session.form.list("ses_1")?.length === 1) @@ -1562,7 +1564,7 @@ test("adds, dismisses, and refreshes form requests", async () => { id: "evt_form_created_2", created: 3, type: "form.created", - data: { form: { id: "frm_2", sessionID: "ses_1", title: "Input requested", fields: [] } }, + data: { form: { id: "frm_2", sessionID: "ses_1", title: "Input requested", fields: formFields } }, }) emitEvent(events, { id: "evt_form_cancelled_2", @@ -1612,7 +1614,7 @@ test("tracks global forms by location", async () => { location: other, type: "form.created", data: { - form: { id: "frm_other", sessionID: "global", title: "Input requested", fields: [] }, + form: { id: "frm_other", sessionID: "global", title: "Input requested", fields: formFields }, }, }) @@ -1625,7 +1627,7 @@ test("tracks global forms by location", async () => { location: { directory }, type: "form.created", data: { - form: { id: "frm_default", sessionID: "global", title: "Input requested", fields: [] }, + form: { id: "frm_default", sessionID: "global", title: "Input requested", fields: formFields }, }, }) await wait(() => data.session.form.list("global", { directory })?.length === 1) @@ -1664,7 +1666,7 @@ test("refreshes global forms for the requested location", async () => { id: requestedDirectory === other.directory ? "frm_other" : "frm_default", sessionID: "global", title: "Input requested", - fields: [], + fields: formFields, }, ], }) @@ -1742,7 +1744,7 @@ test("refreshes global forms once per loaded location after reconnect", async () id: `frm_${requestedDirectory === other.directory ? "other" : "default"}_${count}`, sessionID: "global", title: "Input requested", - fields: [], + fields: formFields, }, ], }) @@ -1801,7 +1803,7 @@ test("refreshes global forms once per loaded location after reconnect", async () test("reconciles all pending form requests when the event stream reconnects", async () => { const events = createEventStream() let requests = [ - { id: "frm_old", sessionID: "ses_old", title: "Input requested", fields: [] }, + { id: "frm_old", sessionID: "ses_old", title: "Input requested", fields: formFields }, { id: "frm_keep", sessionID: "ses_keep", @@ -1838,7 +1840,7 @@ test("reconciles all pending form requests when the event stream reconnects", as await wait(() => data.session.form.list("ses_old")?.[0]?.id === "frm_old") expect(data.session.form.list("ses_keep")?.[0]?.id).toBe("frm_keep") - requests = [{ id: "frm_new", sessionID: "ses_new", title: "Input requested", fields: [] }] + requests = [{ id: "frm_new", sessionID: "ses_new", title: "Input requested", fields: formFields }] events.disconnect() await wait(() => calls === 2 && data.session.form.list("ses_new")?.[0]?.id === "frm_new")