@absolutejs/ai 0.0.34 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ai/index.js CHANGED
@@ -3680,18 +3680,30 @@ var createUiCards = (definitions) => {
3680
3680
  };
3681
3681
  // src/ai/ui/catalog.ts
3682
3682
  var CHART_TYPES = ["bar", "line", "donut"];
3683
+ var FORM_FIELD_TYPES = [
3684
+ "text",
3685
+ "textarea",
3686
+ "number",
3687
+ "select",
3688
+ "date",
3689
+ "checkbox"
3690
+ ];
3683
3691
  var CHART_MAX_SERIES = 8;
3684
3692
  var CHART_MAX_POINTS = 24;
3685
3693
  var TABLE_MAX_COLUMNS = 8;
3686
3694
  var TABLE_MAX_ROWS = 30;
3687
3695
  var STAT_TILES_MAX = 6;
3688
3696
  var UI_ACTIONS_MAX = 3;
3697
+ var FORM_MAX_FIELDS = 8;
3698
+ var FORM_SELECT_MAX_OPTIONS = 12;
3689
3699
  var LABEL_MAX_CHARS = 80;
3690
3700
  var TITLE_MAX_CHARS = 120;
3691
3701
  var CELL_MAX_CHARS = 160;
3692
3702
  var UNIT_MAX_CHARS = 8;
3693
3703
  var ACTION_LABEL_MAX_CHARS = 40;
3704
+ var DESCRIPTION_MAX_CHARS = 280;
3694
3705
  var ACTION_TOOL_PATTERN = /^[a-z][a-z0-9_]{1,63}$/;
3706
+ var FIELD_NAME_PATTERN = /^[a-z][a-zA-Z0-9_]{0,63}$/;
3695
3707
  var isRecord6 = (value) => typeof value === "object" && value !== null;
3696
3708
  var cleanString = (value, maxChars) => typeof value === "string" && value.trim().length > 0 ? value.trim().slice(0, maxChars) : null;
