@appilots/sdk 0.7.0 → 0.8.0
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 +41 -0
- package/dist/{chunk-DZ7QRFHD.js → chunk-AYWMBMSN.js} +255 -17
- package/dist/{chunk-R4D34FEW.mjs → chunk-C2KVVJ5K.mjs} +253 -17
- package/dist/{chunk-KYFAXT6V.js → chunk-H7BMQTXH.js} +5 -5
- package/dist/{chunk-KUFWRJC4.mjs → chunk-MHWVRZYF.mjs} +100 -35
- package/dist/{chunk-HFRIB4YN.js → chunk-N7EAOLBP.js} +259 -194
- package/dist/{chunk-DR75QTYK.mjs → chunk-ZSEACJKU.mjs} +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +11 -11
- package/dist/hooks/index.mjs +2 -2
- package/dist/{index-nI-s3Exg.d.mts → index-BdYY-dvG.d.mts} +63 -11
- package/dist/{index-nI-s3Exg.d.ts → index-BdYY-dvG.d.ts} +63 -11
- package/dist/index.d.mts +30 -12
- package/dist/index.d.ts +30 -12
- package/dist/index.js +72 -67
- package/dist/index.mjs +10 -5
- package/dist/navigation/index.js +13 -13
- package/dist/navigation/index.mjs +2 -2
- package/package.json +13 -5
package/README.md
CHANGED
|
@@ -33,6 +33,47 @@ function App() {
|
|
|
33
33
|
}
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
## What happens when Appilots breaks
|
|
37
|
+
|
|
38
|
+
The SDK renders inside your app, so a bug of ours must never become an
|
|
39
|
+
outage of yours. Both render surfaces sit behind an error boundary:
|
|
40
|
+
|
|
41
|
+
- If the **provider** throws, your app keeps rendering. The assistant
|
|
42
|
+
goes inert — `AppilotsChat` renders nothing, and `useAppilots()` keeps
|
|
43
|
+
returning a context (with `degraded: true`) so your own code does not
|
|
44
|
+
throw either.
|
|
45
|
+
- If the **chat** throws, only the chat disappears.
|
|
46
|
+
- If the **auto-tracking interceptor** throws on some element, that
|
|
47
|
+
element renders untouched; the agent just does not see it.
|
|
48
|
+
|
|
49
|
+
In every case we log a `console.error` that says plainly it is our bug,
|
|
50
|
+
not yours, and the failure is reported to the Appilots dashboard on the
|
|
51
|
+
next session so we find out without you having to file anything.
|
|
52
|
+
|
|
53
|
+
Degradation lasts for the session — a surface that crashed once usually
|
|
54
|
+
crashes again, and an assistant blinking in and out of your product is
|
|
55
|
+
worse than an absent one. An exception thrown by **your** components is
|
|
56
|
+
never swallowed: it propagates to your own error boundary as it would
|
|
57
|
+
without us.
|
|
58
|
+
|
|
59
|
+
## Native confirmation dialogs
|
|
60
|
+
|
|
61
|
+
When the user approves a destructive action on the chat's confirm card
|
|
62
|
+
and your code then calls `Alert.alert` to double-check, the SDK answers
|
|
63
|
+
that dialog once on their behalf — otherwise they are asked the same
|
|
64
|
+
question twice and the second dialog is one the agent cannot press.
|
|
65
|
+
|
|
66
|
+
Doing that means briefly replacing `Alert.alert`, a global that belongs
|
|
67
|
+
to your app. The replacement is refcounted, restored even if the action
|
|
68
|
+
throws, answers at most one dialog, never presses a `style: 'cancel'`
|
|
69
|
+
button, and expires about a second after the press so unrelated alerts
|
|
70
|
+
(background sync, push handlers) are never touched. To turn it off and
|
|
71
|
+
show your own dialog instead:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<AppilotsProvider config={{ projectId: '…', suppressNativeConfirm: false }}>
|
|
75
|
+
```
|
|
76
|
+
|
|
36
77
|
## Documentation
|
|
37
78
|
|
|
38
79
|
Full documentation available at [docs.appilots.com](https://docs.appilots.com)
|
|
@@ -82,7 +82,9 @@ var AppilotsClient = class {
|
|
|
82
82
|
"Content-Type": "application/json",
|
|
83
83
|
// Version telemetry: lets the server correlate behavior per SDK
|
|
84
84
|
// release and pick the MCP doc matching this app build (B.4).
|
|
85
|
-
|
|
85
|
+
// The platform SDK supplies its own published version; the
|
|
86
|
+
// client-core constant is only the fallback (see `sdkVersion`).
|
|
87
|
+
"X-Appilots-Sdk-Version": options.sdkVersion ?? SDK_VERSION,
|
|
86
88
|
...options.appVersion ? { "X-App-Version": options.appVersion } : {},
|
|
87
89
|
...options.mcpVersion ? { "X-Appilots-Mcp-Version": options.mcpVersion } : {},
|
|
88
90
|
...options.apiKey ? { Authorization: `Bearer ${options.apiKey}` } : {},
|
|
@@ -197,7 +199,8 @@ var AppilotsClient = class {
|
|
|
197
199
|
introspectionFragment() {
|
|
198
200
|
try {
|
|
199
201
|
const report = this.introspectionReporter?.();
|
|
200
|
-
if (!report
|
|
202
|
+
if (!report) return {};
|
|
203
|
+
if (report.captured !== false && !report.failureReason) return {};
|
|
201
204
|
return { introspection: report };
|
|
202
205
|
} catch {
|
|
203
206
|
return {};
|
|
@@ -2848,6 +2851,114 @@ function attachElementIdsToChoiceGroups(choiceGroups, elements) {
|
|
|
2848
2851
|
})
|
|
2849
2852
|
}));
|
|
2850
2853
|
}
|
|
2854
|
+
var WIRE_LIMITS = {
|
|
2855
|
+
route: 200,
|
|
2856
|
+
texts: 500,
|
|
2857
|
+
textLength: 2e3,
|
|
2858
|
+
inputs: 300,
|
|
2859
|
+
buttons: 300,
|
|
2860
|
+
toggles: 300,
|
|
2861
|
+
sliders: 100,
|
|
2862
|
+
lists: 100,
|
|
2863
|
+
listItems: 500,
|
|
2864
|
+
listDataPreview: 500,
|
|
2865
|
+
listDataPreviewTextLength: 500,
|
|
2866
|
+
choiceGroups: 100,
|
|
2867
|
+
choiceOptions: 200,
|
|
2868
|
+
elements: 1e3,
|
|
2869
|
+
elementTexts: 50,
|
|
2870
|
+
elementTextLength: 500,
|
|
2871
|
+
elementActions: 20,
|
|
2872
|
+
idLength: 160,
|
|
2873
|
+
labelLength: 300,
|
|
2874
|
+
valueLength: 4096,
|
|
2875
|
+
containerTypeLength: 60};
|
|
2876
|
+
var Cut = class {
|
|
2877
|
+
dropped = false;
|
|
2878
|
+
/** Cap an array's length, remembering whether entries were lost. */
|
|
2879
|
+
array(values, max) {
|
|
2880
|
+
if (!values || values.length <= max) return values;
|
|
2881
|
+
this.dropped = true;
|
|
2882
|
+
return values.slice(0, max);
|
|
2883
|
+
}
|
|
2884
|
+
string(value, max) {
|
|
2885
|
+
if (value === void 0 || value.length <= max) return value;
|
|
2886
|
+
this.dropped = true;
|
|
2887
|
+
return value.slice(0, max);
|
|
2888
|
+
}
|
|
2889
|
+
};
|
|
2890
|
+
function clampInput(cut, input) {
|
|
2891
|
+
input.id = cut.string(input.id, WIRE_LIMITS.idLength);
|
|
2892
|
+
input.label = cut.string(input.label, WIRE_LIMITS.labelLength);
|
|
2893
|
+
input.placeholder = cut.string(input.placeholder, WIRE_LIMITS.labelLength);
|
|
2894
|
+
input.value = cut.string(input.value, WIRE_LIMITS.valueLength);
|
|
2895
|
+
return input;
|
|
2896
|
+
}
|
|
2897
|
+
function clampList(cut, list) {
|
|
2898
|
+
list.id = cut.string(list.id, WIRE_LIMITS.idLength);
|
|
2899
|
+
list.containerType = cut.string(list.containerType, WIRE_LIMITS.containerTypeLength);
|
|
2900
|
+
list.label = cut.string(list.label, WIRE_LIMITS.labelLength);
|
|
2901
|
+
list.items = cut.array(list.items, WIRE_LIMITS.listItems) ?? [];
|
|
2902
|
+
if (list.dataPreview) {
|
|
2903
|
+
list.dataPreview = cut.array(list.dataPreview, WIRE_LIMITS.listDataPreview);
|
|
2904
|
+
for (const entry of list.dataPreview ?? []) {
|
|
2905
|
+
entry.key = cut.string(entry.key, WIRE_LIMITS.idLength);
|
|
2906
|
+
entry.text = cut.string(entry.text, WIRE_LIMITS.listDataPreviewTextLength);
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
return list;
|
|
2910
|
+
}
|
|
2911
|
+
function clampChoiceGroup(cut, group) {
|
|
2912
|
+
group.id = cut.string(group.id, WIRE_LIMITS.idLength);
|
|
2913
|
+
group.label = cut.string(group.label, WIRE_LIMITS.labelLength);
|
|
2914
|
+
group.options = cut.array(group.options, WIRE_LIMITS.choiceOptions) ?? [];
|
|
2915
|
+
return group;
|
|
2916
|
+
}
|
|
2917
|
+
function clampSnapshotToWireLimits(snapshot) {
|
|
2918
|
+
const cut = new Cut();
|
|
2919
|
+
if (typeof snapshot.route === "string") {
|
|
2920
|
+
snapshot.route = cut.string(snapshot.route, WIRE_LIMITS.route);
|
|
2921
|
+
}
|
|
2922
|
+
snapshot.texts = (cut.array(snapshot.texts, WIRE_LIMITS.texts) ?? []).map(
|
|
2923
|
+
(text) => cut.string(text, WIRE_LIMITS.textLength)
|
|
2924
|
+
);
|
|
2925
|
+
snapshot.inputs = (cut.array(snapshot.inputs, WIRE_LIMITS.inputs) ?? []).map(
|
|
2926
|
+
(input) => clampInput(cut, input)
|
|
2927
|
+
);
|
|
2928
|
+
snapshot.buttons = (cut.array(snapshot.buttons, WIRE_LIMITS.buttons) ?? []).map((button) => {
|
|
2929
|
+
button.id = cut.string(button.id, WIRE_LIMITS.idLength);
|
|
2930
|
+
button.label = cut.string(button.label, WIRE_LIMITS.labelLength);
|
|
2931
|
+
return button;
|
|
2932
|
+
});
|
|
2933
|
+
snapshot.toggles = (cut.array(snapshot.toggles, WIRE_LIMITS.toggles) ?? []).map((toggle) => {
|
|
2934
|
+
toggle.id = cut.string(toggle.id, WIRE_LIMITS.idLength);
|
|
2935
|
+
toggle.label = cut.string(toggle.label, WIRE_LIMITS.labelLength);
|
|
2936
|
+
return toggle;
|
|
2937
|
+
});
|
|
2938
|
+
snapshot.sliders = (cut.array(snapshot.sliders, WIRE_LIMITS.sliders) ?? []).map((slider) => {
|
|
2939
|
+
slider.id = cut.string(slider.id, WIRE_LIMITS.idLength);
|
|
2940
|
+
slider.label = cut.string(slider.label, WIRE_LIMITS.labelLength);
|
|
2941
|
+
return slider;
|
|
2942
|
+
});
|
|
2943
|
+
snapshot.lists = (cut.array(snapshot.lists, WIRE_LIMITS.lists) ?? []).map(
|
|
2944
|
+
(list) => clampList(cut, list)
|
|
2945
|
+
);
|
|
2946
|
+
snapshot.choiceGroups = (cut.array(snapshot.choiceGroups, WIRE_LIMITS.choiceGroups) ?? []).map(
|
|
2947
|
+
(group) => clampChoiceGroup(cut, group)
|
|
2948
|
+
);
|
|
2949
|
+
snapshot.elements = (cut.array(snapshot.elements, WIRE_LIMITS.elements) ?? []).map((element) => {
|
|
2950
|
+
element.id = cut.string(element.id, WIRE_LIMITS.idLength);
|
|
2951
|
+
element.label = cut.string(element.label, WIRE_LIMITS.labelLength);
|
|
2952
|
+
element.targetId = cut.string(element.targetId, WIRE_LIMITS.idLength);
|
|
2953
|
+
element.texts = (cut.array(element.texts, WIRE_LIMITS.elementTexts) ?? []).map(
|
|
2954
|
+
(text) => cut.string(text, WIRE_LIMITS.elementTextLength)
|
|
2955
|
+
);
|
|
2956
|
+
element.actions = cut.array(element.actions, WIRE_LIMITS.elementActions) ?? [];
|
|
2957
|
+
return element;
|
|
2958
|
+
});
|
|
2959
|
+
if (cut.dropped) snapshot.truncated = true;
|
|
2960
|
+
return snapshot;
|
|
2961
|
+
}
|
|
2851
2962
|
|
|
2852
2963
|
// src/registry/ComponentRegistry.ts
|
|
2853
2964
|
var ComponentRegistryImpl = class {
|
|
@@ -3125,6 +3236,40 @@ function sectionListFlatIndex(sections, section, localIndex) {
|
|
|
3125
3236
|
return base + localIndex;
|
|
3126
3237
|
}
|
|
3127
3238
|
|
|
3239
|
+
// src/auto/interceptGuard.ts
|
|
3240
|
+
var _intercept = null;
|
|
3241
|
+
var _failures = 0;
|
|
3242
|
+
var INTERCEPT_FAILURE_LIMIT = 25;
|
|
3243
|
+
function setInterceptor(fn) {
|
|
3244
|
+
_intercept = fn;
|
|
3245
|
+
_failures = 0;
|
|
3246
|
+
}
|
|
3247
|
+
function isInterceptionActive() {
|
|
3248
|
+
return _intercept !== null;
|
|
3249
|
+
}
|
|
3250
|
+
function safeIntercept(type, props) {
|
|
3251
|
+
const intercept = _intercept;
|
|
3252
|
+
if (!intercept) return null;
|
|
3253
|
+
try {
|
|
3254
|
+
return intercept(type, props);
|
|
3255
|
+
} catch (err) {
|
|
3256
|
+
_failures += 1;
|
|
3257
|
+
if (_failures === 1) {
|
|
3258
|
+
console.error(
|
|
3259
|
+
"[Appilots] Auto-tracking failed to inspect an element and passed it through unchanged. Your app is unaffected; the agent may not see this component. This is an Appilots bug \u2014 please report it: https://github.com/Axtern-Labs/Appilots/issues",
|
|
3260
|
+
err
|
|
3261
|
+
);
|
|
3262
|
+
}
|
|
3263
|
+
if (_failures >= INTERCEPT_FAILURE_LIMIT) {
|
|
3264
|
+
_intercept = null;
|
|
3265
|
+
console.error(
|
|
3266
|
+
`[Appilots] Auto-tracking disabled after ${INTERCEPT_FAILURE_LIMIT} failures. The agent will only see components registered explicitly via registerScreen(). Your app is unaffected.`
|
|
3267
|
+
);
|
|
3268
|
+
}
|
|
3269
|
+
return null;
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
|
|
3128
3273
|
// src/auto/enableAutoTracking.tsx
|
|
3129
3274
|
function extractId(props) {
|
|
3130
3275
|
const raw = props?.testID ?? props?.nativeID ?? props?.id ?? props?.accessibilityLabel ?? props?.name ?? props?.placeholder ?? (typeof props?.autoComplete === "string" && props.autoComplete !== "off" ? props.autoComplete : void 0);
|
|
@@ -3583,15 +3728,15 @@ function enableAppilotsAutoTracking(options) {
|
|
|
3583
3728
|
}
|
|
3584
3729
|
return null;
|
|
3585
3730
|
}
|
|
3731
|
+
setInterceptor(interceptType);
|
|
3586
3732
|
React2__default.default.createElement = function(type, props, ...children) {
|
|
3587
|
-
const replacement =
|
|
3733
|
+
const replacement = safeIntercept(type, props);
|
|
3588
3734
|
if (replacement) {
|
|
3589
3735
|
return originalCreateElement(replacement.type, replacement.props, ...children);
|
|
3590
3736
|
}
|
|
3591
3737
|
return originalCreateElement(type, props, ...children);
|
|
3592
3738
|
};
|
|
3593
3739
|
console.log("[Appilots] Auto-tracking: React.createElement patched");
|
|
3594
|
-
_interceptType = interceptType;
|
|
3595
3740
|
try {
|
|
3596
3741
|
const jsxRuntime = __require("react/jsx-runtime");
|
|
3597
3742
|
if (jsxRuntime) {
|
|
@@ -3609,18 +3754,16 @@ function enableAppilotsAutoTracking(options) {
|
|
|
3609
3754
|
console.log("[Appilots] Auto-tracking: react/jsx-dev-runtime not available internally (will be patched by metro shim)");
|
|
3610
3755
|
}
|
|
3611
3756
|
}
|
|
3612
|
-
var _interceptType = null;
|
|
3613
3757
|
var _jsxRuntimePatched = false;
|
|
3614
3758
|
var _jsxDevRuntimePatched = false;
|
|
3615
3759
|
function _patchJsxRuntimeModule(jsxRuntime) {
|
|
3616
|
-
if (_jsxRuntimePatched || !
|
|
3760
|
+
if (_jsxRuntimePatched || !isInterceptionActive() || !jsxRuntime) return;
|
|
3617
3761
|
_jsxRuntimePatched = true;
|
|
3618
|
-
const interceptType = _interceptType;
|
|
3619
3762
|
const origJsx = jsxRuntime.jsx;
|
|
3620
3763
|
const origJsxs = jsxRuntime.jsxs;
|
|
3621
3764
|
if (origJsx) {
|
|
3622
3765
|
jsxRuntime.jsx = function(type, props, key) {
|
|
3623
|
-
const replacement =
|
|
3766
|
+
const replacement = safeIntercept(type, props);
|
|
3624
3767
|
if (replacement) {
|
|
3625
3768
|
return origJsx(replacement.type, replacement.props, key);
|
|
3626
3769
|
}
|
|
@@ -3630,7 +3773,7 @@ function _patchJsxRuntimeModule(jsxRuntime) {
|
|
|
3630
3773
|
}
|
|
3631
3774
|
if (origJsxs) {
|
|
3632
3775
|
jsxRuntime.jsxs = function(type, props, key) {
|
|
3633
|
-
const replacement =
|
|
3776
|
+
const replacement = safeIntercept(type, props);
|
|
3634
3777
|
if (replacement) {
|
|
3635
3778
|
return origJsxs(replacement.type, replacement.props, key);
|
|
3636
3779
|
}
|
|
@@ -3640,13 +3783,12 @@ function _patchJsxRuntimeModule(jsxRuntime) {
|
|
|
3640
3783
|
}
|
|
3641
3784
|
}
|
|
3642
3785
|
function _patchJsxDevRuntimeModule(jsxDevRuntime) {
|
|
3643
|
-
if (_jsxDevRuntimePatched || !
|
|
3786
|
+
if (_jsxDevRuntimePatched || !isInterceptionActive() || !jsxDevRuntime) return;
|
|
3644
3787
|
_jsxDevRuntimePatched = true;
|
|
3645
|
-
const interceptType = _interceptType;
|
|
3646
3788
|
if (jsxDevRuntime.jsxDEV) {
|
|
3647
3789
|
const origJsxDEV = jsxDevRuntime.jsxDEV;
|
|
3648
3790
|
jsxDevRuntime.jsxDEV = function(type, props, key, isStaticChildren, source, self) {
|
|
3649
|
-
const replacement =
|
|
3791
|
+
const replacement = safeIntercept(type, props);
|
|
3650
3792
|
if (replacement) {
|
|
3651
3793
|
return origJsxDEV(replacement.type, replacement.props, key, isStaticChildren, source, self);
|
|
3652
3794
|
}
|
|
@@ -3656,7 +3798,7 @@ function _patchJsxDevRuntimeModule(jsxDevRuntime) {
|
|
|
3656
3798
|
}
|
|
3657
3799
|
}
|
|
3658
3800
|
function _patchJsxRuntimes(jsxRuntime, jsxDevRuntime) {
|
|
3659
|
-
if (!
|
|
3801
|
+
if (!isInterceptionActive()) {
|
|
3660
3802
|
console.warn("[Appilots] _patchJsxRuntimes called but auto-tracking is not enabled");
|
|
3661
3803
|
return;
|
|
3662
3804
|
}
|
|
@@ -3726,7 +3868,14 @@ function setFiberRoot(fiber) {
|
|
|
3726
3868
|
_diagnostics.captured = true;
|
|
3727
3869
|
}
|
|
3728
3870
|
function getFiberRoot() {
|
|
3729
|
-
return _fiberRoot;
|
|
3871
|
+
return resolveCurrentRoot(_fiberRoot);
|
|
3872
|
+
}
|
|
3873
|
+
function resolveCurrentRoot(fiber) {
|
|
3874
|
+
const current = fiber?.stateNode?.current;
|
|
3875
|
+
if (current && (current === fiber || current.alternate === fiber)) {
|
|
3876
|
+
return current;
|
|
3877
|
+
}
|
|
3878
|
+
return fiber;
|
|
3730
3879
|
}
|
|
3731
3880
|
function recordIntrospectionFailure(reason, reactVersion) {
|
|
3732
3881
|
_diagnostics.failureCount += 1;
|
|
@@ -3735,6 +3884,13 @@ function recordIntrospectionFailure(reason, reactVersion) {
|
|
|
3735
3884
|
_diagnostics.reactVersion = reactVersion;
|
|
3736
3885
|
}
|
|
3737
3886
|
}
|
|
3887
|
+
function recordRenderFailure(reactVersion) {
|
|
3888
|
+
_fiberRoot = null;
|
|
3889
|
+
_diagnostics.captured = false;
|
|
3890
|
+
_diagnostics.failureCount += 1;
|
|
3891
|
+
_diagnostics.failureReason = "render-crashed";
|
|
3892
|
+
_diagnostics.reactVersion = reactVersion;
|
|
3893
|
+
}
|
|
3738
3894
|
function getIntrospectionDiagnostics() {
|
|
3739
3895
|
return { ..._diagnostics };
|
|
3740
3896
|
}
|
|
@@ -3746,6 +3902,9 @@ function typeName(fiber) {
|
|
|
3746
3902
|
if (typeof t === "object") return t.displayName ?? t.render?.displayName ?? t.render?.name ?? "forwardRef/memo";
|
|
3747
3903
|
return String(t);
|
|
3748
3904
|
}
|
|
3905
|
+
|
|
3906
|
+
// src/version.ts
|
|
3907
|
+
var SDK_VERSION2 = "0.8.0";
|
|
3749
3908
|
var FiberSentinel = class extends React2__default.default.Component {
|
|
3750
3909
|
componentDidMount() {
|
|
3751
3910
|
const fiber = this._reactInternals ?? this._reactInternalFiber ?? null;
|
|
@@ -3795,10 +3954,83 @@ function appilotsDebugWarn(...args) {
|
|
|
3795
3954
|
if (!isDebugEnabled()) return;
|
|
3796
3955
|
console.log("[Appilots]", ...args);
|
|
3797
3956
|
}
|
|
3957
|
+
var AppilotsErrorBoundary = class extends React2__default.default.Component {
|
|
3958
|
+
state = { degraded: false, escalate: null };
|
|
3959
|
+
/**
|
|
3960
|
+
* Instance field rather than state: `componentDidCatch` needs to know
|
|
3961
|
+
* whether THIS is the first failure, and by the time it runs
|
|
3962
|
+
* `getDerivedStateFromError` has already flipped `state.degraded`.
|
|
3963
|
+
*/
|
|
3964
|
+
hasDegradedOnce = false;
|
|
3965
|
+
static getDerivedStateFromError() {
|
|
3966
|
+
return { degraded: true };
|
|
3967
|
+
}
|
|
3968
|
+
componentDidCatch(error, info) {
|
|
3969
|
+
if (this.hasDegradedOnce) {
|
|
3970
|
+
this.setState({ escalate: error ?? new Error("Appilots: re-thrown host render error") });
|
|
3971
|
+
return;
|
|
3972
|
+
}
|
|
3973
|
+
this.hasDegradedOnce = true;
|
|
3974
|
+
console.error(
|
|
3975
|
+
`[Appilots] The Appilots ${this.props.surface} threw while rendering and has been disabled for the rest of this session. Your app keeps running \u2014 this is an Appilots bug, not a bug in your code. Please report it with the stack below: https://github.com/Axtern-Labs/Appilots/issues`,
|
|
3976
|
+
error
|
|
3977
|
+
);
|
|
3978
|
+
try {
|
|
3979
|
+
this.props.onError?.(error, info?.componentStack ?? null);
|
|
3980
|
+
} catch {
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
render() {
|
|
3984
|
+
if (this.state.escalate !== null) throw this.state.escalate;
|
|
3985
|
+
if (this.state.degraded) return this.props.fallback;
|
|
3986
|
+
return this.props.children;
|
|
3987
|
+
}
|
|
3988
|
+
};
|
|
3798
3989
|
|
|
3799
3990
|
// src/context/AppilotsProvider.tsx
|
|
3800
3991
|
var AppilotsContext = React2.createContext(null);
|
|
3801
|
-
function
|
|
3992
|
+
function createInertClient() {
|
|
3993
|
+
const unavailable = () => Promise.reject(
|
|
3994
|
+
new Error("Appilots is unavailable: the SDK degraded after a render error.")
|
|
3995
|
+
);
|
|
3996
|
+
return new Proxy({}, {
|
|
3997
|
+
get: (_target, prop) => {
|
|
3998
|
+
if (prop === "then" || typeof prop === "symbol") return void 0;
|
|
3999
|
+
return unavailable;
|
|
4000
|
+
}
|
|
4001
|
+
});
|
|
4002
|
+
}
|
|
4003
|
+
function createDegradedContext(config) {
|
|
4004
|
+
return {
|
|
4005
|
+
config: config ?? { projectId: "" },
|
|
4006
|
+
client: createInertClient(),
|
|
4007
|
+
subscribe: () => () => {
|
|
4008
|
+
},
|
|
4009
|
+
emit: () => {
|
|
4010
|
+
},
|
|
4011
|
+
remotePersonalization: null,
|
|
4012
|
+
degraded: true
|
|
4013
|
+
};
|
|
4014
|
+
}
|
|
4015
|
+
function AppilotsProvider({ config, children, client }) {
|
|
4016
|
+
return /* @__PURE__ */ React2__default.default.createElement(
|
|
4017
|
+
AppilotsErrorBoundary,
|
|
4018
|
+
{
|
|
4019
|
+
surface: "provider",
|
|
4020
|
+
onError: reportProviderRenderFailure,
|
|
4021
|
+
fallback: /* @__PURE__ */ React2__default.default.createElement(AppilotsContext.Provider, { value: createDegradedContext(config ?? null) }, children)
|
|
4022
|
+
},
|
|
4023
|
+
/* @__PURE__ */ React2__default.default.createElement(AppilotsProviderInner, { config, client }, children)
|
|
4024
|
+
);
|
|
4025
|
+
}
|
|
4026
|
+
function reportProviderRenderFailure() {
|
|
4027
|
+
recordRenderFailure(readReactVersion());
|
|
4028
|
+
}
|
|
4029
|
+
function readReactVersion() {
|
|
4030
|
+
const version = React2__default.default.version;
|
|
4031
|
+
return typeof version === "string" ? version : null;
|
|
4032
|
+
}
|
|
4033
|
+
function AppilotsProviderInner({ config: configProp, children, client: externalClient }) {
|
|
3802
4034
|
console.log(`[Appilots] AppilotsProvider initializing \u2014 config source: ${configProp ? "prop" : "auto (globalThis.__APPILOTS_RC__)"}`);
|
|
3803
4035
|
tryAutoConfig();
|
|
3804
4036
|
const globalConfig = getGlobalConfig();
|
|
@@ -3811,7 +4043,8 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3811
4043
|
debug: globalConfig.debug,
|
|
3812
4044
|
appVersion: globalConfig.appVersion,
|
|
3813
4045
|
mcpVersion: globalConfig.mcpVersion,
|
|
3814
|
-
fetchPersonalization: globalConfig.fetchPersonalization
|
|
4046
|
+
fetchPersonalization: globalConfig.fetchPersonalization,
|
|
4047
|
+
suppressNativeConfirm: globalConfig.suppressNativeConfirm
|
|
3815
4048
|
} : null);
|
|
3816
4049
|
if (!config?.projectId) {
|
|
3817
4050
|
throw new Error(
|
|
@@ -3850,6 +4083,9 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3850
4083
|
debug: config.debug,
|
|
3851
4084
|
appVersion: config.appVersion,
|
|
3852
4085
|
mcpVersion: config.mcpVersion,
|
|
4086
|
+
// This package's published version, so the server knows which
|
|
4087
|
+
// SDK is actually in the field (issue #312).
|
|
4088
|
+
sdkVersion: SDK_VERSION2,
|
|
3853
4089
|
user: config.user,
|
|
3854
4090
|
// Only reports a FAILED reading; the happy path sends nothing.
|
|
3855
4091
|
introspectionReporter: getIntrospectionDiagnostics
|
|
@@ -4394,17 +4630,19 @@ function clearScreenRegistry() {
|
|
|
4394
4630
|
|
|
4395
4631
|
exports.ActionQueueMachine = ActionQueueMachine;
|
|
4396
4632
|
exports.AppilotsClient = AppilotsClient;
|
|
4633
|
+
exports.AppilotsErrorBoundary = AppilotsErrorBoundary;
|
|
4397
4634
|
exports.AppilotsProvider = AppilotsProvider;
|
|
4398
4635
|
exports.AppilotsRegistryProvider = AppilotsRegistryProvider;
|
|
4399
4636
|
exports.ChatSessionMachine = ChatSessionMachine;
|
|
4400
4637
|
exports.OPTIONAL_STEP_AUTOMATION_HINT = OPTIONAL_STEP_AUTOMATION_HINT;
|
|
4401
4638
|
exports.RateLimitedError = RateLimitedError;
|
|
4402
|
-
exports.SDK_VERSION =
|
|
4639
|
+
exports.SDK_VERSION = SDK_VERSION2;
|
|
4403
4640
|
exports._patchJsxRuntimes = _patchJsxRuntimes;
|
|
4404
4641
|
exports.actionPressTargetId = actionPressTargetId;
|
|
4405
4642
|
exports.appilotsDebugLog = appilotsDebugLog;
|
|
4406
4643
|
exports.appilotsDebugWarn = appilotsDebugWarn;
|
|
4407
4644
|
exports.attachElementIdsToChoiceGroups = attachElementIdsToChoiceGroups;
|
|
4645
|
+
exports.clampSnapshotToWireLimits = clampSnapshotToWireLimits;
|
|
4408
4646
|
exports.clearAppilotsDebugTraces = clearAppilotsDebugTraces;
|
|
4409
4647
|
exports.clearScreenRegistry = clearScreenRegistry;
|
|
4410
4648
|
exports.componentRegistry = componentRegistry;
|