@absolutejs/ai 0.0.40 → 0.0.42
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/README.md +8 -0
- package/dist/ai/index.js +638 -3
- package/dist/ai/index.js.map +6 -5
- package/dist/ai/providers/anthropic.js +3 -2
- package/dist/ai/providers/anthropic.js.map +3 -3
- package/dist/ai/ui/index.js +474 -2
- package/dist/ai/ui/index.js.map +3 -3
- package/dist/src/ai/index.d.ts +2 -0
- package/dist/src/ai/providerProxy.d.ts +16 -0
- package/dist/src/ai/ui/catalog.d.ts +173 -4
- package/dist/src/ai/ui/index.d.ts +7 -4
- package/dist/types/anthropic.d.ts +2 -0
- package/package.json +1 -1
package/dist/ai/index.js
CHANGED
|
@@ -1956,7 +1956,8 @@ async function* parseSSEStream4(body, signal) {
|
|
|
1956
1956
|
var fetchAndStream = async function* (baseUrl, config2, params, configuredMax, promptCaching) {
|
|
1957
1957
|
const body = buildRequestBody4(params, configuredMax, promptCaching);
|
|
1958
1958
|
const target = `${baseUrl}/v1/messages`;
|
|
1959
|
-
const
|
|
1959
|
+
const fetchImpl = config2.fetch ?? fetch;
|
|
1960
|
+
const response = await fetchImpl(target, {
|
|
1960
1961
|
...h2IfHttps4(target),
|
|
1961
1962
|
body: JSON.stringify(body),
|
|
1962
1963
|
headers: {
|
|
@@ -3654,6 +3655,165 @@ var streamAIWithTools = async function* (options) {
|
|
|
3654
3655
|
yield { ...summary, type: "done" };
|
|
3655
3656
|
return summary;
|
|
3656
3657
|
};
|
|
3658
|
+
// src/ai/providerProxy.ts
|
|
3659
|
+
var DEFAULT_HEARTBEAT_MS2 = 5000;
|
|
3660
|
+
var encoder = new TextEncoder;
|
|
3661
|
+
var wireParams = (params) => ({
|
|
3662
|
+
...params.cacheSystemPrompt === undefined ? {} : { cacheSystemPrompt: params.cacheSystemPrompt },
|
|
3663
|
+
...params.frequencyPenalty === undefined ? {} : { frequencyPenalty: params.frequencyPenalty },
|
|
3664
|
+
...params.maxTokens === undefined ? {} : { maxTokens: params.maxTokens },
|
|
3665
|
+
messages: params.messages,
|
|
3666
|
+
model: params.model,
|
|
3667
|
+
...params.parallelToolCalls === undefined ? {} : { parallelToolCalls: params.parallelToolCalls },
|
|
3668
|
+
...params.presencePenalty === undefined ? {} : { presencePenalty: params.presencePenalty },
|
|
3669
|
+
...params.promptCaching === undefined ? {} : { promptCaching: params.promptCaching },
|
|
3670
|
+
...params.reasoning === undefined ? {} : { reasoning: params.reasoning },
|
|
3671
|
+
...params.responseFormat === undefined ? {} : { responseFormat: params.responseFormat },
|
|
3672
|
+
...params.seed === undefined ? {} : { seed: params.seed },
|
|
3673
|
+
...params.stopSequences === undefined ? {} : { stopSequences: params.stopSequences },
|
|
3674
|
+
...params.systemPrompt === undefined ? {} : { systemPrompt: params.systemPrompt },
|
|
3675
|
+
...params.temperature === undefined ? {} : { temperature: params.temperature },
|
|
3676
|
+
...params.toolChoice === undefined ? {} : { toolChoice: params.toolChoice },
|
|
3677
|
+
...params.tools === undefined ? {} : { tools: params.tools },
|
|
3678
|
+
...params.topP === undefined ? {} : { topP: params.topP }
|
|
3679
|
+
});
|
|
3680
|
+
var parseProviderProxyParams = (value) => {
|
|
3681
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
3682
|
+
return null;
|
|
3683
|
+
const input = value;
|
|
3684
|
+
if (typeof input.model !== "string" || input.model.trim() === "")
|
|
3685
|
+
return null;
|
|
3686
|
+
if (!Array.isArray(input.messages))
|
|
3687
|
+
return null;
|
|
3688
|
+
return wireParams(input);
|
|
3689
|
+
};
|
|
3690
|
+
var encodeEvent = (event, data) => encoder.encode(`event: ${event}
|
|
3691
|
+
data: ${JSON.stringify(data)}
|
|
3692
|
+
|
|
3693
|
+
`);
|
|
3694
|
+
var errorPayload = (error) => {
|
|
3695
|
+
const providerError = error instanceof ProviderError ? error : ProviderError.from(error, "remote");
|
|
3696
|
+
return {
|
|
3697
|
+
message: providerError.message,
|
|
3698
|
+
provider: providerError.provider,
|
|
3699
|
+
retryable: providerError.retryable,
|
|
3700
|
+
status: providerError.status,
|
|
3701
|
+
type: providerError.type
|
|
3702
|
+
};
|
|
3703
|
+
};
|
|
3704
|
+
var streamResponseBody = (iterator, heartbeatMs, onError) => new ReadableStream({
|
|
3705
|
+
async start(controller) {
|
|
3706
|
+
try {
|
|
3707
|
+
for (;; ) {
|
|
3708
|
+
const pending = iterator.next();
|
|
3709
|
+
let next;
|
|
3710
|
+
for (;; ) {
|
|
3711
|
+
let timer;
|
|
3712
|
+
const heartbeat = new Promise((resolve) => {
|
|
3713
|
+
timer = setTimeout(() => resolve("heartbeat"), heartbeatMs);
|
|
3714
|
+
});
|
|
3715
|
+
const winner = heartbeatMs > 0 ? await Promise.race([pending, heartbeat]) : await pending;
|
|
3716
|
+
if (timer)
|
|
3717
|
+
clearTimeout(timer);
|
|
3718
|
+
if (winner === "heartbeat") {
|
|
3719
|
+
controller.enqueue(encoder.encode(`: ping
|
|
3720
|
+
|
|
3721
|
+
`));
|
|
3722
|
+
continue;
|
|
3723
|
+
}
|
|
3724
|
+
next = winner;
|
|
3725
|
+
break;
|
|
3726
|
+
}
|
|
3727
|
+
if (next.done)
|
|
3728
|
+
break;
|
|
3729
|
+
controller.enqueue(encodeEvent("chunk", next.value));
|
|
3730
|
+
}
|
|
3731
|
+
} catch (error) {
|
|
3732
|
+
await onError?.(error);
|
|
3733
|
+
controller.enqueue(encodeEvent("error", errorPayload(error)));
|
|
3734
|
+
} finally {
|
|
3735
|
+
await iterator.return?.();
|
|
3736
|
+
controller.close();
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
});
|
|
3740
|
+
var createProviderProxyResponse = async (provider, value, options = {}) => {
|
|
3741
|
+
const params = parseProviderProxyParams(value);
|
|
3742
|
+
if (!params) {
|
|
3743
|
+
return Response.json({ error: "invalid provider stream request" }, { status: 400 });
|
|
3744
|
+
}
|
|
3745
|
+
const iterator = provider.stream({ ...params, signal: options.signal })[Symbol.asyncIterator]();
|
|
3746
|
+
return new Response(streamResponseBody(iterator, options.heartbeatMs ?? DEFAULT_HEARTBEAT_MS2, options.onError), {
|
|
3747
|
+
headers: {
|
|
3748
|
+
"cache-control": "no-cache",
|
|
3749
|
+
"content-type": "text/event-stream; charset=utf-8",
|
|
3750
|
+
"x-accel-buffering": "no",
|
|
3751
|
+
...Object.fromEntries(new Headers(options.headers))
|
|
3752
|
+
}
|
|
3753
|
+
});
|
|
3754
|
+
};
|
|
3755
|
+
var parseRemoteStream = async function* (response) {
|
|
3756
|
+
if (!response.ok) {
|
|
3757
|
+
throw ProviderError.fromResponse("remote", response.status, await response.text());
|
|
3758
|
+
}
|
|
3759
|
+
if (!response.body)
|
|
3760
|
+
throw new ProviderError({
|
|
3761
|
+
message: "Remote provider returned no response body",
|
|
3762
|
+
provider: "remote",
|
|
3763
|
+
retryable: true
|
|
3764
|
+
});
|
|
3765
|
+
const reader = response.body.getReader();
|
|
3766
|
+
const decoder = new TextDecoder;
|
|
3767
|
+
let buffer = "";
|
|
3768
|
+
try {
|
|
3769
|
+
for (;; ) {
|
|
3770
|
+
const { done, value } = await reader.read();
|
|
3771
|
+
buffer += decoder.decode(value, { stream: !done });
|
|
3772
|
+
const frames = buffer.split(/\r?\n\r?\n/);
|
|
3773
|
+
buffer = frames.pop() ?? "";
|
|
3774
|
+
for (const frame of frames) {
|
|
3775
|
+
if (frame.startsWith(":"))
|
|
3776
|
+
continue;
|
|
3777
|
+
const event = /^event:\s*(.+)$/m.exec(frame)?.[1];
|
|
3778
|
+
const data = frame.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join(`
|
|
3779
|
+
`);
|
|
3780
|
+
if (!data)
|
|
3781
|
+
continue;
|
|
3782
|
+
const parsed = JSON.parse(data);
|
|
3783
|
+
if (event === "error") {
|
|
3784
|
+
throw new ProviderError({
|
|
3785
|
+
message: "message" in parsed && typeof parsed.message === "string" ? parsed.message : "Remote provider stream failed",
|
|
3786
|
+
provider: "provider" in parsed && typeof parsed.provider === "string" ? parsed.provider : "remote",
|
|
3787
|
+
retryable: "retryable" in parsed && typeof parsed.retryable === "boolean" ? parsed.retryable : true,
|
|
3788
|
+
status: "status" in parsed && (typeof parsed.status === "number" || parsed.status === null) ? parsed.status : null,
|
|
3789
|
+
type: "type" in parsed && (typeof parsed.type === "string" || parsed.type === null) ? parsed.type : null
|
|
3790
|
+
});
|
|
3791
|
+
}
|
|
3792
|
+
if (event === "chunk")
|
|
3793
|
+
yield parsed;
|
|
3794
|
+
}
|
|
3795
|
+
if (done)
|
|
3796
|
+
break;
|
|
3797
|
+
}
|
|
3798
|
+
} finally {
|
|
3799
|
+
reader.releaseLock();
|
|
3800
|
+
}
|
|
3801
|
+
};
|
|
3802
|
+
var remoteProvider = (config2) => ({
|
|
3803
|
+
stream: async function* (params) {
|
|
3804
|
+
const headers = typeof config2.headers === "function" ? await config2.headers() : config2.headers;
|
|
3805
|
+
const response = await (config2.fetch ?? fetch)(config2.url, {
|
|
3806
|
+
body: JSON.stringify(wireParams(params)),
|
|
3807
|
+
headers: {
|
|
3808
|
+
"content-type": "application/json",
|
|
3809
|
+
...Object.fromEntries(new Headers(headers))
|
|
3810
|
+
},
|
|
3811
|
+
method: "POST",
|
|
3812
|
+
signal: params.signal
|
|
3813
|
+
});
|
|
3814
|
+
yield* parseRemoteStream(response);
|
|
3815
|
+
}
|
|
3816
|
+
});
|
|
3657
3817
|
// src/ai/ui/uiCards.ts
|
|
3658
3818
|
var createUiCards = (definitions) => {
|
|
3659
3819
|
const byName = new Map(definitions.map((definition) => [definition.name, definition]));
|
|
@@ -3690,6 +3850,12 @@ var FORM_FIELD_TYPES = [
|
|
|
3690
3850
|
"checkbox",
|
|
3691
3851
|
"password"
|
|
3692
3852
|
];
|
|
3853
|
+
var PLAN_STEP_STATUSES = [
|
|
3854
|
+
"pending",
|
|
3855
|
+
"active",
|
|
3856
|
+
"done",
|
|
3857
|
+
"error"
|
|
3858
|
+
];
|
|
3693
3859
|
var CHART_MAX_SERIES = 8;
|
|
3694
3860
|
var CHART_MAX_POINTS = 24;
|
|
3695
3861
|
var TABLE_MAX_COLUMNS = 8;
|
|
@@ -3698,14 +3864,28 @@ var STAT_TILES_MAX = 6;
|
|
|
3698
3864
|
var UI_ACTIONS_MAX = 3;
|
|
3699
3865
|
var FORM_MAX_FIELDS = 8;
|
|
3700
3866
|
var FORM_SELECT_MAX_OPTIONS = 12;
|
|
3867
|
+
var CHOICE_MAX_OPTIONS = 8;
|
|
3868
|
+
var CONFIRM_CONSEQUENCE_MAX_CHARS = 500;
|
|
3869
|
+
var DIFF_MAX_FILES = 6;
|
|
3870
|
+
var DIFF_MAX_LINES = 400;
|
|
3871
|
+
var PLAN_MAX_STEPS = 12;
|
|
3872
|
+
var CREDENTIAL_MAX_KEYS = 8;
|
|
3873
|
+
var CARD_ID_MAX_CHARS = 64;
|
|
3701
3874
|
var LABEL_MAX_CHARS = 80;
|
|
3702
3875
|
var TITLE_MAX_CHARS = 120;
|
|
3703
3876
|
var CELL_MAX_CHARS = 160;
|
|
3704
3877
|
var UNIT_MAX_CHARS = 8;
|
|
3705
3878
|
var ACTION_LABEL_MAX_CHARS = 40;
|
|
3706
3879
|
var DESCRIPTION_MAX_CHARS = 280;
|
|
3880
|
+
var BADGE_MAX_CHARS = 24;
|
|
3881
|
+
var DIFF_PATH_MAX_CHARS = 260;
|
|
3882
|
+
var DIFF_LINE_MAX_CHARS = 300;
|
|
3883
|
+
var DOCS_URL_MAX_CHARS = 300;
|
|
3707
3884
|
var ACTION_TOOL_PATTERN = /^[a-z][a-z0-9_]{1,63}$/;
|
|
3708
3885
|
var FIELD_NAME_PATTERN = /^[a-z][a-zA-Z0-9_]{0,63}$/;
|
|
3886
|
+
var CARD_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
3887
|
+
var ENV_KEY_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
3888
|
+
var DOCS_URL_PATTERN = /^https?:\/\//;
|
|
3709
3889
|
var isRecord6 = (value) => typeof value === "object" && value !== null;
|
|
3710
3890
|
var cleanString = (value, maxChars) => typeof value === "string" && value.trim().length > 0 ? value.trim().slice(0, maxChars) : null;
|
|
3711
3891
|
var cleanStringArray = (value, maxItems, maxChars) => {
|
|
@@ -3729,6 +3909,17 @@ var cleanNumberArray = (value, maxItems) => {
|
|
|
3729
3909
|
}
|
|
3730
3910
|
return cleaned;
|
|
3731
3911
|
};
|
|
3912
|
+
var cleanId = (value) => {
|
|
3913
|
+
if (typeof value !== "string")
|
|
3914
|
+
return null;
|
|
3915
|
+
const trimmed = value.trim().slice(0, CARD_ID_MAX_CHARS);
|
|
3916
|
+
return CARD_ID_PATTERN.test(trimmed) ? trimmed : null;
|
|
3917
|
+
};
|
|
3918
|
+
var applyCardId = (spec, raw) => {
|
|
3919
|
+
const cardId = cleanId(raw);
|
|
3920
|
+
if (cardId)
|
|
3921
|
+
spec.cardId = cardId;
|
|
3922
|
+
};
|
|
3732
3923
|
var parseUiActions = (value) => {
|
|
3733
3924
|
if (!Array.isArray(value) || value.length === 0)
|
|
3734
3925
|
return;
|
|
@@ -3763,6 +3954,22 @@ var ACTIONS_SCHEMA = {
|
|
|
3763
3954
|
},
|
|
3764
3955
|
type: "array"
|
|
3765
3956
|
};
|
|
3957
|
+
var CARD_ID_SCHEMA = {
|
|
3958
|
+
description: "Optional stable card identity (letters/digits/_/-, max 64 chars). Re-emit a card with the SAME cardId to update the earlier render in place instead of adding a new card.",
|
|
3959
|
+
type: "string"
|
|
3960
|
+
};
|
|
3961
|
+
var ACTION_BINDING_SCHEMA = {
|
|
3962
|
+
properties: {
|
|
3963
|
+
input: {
|
|
3964
|
+
description: "The exact tool input to send (real ids you looked up, never placeholders)",
|
|
3965
|
+
type: "object"
|
|
3966
|
+
},
|
|
3967
|
+
label: { description: "Button label", type: "string" },
|
|
3968
|
+
tool: { description: "The tool name to invoke", type: "string" }
|
|
3969
|
+
},
|
|
3970
|
+
required: ["label", "tool", "input"],
|
|
3971
|
+
type: "object"
|
|
3972
|
+
};
|
|
3766
3973
|
var parseChartSpec = (input) => {
|
|
3767
3974
|
if (!isRecord6(input))
|
|
3768
3975
|
return null;
|
|
@@ -3802,6 +4009,7 @@ var parseChartSpec = (input) => {
|
|
|
3802
4009
|
const actions = parseUiActions(input.actions);
|
|
3803
4010
|
if (actions)
|
|
3804
4011
|
spec.actions = actions;
|
|
4012
|
+
applyCardId(spec, input.cardId);
|
|
3805
4013
|
return spec;
|
|
3806
4014
|
};
|
|
3807
4015
|
var parseTableSpec = (input) => {
|
|
@@ -3828,6 +4036,7 @@ var parseTableSpec = (input) => {
|
|
|
3828
4036
|
const actions = parseUiActions(input.actions);
|
|
3829
4037
|
if (actions)
|
|
3830
4038
|
spec.actions = actions;
|
|
4039
|
+
applyCardId(spec, input.cardId);
|
|
3831
4040
|
return spec;
|
|
3832
4041
|
};
|
|
3833
4042
|
var parseStatTilesSpec = (input) => {
|
|
@@ -3856,6 +4065,7 @@ var parseStatTilesSpec = (input) => {
|
|
|
3856
4065
|
const actions = parseUiActions(input.actions);
|
|
3857
4066
|
if (actions)
|
|
3858
4067
|
spec.actions = actions;
|
|
4068
|
+
applyCardId(spec, input.cardId);
|
|
3859
4069
|
return spec;
|
|
3860
4070
|
};
|
|
3861
4071
|
var parseFormField = (raw) => {
|
|
@@ -3908,6 +4118,188 @@ var parseFormSpec = (input) => {
|
|
|
3908
4118
|
const description = cleanString(input.description, DESCRIPTION_MAX_CHARS);
|
|
3909
4119
|
if (description)
|
|
3910
4120
|
spec.description = description;
|
|
4121
|
+
applyCardId(spec, input.cardId);
|
|
4122
|
+
return spec;
|
|
4123
|
+
};
|
|
4124
|
+
var parseChoiceOption = (raw) => {
|
|
4125
|
+
if (!isRecord6(raw))
|
|
4126
|
+
return null;
|
|
4127
|
+
const id = cleanId(raw.id);
|
|
4128
|
+
const label = cleanString(raw.label, LABEL_MAX_CHARS);
|
|
4129
|
+
if (!id || !label)
|
|
4130
|
+
return null;
|
|
4131
|
+
const option = { id, label };
|
|
4132
|
+
const description = cleanString(raw.description, DESCRIPTION_MAX_CHARS);
|
|
4133
|
+
if (description)
|
|
4134
|
+
option.description = description;
|
|
4135
|
+
const badge = cleanString(raw.badge, BADGE_MAX_CHARS);
|
|
4136
|
+
if (badge)
|
|
4137
|
+
option.badge = badge;
|
|
4138
|
+
return option;
|
|
4139
|
+
};
|
|
4140
|
+
var parseChoiceSpec = (input) => {
|
|
4141
|
+
if (!isRecord6(input))
|
|
4142
|
+
return null;
|
|
4143
|
+
const title = cleanString(input.title, TITLE_MAX_CHARS);
|
|
4144
|
+
const [submit] = parseUiActions([input.submit]) ?? [];
|
|
4145
|
+
if (!title || !submit)
|
|
4146
|
+
return null;
|
|
4147
|
+
if (!Array.isArray(input.options) || input.options.length === 0)
|
|
4148
|
+
return null;
|
|
4149
|
+
const options = [];
|
|
4150
|
+
const seen = new Set;
|
|
4151
|
+
for (const raw of input.options.slice(0, CHOICE_MAX_OPTIONS)) {
|
|
4152
|
+
const option = parseChoiceOption(raw);
|
|
4153
|
+
if (!option || seen.has(option.id))
|
|
4154
|
+
return null;
|
|
4155
|
+
seen.add(option.id);
|
|
4156
|
+
options.push(option);
|
|
4157
|
+
}
|
|
4158
|
+
const spec = { options, submit, title };
|
|
4159
|
+
const description = cleanString(input.description, DESCRIPTION_MAX_CHARS);
|
|
4160
|
+
if (description)
|
|
4161
|
+
spec.description = description;
|
|
4162
|
+
if (input.multi === true)
|
|
4163
|
+
spec.multi = true;
|
|
4164
|
+
applyCardId(spec, input.cardId);
|
|
4165
|
+
return spec;
|
|
4166
|
+
};
|
|
4167
|
+
var parseConfirmSpec = (input) => {
|
|
4168
|
+
if (!isRecord6(input))
|
|
4169
|
+
return null;
|
|
4170
|
+
const title = cleanString(input.title, TITLE_MAX_CHARS);
|
|
4171
|
+
const consequence = cleanString(input.consequence, CONFIRM_CONSEQUENCE_MAX_CHARS);
|
|
4172
|
+
const confirmLabel = cleanString(input.confirmLabel, ACTION_LABEL_MAX_CHARS);
|
|
4173
|
+
const [confirm] = parseUiActions([input.confirm]) ?? [];
|
|
4174
|
+
if (!title || !consequence || !confirmLabel || !confirm)
|
|
4175
|
+
return null;
|
|
4176
|
+
const spec = { confirm, confirmLabel, consequence, title };
|
|
4177
|
+
const cancelLabel = cleanString(input.cancelLabel, ACTION_LABEL_MAX_CHARS);
|
|
4178
|
+
if (cancelLabel)
|
|
4179
|
+
spec.cancelLabel = cancelLabel;
|
|
4180
|
+
if (input.danger === true)
|
|
4181
|
+
spec.danger = true;
|
|
4182
|
+
applyCardId(spec, input.cardId);
|
|
4183
|
+
return spec;
|
|
4184
|
+
};
|
|
4185
|
+
var parseDiffFile = (raw, budget) => {
|
|
4186
|
+
if (!isRecord6(raw))
|
|
4187
|
+
return null;
|
|
4188
|
+
const path = cleanString(raw.path, DIFF_PATH_MAX_CHARS);
|
|
4189
|
+
if (!path || typeof raw.diff !== "string" || raw.diff.trim().length === 0) {
|
|
4190
|
+
return null;
|
|
4191
|
+
}
|
|
4192
|
+
const lines = raw.diff.split(/\r?\n/).map((line) => line.slice(0, DIFF_LINE_MAX_CHARS));
|
|
4193
|
+
const kept = lines.slice(0, Math.max(budget.remaining, 0));
|
|
4194
|
+
budget.remaining -= kept.length;
|
|
4195
|
+
const file = { diff: kept.join(`
|
|
4196
|
+
`), path };
|
|
4197
|
+
if (raw.truncated === true || kept.length < lines.length) {
|
|
4198
|
+
file.truncated = true;
|
|
4199
|
+
}
|
|
4200
|
+
return file;
|
|
4201
|
+
};
|
|
4202
|
+
var parseDiffSpec = (input) => {
|
|
4203
|
+
if (!isRecord6(input))
|
|
4204
|
+
return null;
|
|
4205
|
+
const title = cleanString(input.title, TITLE_MAX_CHARS);
|
|
4206
|
+
const [apply] = parseUiActions([input.apply]) ?? [];
|
|
4207
|
+
if (!title || !apply)
|
|
4208
|
+
return null;
|
|
4209
|
+
if (!Array.isArray(input.files) || input.files.length === 0)
|
|
4210
|
+
return null;
|
|
4211
|
+
const budget = { remaining: DIFF_MAX_LINES };
|
|
4212
|
+
const files = [];
|
|
4213
|
+
for (const raw of input.files.slice(0, DIFF_MAX_FILES)) {
|
|
4214
|
+
const file = parseDiffFile(raw, budget);
|
|
4215
|
+
if (!file)
|
|
4216
|
+
return null;
|
|
4217
|
+
files.push(file);
|
|
4218
|
+
}
|
|
4219
|
+
const spec = { apply, files, title };
|
|
4220
|
+
const [reject] = parseUiActions([input.reject]) ?? [];
|
|
4221
|
+
if (reject)
|
|
4222
|
+
spec.reject = reject;
|
|
4223
|
+
const note = cleanString(input.note, DESCRIPTION_MAX_CHARS);
|
|
4224
|
+
if (note)
|
|
4225
|
+
spec.note = note;
|
|
4226
|
+
applyCardId(spec, input.cardId);
|
|
4227
|
+
return spec;
|
|
4228
|
+
};
|
|
4229
|
+
var parsePlanStep = (raw) => {
|
|
4230
|
+
if (!isRecord6(raw))
|
|
4231
|
+
return null;
|
|
4232
|
+
const id = cleanId(raw.id);
|
|
4233
|
+
const label = cleanString(raw.label, LABEL_MAX_CHARS);
|
|
4234
|
+
const status = PLAN_STEP_STATUSES.find((entry) => entry === raw.status);
|
|
4235
|
+
if (!id || !label || !status)
|
|
4236
|
+
return null;
|
|
4237
|
+
const step = { id, label, status };
|
|
4238
|
+
const detail = cleanString(raw.detail, CELL_MAX_CHARS);
|
|
4239
|
+
if (detail)
|
|
4240
|
+
step.detail = detail;
|
|
4241
|
+
return step;
|
|
4242
|
+
};
|
|
4243
|
+
var parsePlanSpec = (input) => {
|
|
4244
|
+
if (!isRecord6(input))
|
|
4245
|
+
return null;
|
|
4246
|
+
const title = cleanString(input.title, TITLE_MAX_CHARS);
|
|
4247
|
+
if (!title)
|
|
4248
|
+
return null;
|
|
4249
|
+
if (!Array.isArray(input.steps) || input.steps.length === 0)
|
|
4250
|
+
return null;
|
|
4251
|
+
const steps = [];
|
|
4252
|
+
const seen = new Set;
|
|
4253
|
+
for (const raw of input.steps.slice(0, PLAN_MAX_STEPS)) {
|
|
4254
|
+
const step = parsePlanStep(raw);
|
|
4255
|
+
if (!step || seen.has(step.id))
|
|
4256
|
+
return null;
|
|
4257
|
+
seen.add(step.id);
|
|
4258
|
+
steps.push(step);
|
|
4259
|
+
}
|
|
4260
|
+
const spec = { steps, title };
|
|
4261
|
+
const note = cleanString(input.note, DESCRIPTION_MAX_CHARS);
|
|
4262
|
+
if (note)
|
|
4263
|
+
spec.note = note;
|
|
4264
|
+
applyCardId(spec, input.cardId);
|
|
4265
|
+
return spec;
|
|
4266
|
+
};
|
|
4267
|
+
var parseCredentialKey = (raw) => {
|
|
4268
|
+
if (!isRecord6(raw))
|
|
4269
|
+
return null;
|
|
4270
|
+
const key = typeof raw.key === "string" && ENV_KEY_PATTERN.test(raw.key) ? raw.key : null;
|
|
4271
|
+
if (!key)
|
|
4272
|
+
return null;
|
|
4273
|
+
const entry = { key, secret: raw.secret !== false };
|
|
4274
|
+
const label = cleanString(raw.label, LABEL_MAX_CHARS);
|
|
4275
|
+
if (label)
|
|
4276
|
+
entry.label = label;
|
|
4277
|
+
const docsUrl = cleanString(raw.docsUrl, DOCS_URL_MAX_CHARS);
|
|
4278
|
+
if (docsUrl && DOCS_URL_PATTERN.test(docsUrl))
|
|
4279
|
+
entry.docsUrl = docsUrl;
|
|
4280
|
+
if (typeof raw.isSet === "boolean")
|
|
4281
|
+
entry.isSet = raw.isSet;
|
|
4282
|
+
return entry;
|
|
4283
|
+
};
|
|
4284
|
+
var parseCredentialSpec = (input) => {
|
|
4285
|
+
if (!isRecord6(input))
|
|
4286
|
+
return null;
|
|
4287
|
+
const title = cleanString(input.title, TITLE_MAX_CHARS);
|
|
4288
|
+
if (!title)
|
|
4289
|
+
return null;
|
|
4290
|
+
if (!Array.isArray(input.keys) || input.keys.length === 0)
|
|
4291
|
+
return null;
|
|
4292
|
+
const keys = [];
|
|
4293
|
+
const seen = new Set;
|
|
4294
|
+
for (const raw of input.keys.slice(0, CREDENTIAL_MAX_KEYS)) {
|
|
4295
|
+
const entry = parseCredentialKey(raw);
|
|
4296
|
+
if (!entry || seen.has(entry.key))
|
|
4297
|
+
return null;
|
|
4298
|
+
seen.add(entry.key);
|
|
4299
|
+
keys.push(entry);
|
|
4300
|
+
}
|
|
4301
|
+
const spec = { keys, title };
|
|
4302
|
+
applyCardId(spec, input.cardId);
|
|
3911
4303
|
return spec;
|
|
3912
4304
|
};
|
|
3913
4305
|
var SERIES_SCHEMA = {
|
|
@@ -3928,6 +4320,7 @@ var chartCard = {
|
|
|
3928
4320
|
inputSchema: {
|
|
3929
4321
|
properties: {
|
|
3930
4322
|
actions: ACTIONS_SCHEMA,
|
|
4323
|
+
cardId: CARD_ID_SCHEMA,
|
|
3931
4324
|
labels: {
|
|
3932
4325
|
description: "Category labels \u2014 x-axis for bar/line, slice names for donut (max 24)",
|
|
3933
4326
|
items: { type: "string" },
|
|
@@ -3961,6 +4354,7 @@ var tableCard = {
|
|
|
3961
4354
|
inputSchema: {
|
|
3962
4355
|
properties: {
|
|
3963
4356
|
actions: ACTIONS_SCHEMA,
|
|
4357
|
+
cardId: CARD_ID_SCHEMA,
|
|
3964
4358
|
columns: {
|
|
3965
4359
|
description: "Column headers (max 8)",
|
|
3966
4360
|
items: { type: "string" },
|
|
@@ -3985,6 +4379,7 @@ var statTilesCard = {
|
|
|
3985
4379
|
inputSchema: {
|
|
3986
4380
|
properties: {
|
|
3987
4381
|
actions: ACTIONS_SCHEMA,
|
|
4382
|
+
cardId: CARD_ID_SCHEMA,
|
|
3988
4383
|
tiles: {
|
|
3989
4384
|
description: "The tiles (max 6)",
|
|
3990
4385
|
items: {
|
|
@@ -4017,6 +4412,7 @@ var formCard = {
|
|
|
4017
4412
|
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. Use type "password" for sensitive values (API keys, secrets, credentials) \u2014 the host renders it masked and never pre-fill a value for it.`,
|
|
4018
4413
|
inputSchema: {
|
|
4019
4414
|
properties: {
|
|
4415
|
+
cardId: CARD_ID_SCHEMA,
|
|
4020
4416
|
description: {
|
|
4021
4417
|
description: "Optional one-line helper text under the title",
|
|
4022
4418
|
type: "string"
|
|
@@ -4072,11 +4468,229 @@ var formCard = {
|
|
|
4072
4468
|
name: "render_form",
|
|
4073
4469
|
parse: parseFormSpec
|
|
4074
4470
|
};
|
|
4471
|
+
var choiceCard = {
|
|
4472
|
+
ack: "(choice card rendered inline \u2014 the member picks an option, which runs the bound tool with their selection merged in. Do not re-ask in text; wait for the selection)",
|
|
4473
|
+
description: "Render a structured choice card whenever the member must pick between concrete options (which plan, which duplicate record to keep, which time slot) \u2014 never ask them to 'reply 1 or 2' in prose. Give every option a stable id; on selection the host merges { choice: id } (or { choices: [ids] } when multi is true) into submit.input and invokes submit.tool exactly like a clicked action button, so put everything you already resolved into submit.input. Max 8 options.",
|
|
4474
|
+
inputSchema: {
|
|
4475
|
+
properties: {
|
|
4476
|
+
cardId: CARD_ID_SCHEMA,
|
|
4477
|
+
description: {
|
|
4478
|
+
description: "Optional one-line helper text under the title",
|
|
4479
|
+
type: "string"
|
|
4480
|
+
},
|
|
4481
|
+
multi: {
|
|
4482
|
+
description: "Allow selecting several options \u2014 submits { choices: [ids] } instead of { choice: id }",
|
|
4483
|
+
type: "boolean"
|
|
4484
|
+
},
|
|
4485
|
+
options: {
|
|
4486
|
+
description: "The options to choose between (max 8)",
|
|
4487
|
+
items: {
|
|
4488
|
+
properties: {
|
|
4489
|
+
badge: {
|
|
4490
|
+
description: 'Tiny annotation beside the label, e.g. "recommended"',
|
|
4491
|
+
type: "string"
|
|
4492
|
+
},
|
|
4493
|
+
description: {
|
|
4494
|
+
description: "One-line explanation of the option",
|
|
4495
|
+
type: "string"
|
|
4496
|
+
},
|
|
4497
|
+
id: {
|
|
4498
|
+
description: "Stable option id merged into submit.input on selection (letters/digits/_/-)",
|
|
4499
|
+
type: "string"
|
|
4500
|
+
},
|
|
4501
|
+
label: { description: "What the member sees", type: "string" }
|
|
4502
|
+
},
|
|
4503
|
+
required: ["id", "label"],
|
|
4504
|
+
type: "object"
|
|
4505
|
+
},
|
|
4506
|
+
type: "array"
|
|
4507
|
+
},
|
|
4508
|
+
submit: {
|
|
4509
|
+
...ACTION_BINDING_SCHEMA,
|
|
4510
|
+
description: "The submit binding: the tool to run once a choice is made. The selection is merged into input as { choice: id } (or { choices: [ids] })"
|
|
4511
|
+
},
|
|
4512
|
+
title: { description: "The decision being made", type: "string" }
|
|
4513
|
+
},
|
|
4514
|
+
required: ["title", "options", "submit"],
|
|
4515
|
+
type: "object"
|
|
4516
|
+
},
|
|
4517
|
+
name: "render_choice",
|
|
4518
|
+
parse: parseChoiceSpec
|
|
4519
|
+
};
|
|
4520
|
+
var confirmCard = {
|
|
4521
|
+
ack: "(confirmation card rendered inline \u2014 NOTHING has run yet; the action only runs if the member clicks confirm. Do not claim or assume it happened; wait for the outcome)",
|
|
4522
|
+
description: "Render an explicit confirmation card before any destructive or irreversible action (deleting data, sending money or bulk email, cancelling a subscription). State the consequence in plain language \u2014 exactly what will happen. TRUST CONTRACT: the host invokes confirm ONLY on a real member click, never on your say-so; hosts SHOULD mint an unforgeable server-side confirmation token at click time and require it on the downstream action, so a confirmation can never be fabricated in text. Set danger: true for destructive styling. Rendering this card is never itself consent.",
|
|
4523
|
+
inputSchema: {
|
|
4524
|
+
properties: {
|
|
4525
|
+
cancelLabel: {
|
|
4526
|
+
description: 'Optional dismiss label, e.g. "Keep project"',
|
|
4527
|
+
type: "string"
|
|
4528
|
+
},
|
|
4529
|
+
cardId: CARD_ID_SCHEMA,
|
|
4530
|
+
confirm: {
|
|
4531
|
+
...ACTION_BINDING_SCHEMA,
|
|
4532
|
+
description: "The action to run ONLY when the member clicks confirm (fully-resolved input, real ids)"
|
|
4533
|
+
},
|
|
4534
|
+
confirmLabel: {
|
|
4535
|
+
description: 'The confirm button label, e.g. "Delete project"',
|
|
4536
|
+
type: "string"
|
|
4537
|
+
},
|
|
4538
|
+
consequence: {
|
|
4539
|
+
description: "What will happen if confirmed, in plain language (max 500 chars)",
|
|
4540
|
+
type: "string"
|
|
4541
|
+
},
|
|
4542
|
+
danger: {
|
|
4543
|
+
description: "Render destructive (red) styling",
|
|
4544
|
+
type: "boolean"
|
|
4545
|
+
},
|
|
4546
|
+
title: { description: "Short question being confirmed", type: "string" }
|
|
4547
|
+
},
|
|
4548
|
+
required: ["title", "consequence", "confirmLabel", "confirm"],
|
|
4549
|
+
type: "object"
|
|
4550
|
+
},
|
|
4551
|
+
name: "render_confirm",
|
|
4552
|
+
parse: parseConfirmSpec
|
|
4553
|
+
};
|
|
4554
|
+
var diffCard = {
|
|
4555
|
+
ack: "(diff card rendered inline \u2014 the member reviews the changes and clicks apply or reject. Do not restate the diff in text and do not assume it was applied; wait for their decision)",
|
|
4556
|
+
description: "Render proposed file changes as reviewable unified diffs before applying them (max 6 files and 400 diff lines total \u2014 oversized diffs are truncated for display with truncated: true, never rejected). The diffs are DISPLAY data: the host renders the +/- coloring and nothing executes from the text. Bind apply (and optionally reject) to YOUR tools with fully-resolved input; hosts SHOULD route apply through a click-minted server-side token exactly like a confirmation card, because applying changes is destructive.",
|
|
4557
|
+
inputSchema: {
|
|
4558
|
+
properties: {
|
|
4559
|
+
apply: {
|
|
4560
|
+
...ACTION_BINDING_SCHEMA,
|
|
4561
|
+
description: "The action that applies the changes when the member clicks it"
|
|
4562
|
+
},
|
|
4563
|
+
cardId: CARD_ID_SCHEMA,
|
|
4564
|
+
files: {
|
|
4565
|
+
description: "The changed files (max 6, 400 diff lines total)",
|
|
4566
|
+
items: {
|
|
4567
|
+
properties: {
|
|
4568
|
+
diff: {
|
|
4569
|
+
description: "Unified diff text for this file (display only)",
|
|
4570
|
+
type: "string"
|
|
4571
|
+
},
|
|
4572
|
+
path: { description: "File path being changed", type: "string" },
|
|
4573
|
+
truncated: {
|
|
4574
|
+
description: "Set true if you already cut the diff for size",
|
|
4575
|
+
type: "boolean"
|
|
4576
|
+
}
|
|
4577
|
+
},
|
|
4578
|
+
required: ["path", "diff"],
|
|
4579
|
+
type: "object"
|
|
4580
|
+
},
|
|
4581
|
+
type: "array"
|
|
4582
|
+
},
|
|
4583
|
+
note: {
|
|
4584
|
+
description: "Optional one-line note under the diffs",
|
|
4585
|
+
type: "string"
|
|
4586
|
+
},
|
|
4587
|
+
reject: {
|
|
4588
|
+
...ACTION_BINDING_SCHEMA,
|
|
4589
|
+
description: "Optional action to run when the member rejects"
|
|
4590
|
+
},
|
|
4591
|
+
title: { description: "What the change set does", type: "string" }
|
|
4592
|
+
},
|
|
4593
|
+
required: ["title", "files", "apply"],
|
|
4594
|
+
type: "object"
|
|
4595
|
+
},
|
|
4596
|
+
name: "render_diff",
|
|
4597
|
+
parse: parseDiffSpec
|
|
4598
|
+
};
|
|
4599
|
+
var planCard = {
|
|
4600
|
+
ack: "(plan rendered inline \u2014 as you work, re-emit render_plan with the SAME cardId and updated step statuses instead of narrating progress; do not restate the steps as text)",
|
|
4601
|
+
description: "Render a live multi-step plan card (max 12 steps) when you start multi-step work. Display-only \u2014 it has no buttons. Set a cardId and give every step a stable id, then as you progress RE-EMIT this card with the SAME cardId and updated step statuses (pending / active / done / error): the host replaces the earlier render in place, so the member sees one live plan instead of a stack of copies.",
|
|
4602
|
+
inputSchema: {
|
|
4603
|
+
properties: {
|
|
4604
|
+
cardId: CARD_ID_SCHEMA,
|
|
4605
|
+
note: {
|
|
4606
|
+
description: "Optional one-line note under the steps",
|
|
4607
|
+
type: "string"
|
|
4608
|
+
},
|
|
4609
|
+
steps: {
|
|
4610
|
+
description: "The plan steps in order (max 12)",
|
|
4611
|
+
items: {
|
|
4612
|
+
properties: {
|
|
4613
|
+
detail: {
|
|
4614
|
+
description: "One-line progress or error note under the label",
|
|
4615
|
+
type: "string"
|
|
4616
|
+
},
|
|
4617
|
+
id: {
|
|
4618
|
+
description: "Stable step id \u2014 keep it identical across re-emits (letters/digits/_/-)",
|
|
4619
|
+
type: "string"
|
|
4620
|
+
},
|
|
4621
|
+
label: { description: "What this step does", type: "string" },
|
|
4622
|
+
status: { enum: [...PLAN_STEP_STATUSES], type: "string" }
|
|
4623
|
+
},
|
|
4624
|
+
required: ["id", "label", "status"],
|
|
4625
|
+
type: "object"
|
|
4626
|
+
},
|
|
4627
|
+
type: "array"
|
|
4628
|
+
},
|
|
4629
|
+
title: { description: "What the plan accomplishes", type: "string" }
|
|
4630
|
+
},
|
|
4631
|
+
required: ["title", "steps"],
|
|
4632
|
+
type: "object"
|
|
4633
|
+
},
|
|
4634
|
+
name: "render_plan",
|
|
4635
|
+
parse: parsePlanSpec
|
|
4636
|
+
};
|
|
4637
|
+
var credentialCard = {
|
|
4638
|
+
ack: "(credential request rendered inline \u2014 the member enters the values in the host UI and they are stored outside this conversation; you will receive a message naming which keys were set, never the values. Do not ask for the values in text)",
|
|
4639
|
+
description: "Render a credential-request card when setup needs environment values from the member (API keys, secrets, connection strings) \u2014 max 8 keys, each an ENV_STYLE name with an optional label and docs link. This card deliberately has NO submit binding and collects NOTHING through you: the host UI gathers the values and stores them outside the model loop (its own .env or secret store), then sends a continuation message naming WHICH keys were set \u2014 never the values. Never ask for secret values in plain text, and never attach values to this card (any value-like field is dropped).",
|
|
4640
|
+
inputSchema: {
|
|
4641
|
+
properties: {
|
|
4642
|
+
cardId: CARD_ID_SCHEMA,
|
|
4643
|
+
keys: {
|
|
4644
|
+
description: "The environment keys to request (max 8)",
|
|
4645
|
+
items: {
|
|
4646
|
+
properties: {
|
|
4647
|
+
docsUrl: {
|
|
4648
|
+
description: "Where to obtain the credential (provider dashboard URL)",
|
|
4649
|
+
type: "string"
|
|
4650
|
+
},
|
|
4651
|
+
isSet: {
|
|
4652
|
+
description: "Already configured on the host \u2014 rendered as set, with a replace affordance",
|
|
4653
|
+
type: "boolean"
|
|
4654
|
+
},
|
|
4655
|
+
key: {
|
|
4656
|
+
description: 'Environment variable name, e.g. "STRIPE_SECRET_KEY"',
|
|
4657
|
+
type: "string"
|
|
4658
|
+
},
|
|
4659
|
+
label: {
|
|
4660
|
+
description: 'Human label, e.g. "Stripe secret key"',
|
|
4661
|
+
type: "string"
|
|
4662
|
+
},
|
|
4663
|
+
secret: {
|
|
4664
|
+
description: "Mask and never echo (default true \u2014 only set false for genuinely public values)",
|
|
4665
|
+
type: "boolean"
|
|
4666
|
+
}
|
|
4667
|
+
},
|
|
4668
|
+
required: ["key"],
|
|
4669
|
+
type: "object"
|
|
4670
|
+
},
|
|
4671
|
+
type: "array"
|
|
4672
|
+
},
|
|
4673
|
+
title: {
|
|
4674
|
+
description: 'What the credentials unlock, e.g. "Connect Stripe"',
|
|
4675
|
+
type: "string"
|
|
4676
|
+
}
|
|
4677
|
+
},
|
|
4678
|
+
required: ["title", "keys"],
|
|
4679
|
+
type: "object"
|
|
4680
|
+
},
|
|
4681
|
+
name: "request_credentials",
|
|
4682
|
+
parse: parseCredentialSpec
|
|
4683
|
+
};
|
|
4075
4684
|
var BUILTIN_UI_CARDS = [
|
|
4076
4685
|
chartCard,
|
|
4077
4686
|
tableCard,
|
|
4078
4687
|
statTilesCard,
|
|
4079
|
-
formCard
|
|
4688
|
+
formCard,
|
|
4689
|
+
choiceCard,
|
|
4690
|
+
confirmCard,
|
|
4691
|
+
diffCard,
|
|
4692
|
+
planCard,
|
|
4693
|
+
credentialCard
|
|
4080
4694
|
];
|
|
4081
4695
|
// src/ai/ui/svg.ts
|
|
4082
4696
|
var LIGHT_UI_THEME = {
|
|
@@ -5226,11 +5840,19 @@ export {
|
|
|
5226
5840
|
serializeAIMessage,
|
|
5227
5841
|
resolveRenderers,
|
|
5228
5842
|
renderChartSvg,
|
|
5843
|
+
remoteProvider,
|
|
5229
5844
|
providerStatusPage,
|
|
5845
|
+
planCard,
|
|
5230
5846
|
parseUiActions,
|
|
5231
5847
|
parseTableSpec,
|
|
5232
5848
|
parseStatTilesSpec,
|
|
5849
|
+
parseProviderProxyParams,
|
|
5850
|
+
parsePlanSpec,
|
|
5233
5851
|
parseFormSpec,
|
|
5852
|
+
parseDiffSpec,
|
|
5853
|
+
parseCredentialSpec,
|
|
5854
|
+
parseConfirmSpec,
|
|
5855
|
+
parseChoiceSpec,
|
|
5234
5856
|
parseChartSpec,
|
|
5235
5857
|
parseAIMessage,
|
|
5236
5858
|
openaiResponses,
|
|
@@ -5249,15 +5871,20 @@ export {
|
|
|
5249
5871
|
gemini,
|
|
5250
5872
|
formCard,
|
|
5251
5873
|
fetchProviderApiStatus,
|
|
5874
|
+
diffCard,
|
|
5252
5875
|
deepseek,
|
|
5876
|
+
credentialCard,
|
|
5253
5877
|
createUiCards,
|
|
5254
5878
|
createSyncConversationStore,
|
|
5879
|
+
createProviderProxyResponse,
|
|
5255
5880
|
createOAuth2ClientCredentialsTokenSource,
|
|
5256
5881
|
createMemoryStore,
|
|
5257
5882
|
createConversationManager,
|
|
5258
5883
|
createAIStream,
|
|
5259
5884
|
createAIConnection,
|
|
5885
|
+
confirmCard,
|
|
5260
5886
|
configureProviderResilience,
|
|
5887
|
+
choiceCard,
|
|
5261
5888
|
chartCard,
|
|
5262
5889
|
anthropic,
|
|
5263
5890
|
alibaba,
|
|
@@ -5268,16 +5895,24 @@ export {
|
|
|
5268
5895
|
STAT_TILES_MAX,
|
|
5269
5896
|
ProviderError,
|
|
5270
5897
|
PROVIDER_STATUS_PAGES,
|
|
5898
|
+
PLAN_STEP_STATUSES,
|
|
5899
|
+
PLAN_MAX_STEPS,
|
|
5271
5900
|
LIGHT_UI_THEME,
|
|
5272
5901
|
FORM_SELECT_MAX_OPTIONS,
|
|
5273
5902
|
FORM_MAX_FIELDS,
|
|
5274
5903
|
FORM_FIELD_TYPES,
|
|
5904
|
+
DIFF_MAX_LINES,
|
|
5905
|
+
DIFF_MAX_FILES,
|
|
5275
5906
|
DARK_UI_THEME,
|
|
5907
|
+
CREDENTIAL_MAX_KEYS,
|
|
5908
|
+
CONFIRM_CONSEQUENCE_MAX_CHARS,
|
|
5909
|
+
CHOICE_MAX_OPTIONS,
|
|
5276
5910
|
CHART_TYPES,
|
|
5277
5911
|
CHART_MAX_SERIES,
|
|
5278
5912
|
CHART_MAX_POINTS,
|
|
5913
|
+
CARD_ID_MAX_CHARS,
|
|
5279
5914
|
BUILTIN_UI_CARDS
|
|
5280
5915
|
};
|
|
5281
5916
|
|
|
5282
|
-
//# debugId=
|
|
5917
|
+
//# debugId=31B8793E47976E7B64756E2164756E21
|
|
5283
5918
|
//# sourceMappingURL=index.js.map
|