@appilots/sdk 0.4.1 → 0.6.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/dist/{chunk-P2BR4DFF.mjs → chunk-DR75QTYK.mjs} +1 -1
- package/dist/{chunk-J75B2HWG.js → chunk-DZ7QRFHD.js} +130 -10
- package/dist/{chunk-YSLDAQV7.js → chunk-HFRIB4YN.js} +160 -159
- package/dist/{chunk-L2A4EZ6V.mjs → chunk-KUFWRJC4.mjs} +2 -1
- package/dist/{chunk-ZWPABTLA.js → chunk-KYFAXT6V.js} +5 -5
- package/dist/{chunk-4GUPZDWT.mjs → chunk-R4D34FEW.mjs} +128 -11
- 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-Cb0D6uKH.d.mts → index-nI-s3Exg.d.mts} +56 -2
- package/dist/{index-Cb0D6uKH.d.ts → index-nI-s3Exg.d.ts} +56 -2
- package/dist/index.d.mts +40 -3
- package/dist/index.d.ts +40 -3
- package/dist/index.js +73 -65
- package/dist/index.mjs +5 -5
- package/dist/navigation/index.js +13 -13
- package/dist/navigation/index.mjs +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useAppilotsContext, setNavigationRef, setCurrentScreen } from './chunk-
|
|
1
|
+
import { useAppilotsContext, setNavigationRef, setCurrentScreen } from './chunk-R4D34FEW.mjs';
|
|
2
2
|
import React, { useRef, useCallback, useEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
function getActiveRouteName(state) {
|
|
@@ -42,6 +42,21 @@ var StreamAbortError = class extends Error {
|
|
|
42
42
|
this.partialContent = partialContent;
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
+
var RateLimitedError = class extends Error {
|
|
46
|
+
retryAfterSeconds;
|
|
47
|
+
constructor(message, retryAfterSeconds) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.name = "RateLimitedError";
|
|
50
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
function parseRetryAfter(...candidates) {
|
|
54
|
+
for (const candidate of candidates) {
|
|
55
|
+
const seconds = Number(candidate);
|
|
56
|
+
if (Number.isFinite(seconds) && seconds > 0) return Math.ceil(seconds);
|
|
57
|
+
}
|
|
58
|
+
return 60;
|
|
59
|
+
}
|
|
45
60
|
var CONTINUATION_TIMEOUT_MS = 15e4;
|
|
46
61
|
var AppilotsClient = class {
|
|
47
62
|
baseUrl;
|
|
@@ -50,6 +65,7 @@ var AppilotsClient = class {
|
|
|
50
65
|
timeout;
|
|
51
66
|
debug;
|
|
52
67
|
mcpVersion;
|
|
68
|
+
introspectionReporter;
|
|
53
69
|
user;
|
|
54
70
|
sessionId = null;
|
|
55
71
|
/** Guard so identify fires at most once per client instance. */
|
|
@@ -60,6 +76,7 @@ var AppilotsClient = class {
|
|
|
60
76
|
this.timeout = options.timeout ?? 6e4;
|
|
61
77
|
this.debug = options.debug ?? false;
|
|
62
78
|
this.mcpVersion = options.mcpVersion;
|
|
79
|
+
this.introspectionReporter = options.introspectionReporter;
|
|
63
80
|
this.user = options.user;
|
|
64
81
|
this.headers = {
|
|
65
82
|
"Content-Type": "application/json",
|
|
@@ -104,6 +121,15 @@ var AppilotsClient = class {
|
|
|
104
121
|
}
|
|
105
122
|
if (!response.ok) {
|
|
106
123
|
const errorMsg = json?.error?.message ?? json?.error ?? `HTTP ${response.status}`;
|
|
124
|
+
if (response.status === 429) {
|
|
125
|
+
throw new RateLimitedError(
|
|
126
|
+
errorMsg,
|
|
127
|
+
parseRetryAfter(
|
|
128
|
+
json?.error?.retryAfterSeconds,
|
|
129
|
+
response.headers?.get?.("retry-after")
|
|
130
|
+
)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
107
133
|
throw new Error(errorMsg);
|
|
108
134
|
}
|
|
109
135
|
return json.data ?? json;
|
|
@@ -162,6 +188,21 @@ var AppilotsClient = class {
|
|
|
162
188
|
getSessionId() {
|
|
163
189
|
return this.sessionId;
|
|
164
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Wire fragment for introspection health. Empty on the happy path —
|
|
193
|
+
* a working client sends nothing, so the field costs a byte only
|
|
194
|
+
* when something is actually wrong. Never throws: a broken reporter
|
|
195
|
+
* must not take the message down with it.
|
|
196
|
+
*/
|
|
197
|
+
introspectionFragment() {
|
|
198
|
+
try {
|
|
199
|
+
const report = this.introspectionReporter?.();
|
|
200
|
+
if (!report || report.captured !== false) return {};
|
|
201
|
+
return { introspection: report };
|
|
202
|
+
} catch {
|
|
203
|
+
return {};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
165
206
|
// ── Messages ──────────────────────────────────────────────────
|
|
166
207
|
async sendMessage(content, context) {
|
|
167
208
|
if (!this.sessionId) {
|
|
@@ -175,7 +216,8 @@ var AppilotsClient = class {
|
|
|
175
216
|
context,
|
|
176
217
|
// Optional MCP version bundled with this app build. Server
|
|
177
218
|
// compares vs the active MCP doc to detect stale uploads.
|
|
178
|
-
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {}
|
|
219
|
+
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
|
|
220
|
+
...this.introspectionFragment()
|
|
179
221
|
})
|
|
180
222
|
});
|
|
181
223
|
if (data.sessionId) {
|
|
@@ -332,11 +374,25 @@ var AppilotsClient = class {
|
|
|
332
374
|
const contentType = String(xhr.getResponseHeader?.("content-type") ?? "");
|
|
333
375
|
if (xhr.status !== 200 || !contentType.includes("text/event-stream")) {
|
|
334
376
|
let message2 = `HTTP ${xhr.status || 0}`;
|
|
377
|
+
let retryAfterSeconds;
|
|
335
378
|
try {
|
|
336
379
|
const json = JSON.parse(xhr.responseText || "{}");
|
|
337
380
|
message2 = json?.error?.message ?? json?.error ?? message2;
|
|
381
|
+
retryAfterSeconds = json?.error?.retryAfterSeconds;
|
|
338
382
|
} catch {
|
|
339
383
|
}
|
|
384
|
+
if (xhr.status === 429) {
|
|
385
|
+
fail(
|
|
386
|
+
new RateLimitedError(
|
|
387
|
+
message2,
|
|
388
|
+
parseRetryAfter(
|
|
389
|
+
retryAfterSeconds,
|
|
390
|
+
xhr.getResponseHeader?.("retry-after")
|
|
391
|
+
)
|
|
392
|
+
)
|
|
393
|
+
);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
340
396
|
fail(
|
|
341
397
|
sawAnyEvent ? new Error(message2) : new StreamTransportError(message2)
|
|
342
398
|
);
|
|
@@ -402,7 +458,8 @@ var AppilotsClient = class {
|
|
|
402
458
|
content,
|
|
403
459
|
sessionId: this.sessionId,
|
|
404
460
|
context,
|
|
405
|
-
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {}
|
|
461
|
+
...this.mcpVersion ? { mcpVersion: this.mcpVersion } : {},
|
|
462
|
+
...this.introspectionFragment()
|
|
406
463
|
})
|
|
407
464
|
);
|
|
408
465
|
});
|
|
@@ -923,25 +980,41 @@ function detectLocaleFromUserTexts(texts) {
|
|
|
923
980
|
var copy = {
|
|
924
981
|
pt: {
|
|
925
982
|
rateLimit: "O provedor de IA atingiu o limite de uso durante a automa\xE7\xE3o. Aguarde um momento e pe\xE7a para continuar, ou aumente o limite de tokens por minuto.",
|
|
983
|
+
platformRateLimit: (wait) => `Recebi pedidos demais em pouco tempo e precisei pausar. Tente de novo em ${wait}.`,
|
|
926
984
|
invalidInput: "N\xE3o consegui continuar a automa\xE7\xE3o por um problema interno de sincroniza\xE7\xE3o. Pode tentar de novo ou fazer essa parte manualmente?",
|
|
927
985
|
generic: (detail) => `Perdi o fio da automa\xE7\xE3o (${detail}). Pode continuar manualmente ou me pedir de novo?`
|
|
928
986
|
},
|
|
929
987
|
es: {
|
|
930
988
|
rateLimit: "El proveedor de IA alcanz\xF3 su l\xEDmite de uso durante la automatizaci\xF3n. Espera un momento y p\xEDdeme continuar, o aumenta el l\xEDmite de tokens por minuto.",
|
|
989
|
+
platformRateLimit: (wait) => `Recib\xED demasiadas solicitudes en poco tiempo y tuve que pausar. Int\xE9ntalo de nuevo en ${wait}.`,
|
|
931
990
|
invalidInput: "No pude continuar la automatizaci\xF3n por un problema interno de sincronizaci\xF3n. \xBFPuedes intentarlo de nuevo o hacer esta parte manualmente?",
|
|
932
991
|
generic: (detail) => `Perd\xED el hilo de la automatizaci\xF3n (${detail}). \xBFPuedes continuar manualmente o ped\xEDrmelo de nuevo?`
|
|
933
992
|
},
|
|
934
993
|
fr: {
|
|
935
994
|
rateLimit: "Le fournisseur d'IA a atteint sa limite d'utilisation pendant l'automatisation. Attendez un instant et demandez-moi de continuer, ou augmentez la limite de tokens par minute.",
|
|
995
|
+
platformRateLimit: (wait) => `J'ai re\xE7u trop de demandes en peu de temps et j'ai d\xFB faire une pause. R\xE9essayez dans ${wait}.`,
|
|
936
996
|
invalidInput: "Je n'ai pas pu poursuivre l'automatisation \xE0 cause d'un probl\xE8me interne de synchronisation. Pouvez-vous r\xE9essayer ou faire cette \xE9tape manuellement ?",
|
|
937
997
|
generic: (detail) => `J'ai perdu le fil de l'automatisation (${detail}). Vous pouvez continuer manuellement ou me redemander ?`
|
|
938
998
|
},
|
|
939
999
|
en: {
|
|
940
1000
|
rateLimit: "Your AI provider hit its rate limit during automation. Wait a moment and ask me to continue, or raise your TPM limit.",
|
|
1001
|
+
platformRateLimit: (wait) => `I got too many requests in a short time and had to pause. Try again in ${wait}.`,
|
|
941
1002
|
invalidInput: "I could not continue the automation because of an internal sync issue. You can try again or take over manually.",
|
|
942
1003
|
generic: (detail) => `I lost my footing during automation (${detail}). You can take over from here.`
|
|
943
1004
|
}
|
|
944
1005
|
};
|
|
1006
|
+
var waitPhrase = {
|
|
1007
|
+
pt: (s) => s < 90 ? `${Math.ceil(s)} segundos` : `cerca de ${Math.ceil(s / 60)} minutos`,
|
|
1008
|
+
es: (s) => s < 90 ? `${Math.ceil(s)} segundos` : `unos ${Math.ceil(s / 60)} minutos`,
|
|
1009
|
+
fr: (s) => s < 90 ? `${Math.ceil(s)} secondes` : `environ ${Math.ceil(s / 60)} minutes`,
|
|
1010
|
+
en: (s) => s < 90 ? `${Math.ceil(s)} seconds` : `about ${Math.ceil(s / 60)} minutes`
|
|
1011
|
+
};
|
|
1012
|
+
function buildRateLimitedMessage(retryAfterSeconds, recentUserTexts) {
|
|
1013
|
+
const locale = detectLocaleFromUserTexts(recentUserTexts);
|
|
1014
|
+
const strings = copy[locale] ?? copy.en;
|
|
1015
|
+
const seconds = Number.isFinite(retryAfterSeconds) && retryAfterSeconds > 0 ? retryAfterSeconds : 60;
|
|
1016
|
+
return strings.platformRateLimit(waitPhrase[locale](seconds));
|
|
1017
|
+
}
|
|
945
1018
|
function buildContinuationFailureMessage(rawError, recentUserTexts) {
|
|
946
1019
|
const locale = detectLocaleFromUserTexts(recentUserTexts);
|
|
947
1020
|
const strings = copy[locale] ?? copy.en;
|
|
@@ -1545,7 +1618,7 @@ var ChatSessionMachine = class {
|
|
|
1545
1618
|
const raw = err instanceof Error ? err.message : "Continuation failed";
|
|
1546
1619
|
this.warn("ChatSessionMachine: continuation failed \u2014", raw);
|
|
1547
1620
|
const recentUserTexts = this.state.messages.filter((m) => m.role === "user").slice(-4).map((m) => m.content);
|
|
1548
|
-
const friendly = buildContinuationFailureMessage(raw, recentUserTexts);
|
|
1621
|
+
const friendly = err instanceof RateLimitedError ? buildRateLimitedMessage(err.retryAfterSeconds, recentUserTexts) : buildContinuationFailureMessage(raw, recentUserTexts);
|
|
1549
1622
|
this.addAssistantMessage({
|
|
1550
1623
|
id: `error_${++this.messageIdCounter}`,
|
|
1551
1624
|
role: "assistant",
|
|
@@ -1707,6 +1780,17 @@ var ChatSessionMachine = class {
|
|
|
1707
1780
|
removeStreamingPlaceholder();
|
|
1708
1781
|
const errorMessage = err instanceof Error ? err.message : "Failed to send message";
|
|
1709
1782
|
this.setState({ error: errorMessage });
|
|
1783
|
+
if (err instanceof RateLimitedError) {
|
|
1784
|
+
const recentUserTexts = this.state.messages.filter((m) => m.role === "user").slice(-4).map((m) => m.content);
|
|
1785
|
+
this.addAssistantMessage({
|
|
1786
|
+
id: `error_${++this.messageIdCounter}`,
|
|
1787
|
+
role: "assistant",
|
|
1788
|
+
content: buildRateLimitedMessage(err.retryAfterSeconds, recentUserTexts),
|
|
1789
|
+
timestamp: Date.now()
|
|
1790
|
+
});
|
|
1791
|
+
this.setState({ isLoading: false, loadingStatusKey: "thinking" });
|
|
1792
|
+
return;
|
|
1793
|
+
}
|
|
1710
1794
|
this.addAssistantMessage({
|
|
1711
1795
|
id: `error_${++this.messageIdCounter}`,
|
|
1712
1796
|
role: "assistant",
|
|
@@ -3628,15 +3712,32 @@ function getGlobalConfig() {
|
|
|
3628
3712
|
|
|
3629
3713
|
// src/introspection/fiberRoot.ts
|
|
3630
3714
|
var _fiberRoot = null;
|
|
3715
|
+
var _diagnostics = {
|
|
3716
|
+
captured: false,
|
|
3717
|
+
failureReason: null,
|
|
3718
|
+
reactVersion: null,
|
|
3719
|
+
failureCount: 0
|
|
3720
|
+
};
|
|
3631
3721
|
function setFiberRoot(fiber) {
|
|
3632
3722
|
if (_fiberRoot !== fiber) {
|
|
3633
3723
|
console.log(`[Appilots] Introspection: fiber root captured (type=${typeName(fiber)})`);
|
|
3634
3724
|
_fiberRoot = fiber;
|
|
3635
3725
|
}
|
|
3726
|
+
_diagnostics.captured = true;
|
|
3636
3727
|
}
|
|
3637
3728
|
function getFiberRoot() {
|
|
3638
3729
|
return _fiberRoot;
|
|
3639
3730
|
}
|
|
3731
|
+
function recordIntrospectionFailure(reason, reactVersion) {
|
|
3732
|
+
_diagnostics.failureCount += 1;
|
|
3733
|
+
if (_diagnostics.failureReason === null) {
|
|
3734
|
+
_diagnostics.failureReason = reason;
|
|
3735
|
+
_diagnostics.reactVersion = reactVersion;
|
|
3736
|
+
}
|
|
3737
|
+
}
|
|
3738
|
+
function getIntrospectionDiagnostics() {
|
|
3739
|
+
return { ..._diagnostics };
|
|
3740
|
+
}
|
|
3640
3741
|
function typeName(fiber) {
|
|
3641
3742
|
const t = fiber?.type ?? fiber?.elementType;
|
|
3642
3743
|
if (!t) return "unknown";
|
|
@@ -3645,15 +3746,16 @@ function typeName(fiber) {
|
|
|
3645
3746
|
if (typeof t === "object") return t.displayName ?? t.render?.displayName ?? t.render?.name ?? "forwardRef/memo";
|
|
3646
3747
|
return String(t);
|
|
3647
3748
|
}
|
|
3648
|
-
|
|
3649
|
-
// src/introspection/AppilotsFiberRoot.tsx
|
|
3650
3749
|
var FiberSentinel = class extends React2__default.default.Component {
|
|
3651
3750
|
componentDidMount() {
|
|
3652
3751
|
const fiber = this._reactInternals ?? this._reactInternalFiber ?? null;
|
|
3653
3752
|
if (!fiber) {
|
|
3753
|
+
const reactVersion = React2__default.default.version ?? null;
|
|
3654
3754
|
console.warn(
|
|
3655
|
-
|
|
3755
|
+
`[Appilots] FiberSentinel: this._reactInternals is undefined; snapshot capture will fall back to render-time owner. React version may be incompatible (react=${reactVersion}).`
|
|
3656
3756
|
);
|
|
3757
|
+
recordIntrospectionFailure("sentinel-missing-internals", reactVersion);
|
|
3758
|
+
this.props.onUnavailable?.({ reactVersion });
|
|
3657
3759
|
return;
|
|
3658
3760
|
}
|
|
3659
3761
|
let top = fiber;
|
|
@@ -3664,13 +3766,16 @@ var FiberSentinel = class extends React2__default.default.Component {
|
|
|
3664
3766
|
return this.props.children ?? null;
|
|
3665
3767
|
}
|
|
3666
3768
|
};
|
|
3667
|
-
function AppilotsFiberRoot({
|
|
3769
|
+
function AppilotsFiberRoot({
|
|
3770
|
+
children,
|
|
3771
|
+
onUnavailable
|
|
3772
|
+
}) {
|
|
3668
3773
|
const Internals = React2__default.default.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED_IN_THIS_VERSION_OF_REACT;
|
|
3669
3774
|
const ownerFiber = Internals?.ReactCurrentOwner?.current;
|
|
3670
3775
|
if (ownerFiber && !getFiberRoot()) {
|
|
3671
3776
|
setFiberRoot(ownerFiber);
|
|
3672
3777
|
}
|
|
3673
|
-
return /* @__PURE__ */ React2__default.default.createElement(FiberSentinel,
|
|
3778
|
+
return /* @__PURE__ */ React2__default.default.createElement(FiberSentinel, { onUnavailable }, children);
|
|
3674
3779
|
}
|
|
3675
3780
|
|
|
3676
3781
|
// src/debug/logger.ts
|
|
@@ -3727,6 +3832,16 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3727
3832
|
recordAppilotsEventTrace(event);
|
|
3728
3833
|
listenersRef.current.forEach((handler) => handler(event));
|
|
3729
3834
|
}, []);
|
|
3835
|
+
const handleIntrospectionUnavailable = React2.useCallback(
|
|
3836
|
+
({ reactVersion }) => {
|
|
3837
|
+
emit({
|
|
3838
|
+
type: "sdk:introspection:unavailable",
|
|
3839
|
+
timestamp: Date.now(),
|
|
3840
|
+
data: { reason: "sentinel-missing-internals", reactVersion }
|
|
3841
|
+
});
|
|
3842
|
+
},
|
|
3843
|
+
[emit]
|
|
3844
|
+
);
|
|
3730
3845
|
const client = React2.useMemo(
|
|
3731
3846
|
() => externalClient ?? new AppilotsClient({
|
|
3732
3847
|
projectId: config.projectId,
|
|
@@ -3735,7 +3850,9 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3735
3850
|
debug: config.debug,
|
|
3736
3851
|
appVersion: config.appVersion,
|
|
3737
3852
|
mcpVersion: config.mcpVersion,
|
|
3738
|
-
user: config.user
|
|
3853
|
+
user: config.user,
|
|
3854
|
+
// Only reports a FAILED reading; the happy path sends nothing.
|
|
3855
|
+
introspectionReporter: getIntrospectionDiagnostics
|
|
3739
3856
|
}),
|
|
3740
3857
|
[config.projectId, config.apiBaseUrl, config.apiKey, config.debug, config.appVersion, config.mcpVersion, config.user, externalClient]
|
|
3741
3858
|
);
|
|
@@ -3756,7 +3873,7 @@ function AppilotsProvider({ config: configProp, children, client: externalClient
|
|
|
3756
3873
|
() => ({ config, client, subscribe, emit, remotePersonalization }),
|
|
3757
3874
|
[config, client, subscribe, emit, remotePersonalization]
|
|
3758
3875
|
);
|
|
3759
|
-
return /* @__PURE__ */ React2__default.default.createElement(AppilotsContext.Provider, { value }, /* @__PURE__ */ React2__default.default.createElement(AppilotsFiberRoot,
|
|
3876
|
+
return /* @__PURE__ */ React2__default.default.createElement(AppilotsContext.Provider, { value }, /* @__PURE__ */ React2__default.default.createElement(AppilotsFiberRoot, { onUnavailable: handleIntrospectionUnavailable }, children));
|
|
3760
3877
|
}
|
|
3761
3878
|
function useAppilotsContext() {
|
|
3762
3879
|
const context = React2.useContext(AppilotsContext);
|
|
@@ -4281,6 +4398,7 @@ exports.AppilotsProvider = AppilotsProvider;
|
|
|
4281
4398
|
exports.AppilotsRegistryProvider = AppilotsRegistryProvider;
|
|
4282
4399
|
exports.ChatSessionMachine = ChatSessionMachine;
|
|
4283
4400
|
exports.OPTIONAL_STEP_AUTOMATION_HINT = OPTIONAL_STEP_AUTOMATION_HINT;
|
|
4401
|
+
exports.RateLimitedError = RateLimitedError;
|
|
4284
4402
|
exports.SDK_VERSION = SDK_VERSION;
|
|
4285
4403
|
exports._patchJsxRuntimes = _patchJsxRuntimes;
|
|
4286
4404
|
exports.actionPressTargetId = actionPressTargetId;
|
|
@@ -4307,6 +4425,7 @@ exports.getCurrentScreenSignature = getCurrentScreenSignature;
|
|
|
4307
4425
|
exports.getDefaultRegistry = getDefaultRegistry;
|
|
4308
4426
|
exports.getFiberRoot = getFiberRoot;
|
|
4309
4427
|
exports.getGlobalConfig = getGlobalConfig;
|
|
4428
|
+
exports.getIntrospectionDiagnostics = getIntrospectionDiagnostics;
|
|
4310
4429
|
exports.getNavigationRef = getNavigationRef;
|
|
4311
4430
|
exports.getNavigationStateSnapshot = getNavigationStateSnapshot;
|
|
4312
4431
|
exports.getScreenMetadata = getScreenMetadata;
|
|
@@ -4325,6 +4444,7 @@ exports.normalize3 = normalize3;
|
|
|
4325
4444
|
exports.parseStableElementId = parseStableElementId;
|
|
4326
4445
|
exports.probeLoadingState = probeLoadingState;
|
|
4327
4446
|
exports.recordAppilotsDebugTrace = recordAppilotsDebugTrace;
|
|
4447
|
+
exports.recordIntrospectionFailure = recordIntrospectionFailure;
|
|
4328
4448
|
exports.registerScreen = registerScreen;
|
|
4329
4449
|
exports.resolveBaseTheme = resolveBaseTheme;
|
|
4330
4450
|
exports.routesBelongToSameFeature = routesBelongToSameFeature;
|