3697
3709
  var cleanStringArray = (value, maxItems, maxChars) => {
@@ -3844,6 +3856,58 @@ var parseStatTilesSpec = (input) => {
3844
3856
  spec.actions = actions;
3845
3857
  return spec;
3846
3858
  };
3859
+ var parseFormField = (raw) => {
3860
+ if (!isRecord6(raw))
3861
+ return null;
3862
+ const name = typeof raw.name === "string" && FIELD_NAME_PATTERN.test(raw.name) ? raw.name : null;
3863
+ const label = cleanString(raw.label, LABEL_MAX_CHARS);
3864
+ const type = FORM_FIELD_TYPES.find((entry) => entry === raw.type);
3865
+ if (!name || !label || !type)
3866
+ return null;
3867
+ const field = { label, name, type };
3868
+ const placeholder = cleanString(raw.placeholder, LABEL_MAX_CHARS);
3869
+ if (placeholder)
3870
+ field.placeholder = placeholder;
3871
+ if (raw.required === true)
3872
+ field.required = true;
3873
+ const value = cleanString(raw.value, CELL_MAX_CHARS);
3874
+ if (value)
3875
+ field.value = value;
3876
+ const options = cleanStringArray(raw.options, FORM_SELECT_MAX_OPTIONS, LABEL_MAX_CHARS);
3877
+ if (options)
3878
+ field.options = options;
3879
+ if (type === "select" && !options)
3880
+ return null;
3881
+ return field;
3882
+ };
3883
+ var parseFormFields = (value) => {
3884
+ if (!Array.isArray(value) || value.length === 0)
3885
+ return null;
3886
+ const fields = [];
3887
+ const seen = new Set;
3888
+ for (const raw of value.slice(0, FORM_MAX_FIELDS)) {
3889
+ const field = parseFormField(raw);
3890
+ if (!field || seen.has(field.name))
3891
+ return null;
3892
+ seen.add(field.name);
3893
+ fields.push(field);
3894
+ }
3895
+ return fields;
3896
+ };
3897
+ var parseFormSpec = (input) => {
3898
+ if (!isRecord6(input))
3899
+ return null;
3900
+ const title = cleanString(input.title, TITLE_MAX_CHARS);
3901
+ const fields = parseFormFields(input.fields);
3902
+ const [submit] = parseUiActions([input.submit]) ?? [];
3903
+ if (!title || !fields || !submit)
3904
+ return null;
3905
+ const spec = { fields, submit, title };
3906
+ const description = cleanString(input.description, DESCRIPTION_MAX_CHARS);
3907
+ if (description)
3908
+ spec.description = description;
3909
+ return spec;
3910
+ };
3847
3911
  var SERIES_SCHEMA = {
3848
3912
  properties: {
3849
3913
  name: { description: "Series name (shown in the legend)", type: "string" },
@@ -3946,7 +4010,72 @@ var statTilesCard = {
3946
4010
  name: "render_stat_tiles",
3947
4011
  parse: parseStatTilesSpec
3948
4012
  };
3949
- var BUILTIN_UI_CARDS = [chartCard, tableCard, statTilesCard];
4013
+ var formCard = {
4014
+ ack: "(form rendered inline \u2014 the member fills and submits it, which runs the bound tool with their values. Do NOT re-ask for these values in text; wait for the submission)",
4015
+ description: "Render an inline form when you need SEVERAL structured inputs from the member before running a tool (task details, scheduling constraints, outreach parameters) \u2014 one form beats asking field-by-field in prose. Bind submit to one of YOUR tools with any values you already know pre-filled in submit.input; on submit the member's field values are merged into submit.input under each field's name and the tool runs exactly like a clicked action button. Field names must therefore be the tool's actual input property names. Never use it for values you could look up yourself.",
4016
+ inputSchema: {
4017
+ properties: {
4018
+ description: {
4019
+ description: "Optional one-line helper text under the title",
4020
+ type: "string"
4021
+ },
4022
+ fields: {
4023
+ description: "The inputs to collect (max 8). Each field's name must be a real input property of the submit tool.",
4024
+ items: {
4025
+ properties: {
4026
+ label: { description: "Human label for the field", type: "string" },
4027
+ name: {
4028
+ description: 'Tool-input property name the value submits under, e.g. "title"',
4029
+ type: "string"
4030
+ },
4031
+ options: {
4032
+ description: "Choices \u2014 required for select fields (max 12)",
4033
+ items: { type: "string" },
4034
+ type: "array"
4035
+ },
4036
+ placeholder: { type: "string" },
4037
+ required: { type: "boolean" },
4038
+ type: { enum: [...FORM_FIELD_TYPES], type: "string" },
4039
+ value: {
4040
+ description: 'Prefill value (checkbox: "true"/"false")',
4041
+ type: "string"
4042
+ }
4043
+ },
4044
+ required: ["name", "label", "type"],
4045
+ type: "object"
4046
+ },
4047
+ type: "array"
4048
+ },
4049
+ submit: {
4050
+ description: "The submit binding: label for the button, the tool to run, and any input values you already resolved (real ids, never placeholders)",
4051
+ properties: {
4052
+ input: {
4053
+ description: "Pre-resolved input values; field values are merged in on top under their field names",
4054
+ type: "object"
4055
+ },
4056
+ label: {
4057
+ description: 'Button label, e.g. "Create task"',
4058
+ type: "string"
4059
+ },
4060
+ tool: { description: "The tool name to invoke", type: "string" }
4061
+ },
4062
+ required: ["label", "tool", "input"],
4063
+ type: "object"
4064
+ },
4065
+ title: { description: "Short form title", type: "string" }
4066
+ },
4067
+ required: ["title", "fields", "submit"],
4068
+ type: "object"
4069
+ },
4070
+ name: "render_form",
4071
+ parse: parseFormSpec
4072
+ };
4073
+ var BUILTIN_UI_CARDS = [
4074
+ chartCard,
4075
+ tableCard,
4076
+ statTilesCard,
4077
+ formCard
4078
+ ];
3950
4079
  // src/ai/ui/svg.ts
3951
4080
  var LIGHT_UI_THEME = {
3952
4081
  grid: "#e4e4e0",
@@ -5099,6 +5228,7 @@ export {
5099
5228
  parseUiActions,
5100
5229
  parseTableSpec,
5101
5230
  parseStatTilesSpec,
5231
+ parseFormSpec,
5102
5232
  parseChartSpec,
5103
5233
  parseAIMessage,
5104
5234
  openaiResponses,
@@ -5115,6 +5245,7 @@ export {
5115
5245
  generateAIWithTools,
5116
5246
  generateAI,
5117
5247
  gemini,
5248
+ formCard,
5118
5249
  fetchProviderApiStatus,
5119
5250
  deepseek,
5120
5251
  createUiCards,
@@ -5136,6 +5267,9 @@ export {
5136
5267
  ProviderError,
5137
5268
  PROVIDER_STATUS_PAGES,
5138
5269
  LIGHT_UI_THEME,
5270
+ FORM_SELECT_MAX_OPTIONS,
5271
+ FORM_MAX_FIELDS,
5272
+ FORM_FIELD_TYPES,
5139
5273
  DARK_UI_THEME,
5140
5274
  CHART_TYPES,
5141
5275
  CHART_MAX_SERIES,
@@ -5143,5 +5277,5 @@ export {
5143
5277
  BUILTIN_UI_CARDS
5144
5278
  };
5145
5279
 
5146
- //# debugId=0E766AE845A0759F64756E2164756E21
5280
+ //# debugId=975418BCAB9B044864756E2164756E21
5147
5281
  //# sourceMappingURL=index.js.map