@absolutejs/ai 0.0.33 → 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 +189 -3
- package/dist/ai/index.js.map +3 -3
- package/dist/ai/ui/index.js +189 -3
- package/dist/ai/ui/index.js.map +3 -3
- package/dist/src/ai/ui/catalog.d.ts +57 -1
- package/dist/src/ai/ui/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/ai/index.js
CHANGED
|
@@ -3680,15 +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;
|
|
3696
|
+
var UI_ACTIONS_MAX = 3;
|
|
3697
|
+
var FORM_MAX_FIELDS = 8;
|
|
3698
|
+
var FORM_SELECT_MAX_OPTIONS = 12;
|
|
3688
3699
|
var LABEL_MAX_CHARS = 80;
|
|
3689
3700
|
var TITLE_MAX_CHARS = 120;
|
|
3690
3701
|
var CELL_MAX_CHARS = 160;
|
|
3691
3702
|
var UNIT_MAX_CHARS = 8;
|
|
3703
|
+
var ACTION_LABEL_MAX_CHARS = 40;
|
|
3704
|
+
var DESCRIPTION_MAX_CHARS = 280;
|
|
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}$/;
|
|
3692
3707
|
var isRecord6 = (value) => typeof value === "object" && value !== null;
|
|
3693
3708
|
var cleanString = (value, maxChars) => typeof value === "string" && value.trim().length > 0 ? value.trim().slice(0, maxChars) : null;
|
|
3694
3709
|
var cleanStringArray = (value, maxItems, maxChars) => {
|
|
@@ -3712,6 +3727,40 @@ var cleanNumberArray = (value, maxItems) => {
|
|
|
3712
3727
|
}
|
|
3713
3728
|
return cleaned;
|
|
3714
3729
|
};
|
|
3730
|
+
var parseUiActions = (value) => {
|
|
3731
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
3732
|
+
return;
|
|
3733
|
+
const actions = [];
|
|
3734
|
+
for (const raw of value.slice(0, UI_ACTIONS_MAX)) {
|
|
3735
|
+
if (!isRecord6(raw))
|
|
3736
|
+
continue;
|
|
3737
|
+
const label = cleanString(raw.label, ACTION_LABEL_MAX_CHARS);
|
|
3738
|
+
const tool = typeof raw.tool === "string" && ACTION_TOOL_PATTERN.test(raw.tool) ? raw.tool : null;
|
|
3739
|
+
if (!label || !tool || !isRecord6(raw.input))
|
|
3740
|
+
continue;
|
|
3741
|
+
actions.push({ input: raw.input, label, tool });
|
|
3742
|
+
}
|
|
3743
|
+
return actions.length > 0 ? actions : undefined;
|
|
3744
|
+
};
|
|
3745
|
+
var ACTIONS_SCHEMA = {
|
|
3746
|
+
description: "Optional action buttons under the card (max 3): each invokes one of YOUR tools with a fully-resolved input when the member clicks it. Use real ids you looked up \u2014 never placeholders. Approval-gated tools queue their normal approval card.",
|
|
3747
|
+
items: {
|
|
3748
|
+
properties: {
|
|
3749
|
+
input: {
|
|
3750
|
+
description: "The exact tool input to send on click",
|
|
3751
|
+
type: "object"
|
|
3752
|
+
},
|
|
3753
|
+
label: {
|
|
3754
|
+
description: 'Short button label, e.g. "Create follow-up task"',
|
|
3755
|
+
type: "string"
|
|
3756
|
+
},
|
|
3757
|
+
tool: { description: "The tool name to invoke", type: "string" }
|
|
3758
|
+
},
|
|
3759
|
+
required: ["label", "tool", "input"],
|
|
3760
|
+
type: "object"
|
|
3761
|
+
},
|
|
3762
|
+
type: "array"
|
|
3763
|
+
};
|
|
3715
3764
|
var parseChartSpec = (input) => {
|
|
3716
3765
|
if (!isRecord6(input))
|
|
3717
3766
|
return null;
|
|
@@ -3748,6 +3797,9 @@ var parseChartSpec = (input) => {
|
|
|
3748
3797
|
spec.unitPrefix = unitPrefix;
|
|
3749
3798
|
if (unitSuffix)
|
|
3750
3799
|
spec.unitSuffix = unitSuffix;
|
|
3800
|
+
const actions = parseUiActions(input.actions);
|
|
3801
|
+
if (actions)
|
|
3802
|
+
spec.actions = actions;
|
|
3751
3803
|
return spec;
|
|
3752
3804
|
};
|
|
3753
3805
|
var parseTableSpec = (input) => {
|
|
@@ -3771,6 +3823,9 @@ var parseTableSpec = (input) => {
|
|
|
3771
3823
|
const title = cleanString(input.title, TITLE_MAX_CHARS);
|
|
3772
3824
|
if (title)
|
|
3773
3825
|
spec.title = title;
|
|
3826
|
+
const actions = parseUiActions(input.actions);
|
|
3827
|
+
if (actions)
|
|
3828
|
+
spec.actions = actions;
|
|
3774
3829
|
return spec;
|
|
3775
3830
|
};
|
|
3776
3831
|
var parseStatTilesSpec = (input) => {
|
|
@@ -3795,7 +3850,63 @@ var parseStatTilesSpec = (input) => {
|
|
|
3795
3850
|
}
|
|
3796
3851
|
tiles.push(tile);
|
|
3797
3852
|
}
|
|
3798
|
-
|
|
3853
|
+
const spec = { tiles };
|
|
3854
|
+
const actions = parseUiActions(input.actions);
|
|
3855
|
+
if (actions)
|
|
3856
|
+
spec.actions = actions;
|
|
3857
|
+
return spec;
|
|
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;
|
|
3799
3910
|
};
|
|
3800
3911
|
var SERIES_SCHEMA = {
|
|
3801
3912
|
properties: {
|
|
@@ -3814,6 +3925,7 @@ var chartCard = {
|
|
|
3814
3925
|
description: "Render a real chart inline in the chat from data you have (tool results, the conversation). Use whenever numbers COMPARE or TREND: revenue by partner (bar), pipeline over time (line), share of a whole (donut). Rules: bar/line take up to 8 series aligned to the same labels; donut takes exactly ONE series of non-negative values (one slice per label). Prefer a chart over a wall of numbers, but never invent data for it.",
|
|
3815
3926
|
inputSchema: {
|
|
3816
3927
|
properties: {
|
|
3928
|
+
actions: ACTIONS_SCHEMA,
|
|
3817
3929
|
labels: {
|
|
3818
3930
|
description: "Category labels \u2014 x-axis for bar/line, slice names for donut (max 24)",
|
|
3819
3931
|
items: { type: "string" },
|
|
@@ -3846,6 +3958,7 @@ var tableCard = {
|
|
|
3846
3958
|
description: "Render a compact data table inline in the chat (max 8 columns \xD7 30 rows). Use for structured comparisons the member will scan \u2014 matches side by side, deal terms, task lists with dates. All cells are strings; format numbers yourself.",
|
|
3847
3959
|
inputSchema: {
|
|
3848
3960
|
properties: {
|
|
3961
|
+
actions: ACTIONS_SCHEMA,
|
|
3849
3962
|
columns: {
|
|
3850
3963
|
description: "Column headers (max 8)",
|
|
3851
3964
|
items: { type: "string" },
|
|
@@ -3869,6 +3982,7 @@ var statTilesCard = {
|
|
|
3869
3982
|
description: "Render a row of headline stat tiles inline in the chat (max 6): a label, a big value, and an optional delta with direction. Use for the 2-4 numbers that ARE the answer \u2014 total attributed revenue, pipeline value, credits remaining \u2014 instead of burying them in prose.",
|
|
3870
3983
|
inputSchema: {
|
|
3871
3984
|
properties: {
|
|
3985
|
+
actions: ACTIONS_SCHEMA,
|
|
3872
3986
|
tiles: {
|
|
3873
3987
|
description: "The tiles (max 6)",
|
|
3874
3988
|
items: {
|
|
@@ -3896,7 +4010,72 @@ var statTilesCard = {
|
|
|
3896
4010
|
name: "render_stat_tiles",
|
|
3897
4011
|
parse: parseStatTilesSpec
|
|
3898
4012
|
};
|
|
3899
|
-
var
|
|
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
|
+
];
|
|
3900
4079
|
// src/ai/ui/svg.ts
|
|
3901
4080
|
var LIGHT_UI_THEME = {
|
|
3902
4081
|
grid: "#e4e4e0",
|
|
@@ -5046,8 +5225,10 @@ export {
|
|
|
5046
5225
|
resolveRenderers,
|
|
5047
5226
|
renderChartSvg,
|
|
5048
5227
|
providerStatusPage,
|
|
5228
|
+
parseUiActions,
|
|
5049
5229
|
parseTableSpec,
|
|
5050
5230
|
parseStatTilesSpec,
|
|
5231
|
+
parseFormSpec,
|
|
5051
5232
|
parseChartSpec,
|
|
5052
5233
|
parseAIMessage,
|
|
5053
5234
|
openaiResponses,
|
|
@@ -5064,6 +5245,7 @@ export {
|
|
|
5064
5245
|
generateAIWithTools,
|
|
5065
5246
|
generateAI,
|
|
5066
5247
|
gemini,
|
|
5248
|
+
formCard,
|
|
5067
5249
|
fetchProviderApiStatus,
|
|
5068
5250
|
deepseek,
|
|
5069
5251
|
createUiCards,
|
|
@@ -5078,12 +5260,16 @@ export {
|
|
|
5078
5260
|
anthropic,
|
|
5079
5261
|
alibaba,
|
|
5080
5262
|
aiChat,
|
|
5263
|
+
UI_ACTIONS_MAX,
|
|
5081
5264
|
TABLE_MAX_ROWS,
|
|
5082
5265
|
TABLE_MAX_COLUMNS,
|
|
5083
5266
|
STAT_TILES_MAX,
|
|
5084
5267
|
ProviderError,
|
|
5085
5268
|
PROVIDER_STATUS_PAGES,
|
|
5086
5269
|
LIGHT_UI_THEME,
|
|
5270
|
+
FORM_SELECT_MAX_OPTIONS,
|
|
5271
|
+
FORM_MAX_FIELDS,
|
|
5272
|
+
FORM_FIELD_TYPES,
|
|
5087
5273
|
DARK_UI_THEME,
|
|
5088
5274
|
CHART_TYPES,
|
|
5089
5275
|
CHART_MAX_SERIES,
|
|
@@ -5091,5 +5277,5 @@ export {
|
|
|
5091
5277
|
BUILTIN_UI_CARDS
|
|
5092
5278
|
};
|
|
5093
5279
|
|
|
5094
|
-
//# debugId=
|
|
5280
|
+
//# debugId=975418BCAB9B044864756E2164756E21
|
|
5095
5281
|
//# sourceMappingURL=index.js.map
|