@chipmobilesdk/rn-ai 0.4.0 → 0.5.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/CHANGELOG.md +120 -0
- package/README.md +5 -2
- package/lib/commonjs/config/behaviorConfig.js +283 -0
- package/lib/commonjs/config/behaviorConfig.js.map +1 -0
- package/lib/commonjs/contract/gateway.js +60 -0
- package/lib/commonjs/contract/gateway.js.map +1 -0
- package/lib/commonjs/core/aiClient.js +330 -0
- package/lib/commonjs/core/aiClient.js.map +1 -0
- package/lib/commonjs/core/quotaRequest.js +105 -0
- package/lib/commonjs/core/quotaRequest.js.map +1 -0
- package/lib/commonjs/diagnostics/errors.js +108 -0
- package/lib/commonjs/diagnostics/errors.js.map +1 -0
- package/lib/commonjs/diagnostics/messageKeys.js +68 -0
- package/lib/commonjs/diagnostics/messageKeys.js.map +1 -0
- package/lib/commonjs/index.js +102 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/react/hooks.js +170 -0
- package/lib/commonjs/react/hooks.js.map +1 -0
- package/lib/commonjs/transport/sseClient.js +151 -0
- package/lib/commonjs/transport/sseClient.js.map +1 -0
- package/lib/commonjs/transport/timeouts.js +46 -0
- package/lib/commonjs/transport/timeouts.js.map +1 -0
- package/lib/module/config/behaviorConfig.js +275 -0
- package/lib/module/config/behaviorConfig.js.map +1 -0
- package/lib/module/contract/gateway.js +56 -0
- package/lib/module/contract/gateway.js.map +1 -0
- package/lib/module/core/aiClient.js +327 -0
- package/lib/module/core/aiClient.js.map +1 -0
- package/lib/module/core/quotaRequest.js +102 -0
- package/lib/module/core/quotaRequest.js.map +1 -0
- package/lib/module/diagnostics/errors.js +99 -0
- package/lib/module/diagnostics/errors.js.map +1 -0
- package/lib/module/diagnostics/messageKeys.js +61 -0
- package/lib/module/diagnostics/messageKeys.js.map +1 -0
- package/lib/module/index.js +19 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/react/hooks.js +164 -0
- package/lib/module/react/hooks.js.map +1 -0
- package/lib/module/transport/sseClient.js +146 -0
- package/lib/module/transport/sseClient.js.map +1 -0
- package/lib/module/transport/timeouts.js +41 -0
- package/lib/module/transport/timeouts.js.map +1 -0
- package/lib/typescript/commonjs/config/behaviorConfig.d.ts +119 -0
- package/lib/typescript/commonjs/config/behaviorConfig.d.ts.map +1 -0
- package/lib/typescript/commonjs/contract/gateway.d.ts +64 -0
- package/lib/typescript/commonjs/contract/gateway.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/aiClient.d.ts +104 -0
- package/lib/typescript/commonjs/core/aiClient.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/quotaRequest.d.ts +45 -0
- package/lib/typescript/commonjs/core/quotaRequest.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts +38 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts +46 -0
- package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +21 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/react/hooks.d.ts +37 -0
- package/lib/typescript/commonjs/react/hooks.d.ts.map +1 -0
- package/lib/typescript/commonjs/transport/sseClient.d.ts +57 -0
- package/lib/typescript/commonjs/transport/sseClient.d.ts.map +1 -0
- package/lib/typescript/commonjs/transport/timeouts.d.ts +28 -0
- package/lib/typescript/commonjs/transport/timeouts.d.ts.map +1 -0
- package/lib/typescript/module/config/behaviorConfig.d.ts +119 -0
- package/lib/typescript/module/config/behaviorConfig.d.ts.map +1 -0
- package/lib/typescript/module/contract/gateway.d.ts +64 -0
- package/lib/typescript/module/contract/gateway.d.ts.map +1 -0
- package/lib/typescript/module/core/aiClient.d.ts +104 -0
- package/lib/typescript/module/core/aiClient.d.ts.map +1 -0
- package/lib/typescript/module/core/quotaRequest.d.ts +45 -0
- package/lib/typescript/module/core/quotaRequest.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/errors.d.ts +38 -0
- package/lib/typescript/module/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/messageKeys.d.ts +46 -0
- package/lib/typescript/module/diagnostics/messageKeys.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +21 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/react/hooks.d.ts +37 -0
- package/lib/typescript/module/react/hooks.d.ts.map +1 -0
- package/lib/typescript/module/transport/sseClient.d.ts +57 -0
- package/lib/typescript/module/transport/sseClient.d.ts.map +1 -0
- package/lib/typescript/module/transport/timeouts.d.ts +28 -0
- package/lib/typescript/module/transport/timeouts.d.ts.map +1 -0
- package/package.json +40 -12
- package/skills/sdk-rn-ai/SKILL.md +8 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createAiClient = createAiClient;
|
|
7
|
+
var _rnCore = require("@chipmobilesdk/rn-core");
|
|
8
|
+
var _behaviorConfig = require("../config/behaviorConfig.js");
|
|
9
|
+
var _gateway = require("../contract/gateway.js");
|
|
10
|
+
var _errors = require("../diagnostics/errors.js");
|
|
11
|
+
var _sseClient = require("../transport/sseClient.js");
|
|
12
|
+
var _quotaRequest = require("./quotaRequest.js");
|
|
13
|
+
var _timeouts = require("../transport/timeouts.js");
|
|
14
|
+
/** Every failure a caller receives also goes to the app's SDK sinks (CORE-08). */
|
|
15
|
+
const channel = (0, _rnCore.createDiagnosticChannel)('rn-ai');
|
|
16
|
+
function report(operation, error) {
|
|
17
|
+
channel.emit(error.code, error.retryable ? 'warn' : 'error', {
|
|
18
|
+
operation,
|
|
19
|
+
retryable: error.retryable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Minimal slice of the rn-auth `Auth` controller the client needs. */
|
|
24
|
+
|
|
25
|
+
/** What one answer cost, as the gateway reports it. */
|
|
26
|
+
|
|
27
|
+
/** What is left of the app's allowance. */
|
|
28
|
+
|
|
29
|
+
/** Ceiling on one remote-configured backoff step, so a bad document cannot stall a chat. */
|
|
30
|
+
const MAX_RETRY_BACKOFF_MS = 30_000;
|
|
31
|
+
|
|
32
|
+
/** The wait before silent retry `index` (0-based); the last configured step repeats. */
|
|
33
|
+
function backoffBefore(steps, index) {
|
|
34
|
+
const step = steps[Math.min(index, steps.length - 1)] ?? 0;
|
|
35
|
+
return Math.min(Math.max(0, step), MAX_RETRY_BACKOFF_MS);
|
|
36
|
+
}
|
|
37
|
+
/** A quota from the wire, or nothing: a malformed one is not displayed (AI-13). */
|
|
38
|
+
function asQuota(value) {
|
|
39
|
+
if (typeof value !== 'object' || value === null) {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
const candidate = value;
|
|
43
|
+
const fields = [candidate.minuteRemaining, candidate.dayRemaining, candidate.dayTokensRemaining];
|
|
44
|
+
if (!fields.every(field => typeof field === 'number' && Number.isFinite(field))) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
minuteRemaining: candidate.minuteRemaining,
|
|
49
|
+
dayRemaining: candidate.dayRemaining,
|
|
50
|
+
dayTokensRemaining: candidate.dayTokensRemaining
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function createAiClient(clientConfig) {
|
|
54
|
+
const resourceKey = clientConfig.resourceKey ?? 'ai-gateway';
|
|
55
|
+
const transport = clientConfig.transport ?? _sseClient.requestSse;
|
|
56
|
+
const fetchFn = clientConfig.fetchFn ?? fetch;
|
|
57
|
+
const timeouts = {
|
|
58
|
+
..._timeouts.DEFAULT_AI_TIMEOUTS,
|
|
59
|
+
...clientConfig.timeouts
|
|
60
|
+
};
|
|
61
|
+
const scheduler = clientConfig.scheduler ?? _rnCore.realScheduler;
|
|
62
|
+
const configManager = new _behaviorConfig.BehaviorConfigManager({
|
|
63
|
+
configUrl: clientConfig.configUrl,
|
|
64
|
+
appId: clientConfig.appId,
|
|
65
|
+
cache: clientConfig.storage,
|
|
66
|
+
fetchFn: clientConfig.fetchFn,
|
|
67
|
+
timeoutMs: timeouts.configMs,
|
|
68
|
+
...(clientConfig.allowedHosts ? {
|
|
69
|
+
allowedHosts: clientConfig.allowedHosts
|
|
70
|
+
} : {})
|
|
71
|
+
});
|
|
72
|
+
let lastConfig;
|
|
73
|
+
const behaviorListeners = (0, _rnCore.createListenerSet)();
|
|
74
|
+
let snapshot;
|
|
75
|
+
let quota;
|
|
76
|
+
|
|
77
|
+
/** Rebuilt only when a field changes, so useSyncExternalStore sees a stable object. */
|
|
78
|
+
function behaviorState() {
|
|
79
|
+
const config = configManager.state;
|
|
80
|
+
const aiEnabled = lastConfig?.features.aiEnabled ?? true;
|
|
81
|
+
if (!snapshot || snapshot.config !== config || snapshot.aiEnabled !== aiEnabled) {
|
|
82
|
+
snapshot = {
|
|
83
|
+
config,
|
|
84
|
+
aiEnabled
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return snapshot;
|
|
88
|
+
}
|
|
89
|
+
function setLastConfig(next) {
|
|
90
|
+
const wasEnabled = lastConfig?.features.aiEnabled ?? true;
|
|
91
|
+
lastConfig = next;
|
|
92
|
+
if (next.features.aiEnabled !== wasEnabled) behaviorListeners.notify();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** One place records the quota, whichever call learned it (AI-13). */
|
|
96
|
+
function setQuota(next) {
|
|
97
|
+
if (!next || quota && shallowSameQuota(quota, next)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
quota = next;
|
|
101
|
+
behaviorListeners.notify();
|
|
102
|
+
}
|
|
103
|
+
async function acquire(options = {}) {
|
|
104
|
+
const config = await configManager.getConfig();
|
|
105
|
+
setLastConfig(config);
|
|
106
|
+
if (!config.features.aiEnabled) {
|
|
107
|
+
throw new _errors.AiError('config-unavailable', 'AI is disabled for this app', {
|
|
108
|
+
recoverable: false
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const tokenResult = await clientConfig.auth.requestAccessToken(resourceKey, {
|
|
112
|
+
forceRefresh: options.forceRefresh === true
|
|
113
|
+
});
|
|
114
|
+
if (tokenResult.status !== 'success' || !tokenResult.token) {
|
|
115
|
+
// What the auth layer called it, kept as the cause: a screen has to tell
|
|
116
|
+
// "sign in again" from "you are offline" (AI-11).
|
|
117
|
+
throw tokenError(tokenResult.status, tokenResult.errorCode);
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
config,
|
|
121
|
+
token: tokenResult.token
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const endpoint = (config, path) => `${config.api.baseUrl}/api/v1/apps/${clientConfig.appId}/${path}`;
|
|
125
|
+
function chat(request, handlers) {
|
|
126
|
+
let cancelled = false;
|
|
127
|
+
let settled = false;
|
|
128
|
+
let inner;
|
|
129
|
+
|
|
130
|
+
// Every callback to the app goes through here. Nothing is delivered after
|
|
131
|
+
// cancel() — an acquire() or config reload that failed after the user
|
|
132
|
+
// cancelled (or sent the next message) used to flip that screen to
|
|
133
|
+
// `error` — and exactly one terminal callback is delivered.
|
|
134
|
+
const emit = {
|
|
135
|
+
delta(text) {
|
|
136
|
+
if (!cancelled && !settled) handlers.onDelta(text);
|
|
137
|
+
},
|
|
138
|
+
done(result) {
|
|
139
|
+
if (cancelled || settled) return;
|
|
140
|
+
settled = true;
|
|
141
|
+
setQuota(result.quota);
|
|
142
|
+
handlers.onDone(result);
|
|
143
|
+
},
|
|
144
|
+
error(error) {
|
|
145
|
+
if (cancelled || settled) return;
|
|
146
|
+
settled = true;
|
|
147
|
+
inner?.cancel();
|
|
148
|
+
report('chat', error);
|
|
149
|
+
handlers.onError(error);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// Any exception on the way becomes a reported error. Each path used to end
|
|
154
|
+
// in `.catch(() => undefined)`, so a transport that threw (a bad URL from
|
|
155
|
+
// remote config, say) left the UI in `loading` with nothing to show.
|
|
156
|
+
const fail = e => emit.error(e instanceof _errors.AiError ? e : new _errors.AiError('internal', e instanceof Error ? e.message : String(e)));
|
|
157
|
+
const guarded = fn => (...args) => {
|
|
158
|
+
try {
|
|
159
|
+
fn(...args);
|
|
160
|
+
} catch (e) {
|
|
161
|
+
fail(e);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const attempt = async state => {
|
|
165
|
+
const {
|
|
166
|
+
config,
|
|
167
|
+
token
|
|
168
|
+
} = await acquire({
|
|
169
|
+
forceRefresh: state.authRetries > 0
|
|
170
|
+
});
|
|
171
|
+
if (cancelled) return;
|
|
172
|
+
let done;
|
|
173
|
+
let streamErrorCode;
|
|
174
|
+
inner = transport({
|
|
175
|
+
url: endpoint(config, 'chat'),
|
|
176
|
+
method: 'POST',
|
|
177
|
+
headers: {
|
|
178
|
+
Authorization: `Bearer ${token}`,
|
|
179
|
+
'Content-Type': 'application/json'
|
|
180
|
+
},
|
|
181
|
+
body: JSON.stringify(request),
|
|
182
|
+
connectTimeoutMs: timeouts.connectMs,
|
|
183
|
+
idleTimeoutMs: timeouts.idleMs
|
|
184
|
+
}, {
|
|
185
|
+
onData: guarded(payload => {
|
|
186
|
+
if (payload === _gateway.SSE_DONE_SENTINEL) return;
|
|
187
|
+
let event;
|
|
188
|
+
try {
|
|
189
|
+
event = JSON.parse(payload);
|
|
190
|
+
} catch {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (event.type === 'delta' && typeof event.text === 'string') {
|
|
194
|
+
emit.delta(event.text);
|
|
195
|
+
} else if (event.type === 'done' && event.usage) {
|
|
196
|
+
done = {
|
|
197
|
+
usage: event.usage,
|
|
198
|
+
quota: asQuota(event.quota)
|
|
199
|
+
};
|
|
200
|
+
} else if (event.type === 'error') {
|
|
201
|
+
streamErrorCode = event.code ?? 'UPSTREAM_ERROR';
|
|
202
|
+
}
|
|
203
|
+
}),
|
|
204
|
+
onEnd: guarded(() => {
|
|
205
|
+
if (streamErrorCode) {
|
|
206
|
+
emit.error(new _errors.AiError('upstream-error', 'the AI service failed mid-response', {
|
|
207
|
+
cause: streamErrorCode
|
|
208
|
+
}));
|
|
209
|
+
} else if (done) {
|
|
210
|
+
emit.done(done);
|
|
211
|
+
} else {
|
|
212
|
+
// Headers said 200 and the body stopped short: the connection
|
|
213
|
+
// dropped mid-answer, which is a network failure, not a fault
|
|
214
|
+
// of the service.
|
|
215
|
+
emit.error(new _errors.AiError('network', 'the stream ended before it completed'));
|
|
216
|
+
}
|
|
217
|
+
}),
|
|
218
|
+
onError: guarded((status, bodyText, response) => {
|
|
219
|
+
if (cancelled) return;
|
|
220
|
+
recover(status, bodyText, state, {
|
|
221
|
+
...(response ? {
|
|
222
|
+
getHeader: name => response.getHeader(name)
|
|
223
|
+
} : {})
|
|
224
|
+
}, next => attempt(next).catch(fail), fail, emit.error);
|
|
225
|
+
})
|
|
226
|
+
});
|
|
227
|
+
};
|
|
228
|
+
attempt({
|
|
229
|
+
configReloads: 0,
|
|
230
|
+
authRetries: 0
|
|
231
|
+
}).catch(fail);
|
|
232
|
+
return {
|
|
233
|
+
cancel() {
|
|
234
|
+
cancelled = true;
|
|
235
|
+
inner?.cancel();
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* The two recoveries the contract promises, in one place so chat and quota
|
|
242
|
+
* cannot drift (AI-13): a designated status reloads the configuration and
|
|
243
|
+
* retries after the configured backoff, and a 401 retries once with a token
|
|
244
|
+
* the provider had to fetch again.
|
|
245
|
+
*/
|
|
246
|
+
function recover(status, bodyText, state, context, retry, onFailure, onGiveUp) {
|
|
247
|
+
const config = lastConfig;
|
|
248
|
+
if (config && config.recovery.reloadOnHttpStatus.includes(status) && state.configReloads < config.recovery.maxSilentRetries) {
|
|
249
|
+
// Waits `recovery.retryBackoffMs` first (AI-05): a gateway mid-rollout
|
|
250
|
+
// that answered 410 a moment ago may well answer it again at once.
|
|
251
|
+
const retryAfter = backoffBefore(config.recovery.retryBackoffMs, state.configReloads);
|
|
252
|
+
configManager.getConfig({
|
|
253
|
+
forceReload: true
|
|
254
|
+
}).then(reloaded => {
|
|
255
|
+
setLastConfig(reloaded);
|
|
256
|
+
scheduler.setTimeout(() => retry({
|
|
257
|
+
...state,
|
|
258
|
+
configReloads: state.configReloads + 1
|
|
259
|
+
}), retryAfter);
|
|
260
|
+
}, e => onFailure(e instanceof _errors.AiError ? e : new _errors.AiError('config-unavailable', String(e))));
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
// Expired server-side session → one retry with a token the provider
|
|
264
|
+
// actually re-fetched.
|
|
265
|
+
if (status === 401 && state.authRetries < 1) {
|
|
266
|
+
retry({
|
|
267
|
+
...state,
|
|
268
|
+
authRetries: state.authRetries + 1
|
|
269
|
+
});
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
onGiveUp((0, _errors.errorFromHttp)(status, bodyText, context));
|
|
273
|
+
}
|
|
274
|
+
const {
|
|
275
|
+
getQuota
|
|
276
|
+
} = (0, _quotaRequest.createQuotaRequest)({
|
|
277
|
+
fetchFn,
|
|
278
|
+
timeouts,
|
|
279
|
+
acquire,
|
|
280
|
+
endpoint,
|
|
281
|
+
asQuota,
|
|
282
|
+
recover,
|
|
283
|
+
report: error => report('quota', error),
|
|
284
|
+
setQuota
|
|
285
|
+
});
|
|
286
|
+
return {
|
|
287
|
+
chat,
|
|
288
|
+
getQuota,
|
|
289
|
+
lastQuota: () => quota,
|
|
290
|
+
getBehaviorState: () => behaviorState(),
|
|
291
|
+
subscribe: listener => {
|
|
292
|
+
const fromManager = configManager.subscribe(listener);
|
|
293
|
+
const fromClient = behaviorListeners.add(listener);
|
|
294
|
+
return () => {
|
|
295
|
+
fromManager();
|
|
296
|
+
fromClient();
|
|
297
|
+
};
|
|
298
|
+
},
|
|
299
|
+
reloadConfig: async () => {
|
|
300
|
+
setLastConfig(await configManager.getConfig({
|
|
301
|
+
forceReload: true
|
|
302
|
+
}));
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function shallowSameQuota(a, b) {
|
|
307
|
+
return a.minuteRemaining === b.minuteRemaining && a.dayRemaining === b.dayRemaining && a.dayTokensRemaining === b.dayTokensRemaining;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* What the auth layer's refusal means for a chat. The code rn-auth gave is kept
|
|
312
|
+
* as the cause, and it decides the copy: "sign in again" and "you are offline"
|
|
313
|
+
* are different answers, and both used to arrive as `auth-invalid` (AI-11).
|
|
314
|
+
*/
|
|
315
|
+
function tokenError(status, errorCode) {
|
|
316
|
+
const cause = errorCode ? {
|
|
317
|
+
cause: errorCode
|
|
318
|
+
} : {};
|
|
319
|
+
switch (errorCode) {
|
|
320
|
+
case 'session-expired':
|
|
321
|
+
return new _errors.AiError('session-expired', 'the session ended; sign in again', cause);
|
|
322
|
+
case 'network-unavailable':
|
|
323
|
+
return new _errors.AiError('network', 'no connection to the identity provider', cause);
|
|
324
|
+
case 'consent-denied':
|
|
325
|
+
return new _errors.AiError('not-entitled', 'access to the AI resource was denied', cause);
|
|
326
|
+
default:
|
|
327
|
+
return new _errors.AiError('auth-invalid', status === 'denied' ? 'access to the AI resource was refused' : 'could not acquire an access token', cause);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=aiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_rnCore","require","_behaviorConfig","_gateway","_errors","_sseClient","_quotaRequest","_timeouts","channel","createDiagnosticChannel","report","operation","error","emit","code","retryable","MAX_RETRY_BACKOFF_MS","backoffBefore","steps","index","step","Math","min","length","max","asQuota","value","undefined","candidate","fields","minuteRemaining","dayRemaining","dayTokensRemaining","every","field","Number","isFinite","createAiClient","clientConfig","resourceKey","transport","requestSse","fetchFn","fetch","timeouts","DEFAULT_AI_TIMEOUTS","scheduler","realScheduler","configManager","BehaviorConfigManager","configUrl","appId","cache","storage","timeoutMs","configMs","allowedHosts","lastConfig","behaviorListeners","createListenerSet","snapshot","quota","behaviorState","config","state","aiEnabled","features","setLastConfig","next","wasEnabled","notify","setQuota","shallowSameQuota","acquire","options","getConfig","AiError","recoverable","tokenResult","auth","requestAccessToken","forceRefresh","status","token","tokenError","errorCode","endpoint","path","api","baseUrl","chat","request","handlers","cancelled","settled","inner","delta","text","onDelta","done","result","onDone","cancel","onError","fail","e","Error","message","String","guarded","fn","args","attempt","authRetries","streamErrorCode","url","method","headers","Authorization","body","JSON","stringify","connectTimeoutMs","connectMs","idleTimeoutMs","idleMs","onData","payload","SSE_DONE_SENTINEL","event","parse","type","usage","onEnd","cause","bodyText","response","recover","getHeader","name","catch","configReloads","context","retry","onFailure","onGiveUp","recovery","reloadOnHttpStatus","includes","maxSilentRetries","retryAfter","retryBackoffMs","forceReload","then","reloaded","setTimeout","errorFromHttp","getQuota","createQuotaRequest","lastQuota","getBehaviorState","subscribe","listener","fromManager","fromClient","add","reloadConfig","a","b"],"sourceRoot":"../../../src","sources":["core/aiClient.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createQuotaRequest = createQuotaRequest;
|
|
7
|
+
var _errors = require("../diagnostics/errors.js");
|
|
8
|
+
var _timeouts = require("../transport/timeouts.js");
|
|
9
|
+
/**
|
|
10
|
+
* The quota request, and the recovery it shares with a chat (AI-13).
|
|
11
|
+
*
|
|
12
|
+
* `getQuota` used to be the one call with no recovery at all: a gateway that
|
|
13
|
+
* had moved answered 404 for quota while chats silently re-routed, so the
|
|
14
|
+
* figure on screen failed while the feature worked. It now goes through the
|
|
15
|
+
* same `recover` the chat stream does — a designated status reloads the
|
|
16
|
+
* configuration and retries, a 401 retries once with a token the provider had
|
|
17
|
+
* to fetch again.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Where the quota request is in its recovery, shared with the chat path. */
|
|
21
|
+
|
|
22
|
+
/** What is left of the app's allowance. */
|
|
23
|
+
|
|
24
|
+
function createQuotaRequest(deps) {
|
|
25
|
+
const {
|
|
26
|
+
fetchFn,
|
|
27
|
+
timeouts,
|
|
28
|
+
endpoint,
|
|
29
|
+
asQuota,
|
|
30
|
+
recover,
|
|
31
|
+
setQuota
|
|
32
|
+
} = deps;
|
|
33
|
+
const acquire = deps.acquire;
|
|
34
|
+
async function getQuota() {
|
|
35
|
+
try {
|
|
36
|
+
const snapshotValue = await fetchQuotaWithRecovery({
|
|
37
|
+
configReloads: 0,
|
|
38
|
+
authRetries: 0
|
|
39
|
+
});
|
|
40
|
+
setQuota(snapshotValue);
|
|
41
|
+
return snapshotValue;
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (error instanceof _errors.AiError) deps.report(error);
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Same recovery as a chat: a retired endpoint reloads the config and retries. */
|
|
49
|
+
function fetchQuotaWithRecovery(state) {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
fetchQuota(state).then(resolve, error => {
|
|
52
|
+
if (!(error instanceof HttpFailure)) {
|
|
53
|
+
reject(error);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
recover(error.status, error.bodyText, state, {
|
|
57
|
+
getHeader: name => error.getHeader(name)
|
|
58
|
+
}, next => fetchQuotaWithRecovery(next).then(resolve, reject), reject, reject);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Carries the response so `recover` can decide; never reaches the caller. */
|
|
64
|
+
class HttpFailure extends Error {
|
|
65
|
+
constructor(status, bodyText, headers) {
|
|
66
|
+
super(`gateway responded ${status}`);
|
|
67
|
+
this.status = status;
|
|
68
|
+
this.bodyText = bodyText;
|
|
69
|
+
this.headers = headers;
|
|
70
|
+
this.name = 'HttpFailure';
|
|
71
|
+
}
|
|
72
|
+
getHeader(name) {
|
|
73
|
+
return this.headers?.get(name) ?? null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function fetchQuota(state) {
|
|
77
|
+
const {
|
|
78
|
+
config,
|
|
79
|
+
token
|
|
80
|
+
} = await acquire({
|
|
81
|
+
forceRefresh: state.authRetries > 0
|
|
82
|
+
});
|
|
83
|
+
return (0, _timeouts.withTimeout)(timeouts.quotaMs, async signal => {
|
|
84
|
+
const response = await fetchFn(endpoint(config, 'quota'), {
|
|
85
|
+
headers: {
|
|
86
|
+
Authorization: `Bearer ${token}`
|
|
87
|
+
},
|
|
88
|
+
signal
|
|
89
|
+
});
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
throw new HttpFailure(response.status, await response.text(), response.headers);
|
|
92
|
+
}
|
|
93
|
+
const parsed = asQuota(await response.json());
|
|
94
|
+
if (!parsed) {
|
|
95
|
+
// A body that is not the contract's: better no figure than a wrong one.
|
|
96
|
+
throw new _errors.AiError('internal', 'quota response did not match the contract');
|
|
97
|
+
}
|
|
98
|
+
return parsed;
|
|
99
|
+
}, () => new _errors.AiError('network', 'quota request timed out'));
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
getQuota
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=quotaRequest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_errors","require","_timeouts","createQuotaRequest","deps","fetchFn","timeouts","endpoint","asQuota","recover","setQuota","acquire","getQuota","snapshotValue","fetchQuotaWithRecovery","configReloads","authRetries","error","AiError","report","state","Promise","resolve","reject","fetchQuota","then","HttpFailure","status","bodyText","getHeader","name","next","Error","constructor","headers","get","config","token","forceRefresh","withTimeout","quotaMs","signal","response","Authorization","ok","text","parsed","json"],"sourceRoot":"../../../src","sources":["core/quotaRequest.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.AiError = void 0;
|
|
7
|
+
exports.errorFromHttp = errorFromHttp;
|
|
8
|
+
exports.isAiError = isAiError;
|
|
9
|
+
exports.parseRetryAfter = parseRetryAfter;
|
|
10
|
+
var _rnCore = require("@chipmobilesdk/rn-core");
|
|
11
|
+
var _gateway = require("../contract/gateway.js");
|
|
12
|
+
/** Typed client errors (contracts/rn-ai-public-api.md). */
|
|
13
|
+
|
|
14
|
+
/** Codes a retry can fix on its own. */
|
|
15
|
+
const RETRYABLE_BY_DEFAULT = new Set(['rate-limited', 'upstream-busy', 'network']);
|
|
16
|
+
|
|
17
|
+
/** The package's error; an `SdkError` (`@chipmobilesdk/rn-core`) with `pkg: 'rn-ai'`. */
|
|
18
|
+
class AiError extends _rnCore.SdkError {
|
|
19
|
+
/** The underlying code, when one layer down had a name for the failure. */
|
|
20
|
+
|
|
21
|
+
constructor(code, message, options = {}) {
|
|
22
|
+
super('rn-ai', code, {
|
|
23
|
+
message,
|
|
24
|
+
retryable: options.retryable ?? options.recoverable ?? RETRYABLE_BY_DEFAULT.has(code)
|
|
25
|
+
});
|
|
26
|
+
this.name = 'AiError';
|
|
27
|
+
this.retryAfterSeconds = options.retryAfterSeconds;
|
|
28
|
+
this.cause = options.cause;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** @deprecated Use `retryable`, the name every SDK package shares. */
|
|
32
|
+
get recoverable() {
|
|
33
|
+
return this.retryable;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.AiError = AiError;
|
|
37
|
+
function isAiError(value) {
|
|
38
|
+
return value instanceof AiError;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Every gateway code, mapped. Typed as a total record, so a code added to the
|
|
43
|
+
* shared contract does not compile until the client says what it means (GW-13).
|
|
44
|
+
*/
|
|
45
|
+
const HTTP_CODE_MAP = {
|
|
46
|
+
BAD_REQUEST: 'internal',
|
|
47
|
+
AUTH_INVALID: 'auth-invalid',
|
|
48
|
+
NOT_ENTITLED: 'not-entitled',
|
|
49
|
+
USER_BLOCKED: 'user-blocked',
|
|
50
|
+
APP_UNKNOWN: 'app-unknown',
|
|
51
|
+
// The endpoint moved: the client's configuration is the stale part.
|
|
52
|
+
ENDPOINT_RETIRED: 'config-unavailable',
|
|
53
|
+
PAYLOAD_TOO_LARGE: 'payload-too-large',
|
|
54
|
+
MODALITY_NOT_ALLOWED: 'modality-not-allowed',
|
|
55
|
+
RATE_LIMITED: 'rate-limited',
|
|
56
|
+
UPSTREAM_BUSY: 'upstream-busy',
|
|
57
|
+
UPSTREAM_ERROR: 'upstream-error',
|
|
58
|
+
INTERNAL: 'internal'
|
|
59
|
+
};
|
|
60
|
+
function isGatewayCode(value) {
|
|
61
|
+
return typeof value === 'string' && value in HTTP_CODE_MAP;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** `Retry-After` in seconds, from either form the header may take. */
|
|
65
|
+
function parseRetryAfter(value) {
|
|
66
|
+
if (!value) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
const seconds = Number(value);
|
|
70
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
71
|
+
return seconds;
|
|
72
|
+
}
|
|
73
|
+
const date = Date.parse(value);
|
|
74
|
+
if (Number.isFinite(date)) {
|
|
75
|
+
return Math.max(0, Math.round((date - Date.now()) / 1000));
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
/** Map a gateway error response (status + JSON body) to a typed AiError. */
|
|
80
|
+
function errorFromHttp(status, bodyText, context = {}) {
|
|
81
|
+
// Status 0 is not an answer at all: the request never arrived, or the
|
|
82
|
+
// connection dropped. That is a network failure a retry may well fix, not an
|
|
83
|
+
// upstream fault (AI-11).
|
|
84
|
+
if (status === 0) {
|
|
85
|
+
return new AiError('network', bodyText === 'timeout' ? 'the request timed out' : 'no connection');
|
|
86
|
+
}
|
|
87
|
+
let code = status >= 500 ? 'upstream-error' : 'internal';
|
|
88
|
+
let message = `gateway responded ${status}`;
|
|
89
|
+
let gatewayCode;
|
|
90
|
+
let retryAfterSeconds = parseRetryAfter(context.getHeader?.(_gateway.RETRY_AFTER_HEADER));
|
|
91
|
+
try {
|
|
92
|
+
const parsed = JSON.parse(bodyText);
|
|
93
|
+
if (isGatewayCode(parsed.error?.code)) {
|
|
94
|
+
gatewayCode = parsed.error.code;
|
|
95
|
+
code = HTTP_CODE_MAP[gatewayCode];
|
|
96
|
+
}
|
|
97
|
+
// The gateway's text can quote upstream detail; keep it readable but shaped.
|
|
98
|
+
if (parsed.error?.message) message = (0, _rnCore.redactPatterns)(parsed.error.message);
|
|
99
|
+
retryAfterSeconds = parsed.error?.retryAfterSeconds ?? retryAfterSeconds;
|
|
100
|
+
} catch {
|
|
101
|
+
// A body that is not the contract's: the status is all there is to go on.
|
|
102
|
+
}
|
|
103
|
+
return new AiError(code, message, {
|
|
104
|
+
retryAfterSeconds,
|
|
105
|
+
cause: gatewayCode
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_rnCore","require","_gateway","RETRYABLE_BY_DEFAULT","Set","AiError","SdkError","constructor","code","message","options","retryable","recoverable","has","name","retryAfterSeconds","cause","exports","isAiError","value","HTTP_CODE_MAP","BAD_REQUEST","AUTH_INVALID","NOT_ENTITLED","USER_BLOCKED","APP_UNKNOWN","ENDPOINT_RETIRED","PAYLOAD_TOO_LARGE","MODALITY_NOT_ALLOWED","RATE_LIMITED","UPSTREAM_BUSY","UPSTREAM_ERROR","INTERNAL","isGatewayCode","parseRetryAfter","undefined","seconds","Number","isFinite","date","Date","parse","Math","max","round","now","errorFromHttp","status","bodyText","context","gatewayCode","getHeader","RETRY_AFTER_HEADER","parsed","JSON","error","redactPatterns"],"sourceRoot":"../../../src","sources":["diagnostics/errors.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.aiMessage = aiMessage;
|
|
7
|
+
exports.aiMessages = exports.aiMessageSet = void 0;
|
|
8
|
+
exports.messageKeyForError = messageKeyForError;
|
|
9
|
+
var _rnCore = require("@chipmobilesdk/rn-core");
|
|
10
|
+
/**
|
|
11
|
+
* User-facing copy keys (UX-002/003) and their English defaults, as an rn-core
|
|
12
|
+
* message catalog: apps translate them through rn-i18n
|
|
13
|
+
* (`runtimeEntriesFromCatalog(aiMessages)`) or override them directly.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const aiMessageSet = exports.aiMessageSet = (0, _rnCore.defineMessages)({
|
|
17
|
+
user: {
|
|
18
|
+
'ai.state.loading': 'Thinking…',
|
|
19
|
+
'ai.state.streaming': 'Answering…',
|
|
20
|
+
// Neutral copy: the app names its own feature (AI-16).
|
|
21
|
+
'ai.input.placeholder': 'Type a message…',
|
|
22
|
+
'ai.action.send': 'Send',
|
|
23
|
+
'ai.action.cancel': 'Cancel',
|
|
24
|
+
'ai.action.retry': 'Try again',
|
|
25
|
+
'ai.action.retryAt': 'You can try again at {time}',
|
|
26
|
+
'ai.quota.remaining': '{count} requests left today',
|
|
27
|
+
'ai.error.rateLimited': 'You have reached your usage limit.',
|
|
28
|
+
'ai.error.premiumRequired': 'AI features require a premium subscription for this app.',
|
|
29
|
+
'ai.error.blocked': 'AI access is suspended for this account.',
|
|
30
|
+
'ai.error.payloadTooLarge': 'That attachment is too large to send.',
|
|
31
|
+
'ai.error.modality': 'This kind of content is not supported here.',
|
|
32
|
+
'ai.error.busy': 'The AI service is busy. Please try again shortly.',
|
|
33
|
+
'ai.error.unavailable': 'AI features are currently unavailable.',
|
|
34
|
+
'ai.error.signIn': 'Please sign in again to continue.',
|
|
35
|
+
'ai.error.offline': 'No connection. Check your network and try again.',
|
|
36
|
+
'ai.error.generic': 'Something went wrong. Please try again.'
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
const aiMessages = exports.aiMessages = aiMessageSet.defaults;
|
|
40
|
+
function aiMessage(key) {
|
|
41
|
+
return aiMessages[key];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The copy for each error code. A `Record` over the whole code union, so adding a
|
|
46
|
+
* code without choosing its copy fails to compile (AI-16).
|
|
47
|
+
*/
|
|
48
|
+
const ERROR_MESSAGES = {
|
|
49
|
+
'auth-invalid': 'ai.error.signIn',
|
|
50
|
+
'session-expired': 'ai.error.signIn',
|
|
51
|
+
network: 'ai.error.offline',
|
|
52
|
+
'not-entitled': 'ai.error.premiumRequired',
|
|
53
|
+
'user-blocked': 'ai.error.blocked',
|
|
54
|
+
'app-unknown': 'ai.error.unavailable',
|
|
55
|
+
'rate-limited': 'ai.error.rateLimited',
|
|
56
|
+
'upstream-busy': 'ai.error.busy',
|
|
57
|
+
'payload-too-large': 'ai.error.payloadTooLarge',
|
|
58
|
+
'modality-not-allowed': 'ai.error.modality',
|
|
59
|
+
'config-unavailable': 'ai.error.unavailable',
|
|
60
|
+
'upstream-error': 'ai.error.generic',
|
|
61
|
+
internal: 'ai.error.generic'
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** The message key to show a user for an error. */
|
|
65
|
+
function messageKeyForError(error) {
|
|
66
|
+
return ERROR_MESSAGES[error.code];
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=messageKeys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_rnCore","require","aiMessageSet","exports","defineMessages","user","aiMessages","defaults","aiMessage","key","ERROR_MESSAGES","network","internal","messageKeyForError","error","code"],"sourceRoot":"../../../src","sources":["diagnostics/messageKeys.ts"],"mappings":";;;;;;;;AAKA,IAAAA,OAAA,GAAAC,OAAA;AALA;AACA;AACA;AACA;AACA;;AAMO,MAAMC,YAAY,GAAAC,OAAA,CAAAD,YAAA,GAAG,IAAAE,sBAAc,EAAC;EAC1CC,IAAI,EAAE;IACL,kBAAkB,EAAE,WAAW;IAC/B,oBAAoB,EAAE,YAAY;IAClC;IACA,sBAAsB,EAAE,iBAAiB;IACzC,gBAAgB,EAAE,MAAM;IACxB,kBAAkB,EAAE,QAAQ;IAC5B,iBAAiB,EAAE,WAAW;IAC9B,mBAAmB,EAAE,6BAA6B;IAClD,oBAAoB,EAAE,6BAA6B;IACnD,sBAAsB,EAAE,oCAAoC;IAC5D,0BAA0B,EAAE,0DAA0D;IACtF,kBAAkB,EAAE,0CAA0C;IAC9D,0BAA0B,EAAE,uCAAuC;IACnE,mBAAmB,EAAE,6CAA6C;IAClE,eAAe,EAAE,mDAAmD;IACpE,sBAAsB,EAAE,wCAAwC;IAChE,iBAAiB,EAAE,mCAAmC;IACtD,kBAAkB,EAAE,kDAAkD;IACtE,kBAAkB,EAAE;EACrB;AACD,CAAC,CAAC;AAEK,MAAMC,UAAU,GAAAH,OAAA,CAAAG,UAAA,GAAGJ,YAAY,CAACK,QAAQ;AAIxC,SAASC,SAASA,CAACC,GAAiB,EAAU;EACpD,OAAOH,UAAU,CAACG,GAAG,CAAC;AACvB;;AAEA;AACA;AACA;AACA;AACA,MAAMC,cAAiD,GAAG;EACzD,cAAc,EAAE,iBAAiB;EACjC,iBAAiB,EAAE,iBAAiB;EACpCC,OAAO,EAAE,kBAAkB;EAC3B,cAAc,EAAE,0BAA0B;EAC1C,cAAc,EAAE,kBAAkB;EAClC,aAAa,EAAE,sBAAsB;EACrC,cAAc,EAAE,sBAAsB;EACtC,eAAe,EAAE,eAAe;EAChC,mBAAmB,EAAE,0BAA0B;EAC/C,sBAAsB,EAAE,mBAAmB;EAC3C,oBAAoB,EAAE,sBAAsB;EAC5C,gBAAgB,EAAE,kBAAkB;EACpCC,QAAQ,EAAE;AACX,CAAC;;AAED;AACO,SAASC,kBAAkBA,CAACC,KAAc,EAAgB;EAChE,OAAOJ,cAAc,CAACI,KAAK,CAACC,IAAI,CAAC;AAClC","ignoreList":[]}
|