@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,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "AiError", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _errors.AiError;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "GATEWAY_ERROR_STATUS", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _gateway.GATEWAY_ERROR_STATUS;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "QUOTA_HEADERS", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _gateway.QUOTA_HEADERS;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "SSE_DONE_SENTINEL", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _gateway.SSE_DONE_SENTINEL;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "SUPPORTED_SCHEMA_VERSION", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _behaviorConfig.SUPPORTED_SCHEMA_VERSION;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "aiMessage", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _messageKeys.aiMessage;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "aiMessageSet", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _messageKeys.aiMessageSet;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "aiMessages", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _messageKeys.aiMessages;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, "configCacheFromKeyValue", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _behaviorConfig.configCacheFromKeyValue;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, "createAiClient", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _aiClient.createAiClient;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "isAiError", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _errors.isAiError;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(exports, "messageKeyForError", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () {
|
|
75
|
+
return _messageKeys.messageKeyForError;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(exports, "useAiBehaviorState", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return _hooks.useAiBehaviorState;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(exports, "useAiChat", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () {
|
|
87
|
+
return _hooks.useAiChat;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(exports, "useAiQuota", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return _hooks.useAiQuota;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
var _aiClient = require("./core/aiClient.js");
|
|
97
|
+
var _behaviorConfig = require("./config/behaviorConfig.js");
|
|
98
|
+
var _gateway = require("./contract/gateway.js");
|
|
99
|
+
var _hooks = require("./react/hooks.js");
|
|
100
|
+
var _errors = require("./diagnostics/errors.js");
|
|
101
|
+
var _messageKeys = require("./diagnostics/messageKeys.js");
|
|
102
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_aiClient","require","_behaviorConfig","_gateway","_hooks","_errors","_messageKeys"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,IAAAA,SAAA,GAAAC,OAAA;AAiBA,IAAAC,eAAA,GAAAD,OAAA;AAaA,IAAAE,QAAA,GAAAF,OAAA;AAUA,IAAAG,MAAA,GAAAH,OAAA;AAQA,IAAAI,OAAA,GAAAJ,OAAA;AAEA,IAAAK,YAAA,GAAAL,OAAA","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useAiBehaviorState = useAiBehaviorState;
|
|
7
|
+
exports.useAiChat = useAiChat;
|
|
8
|
+
exports.useAiQuota = useAiQuota;
|
|
9
|
+
var _react = require("@chipmobilesdk/rn-core/react");
|
|
10
|
+
var _react2 = require("react");
|
|
11
|
+
const DEFAULT_FLUSH_MS = 50;
|
|
12
|
+
function useAiChat(client, options = {}) {
|
|
13
|
+
const [status, setStatus] = (0, _react2.useState)('idle');
|
|
14
|
+
const [text, setText] = (0, _react2.useState)('');
|
|
15
|
+
const [error, setError] = (0, _react2.useState)();
|
|
16
|
+
const [retryAt, setRetryAt] = (0, _react2.useState)();
|
|
17
|
+
const fromClient = useAiQuotaValue(client);
|
|
18
|
+
// The figure this chat was told, for a client of the app's own that keeps none.
|
|
19
|
+
const [reported, setReported] = (0, _react2.useState)();
|
|
20
|
+
const quota = fromClient ?? reported;
|
|
21
|
+
const handleRef = (0, _react2.useRef)(null);
|
|
22
|
+
// Bumped by every send, cancel and unmount. A callback from an older request
|
|
23
|
+
// is dropped, so it can never overwrite the state of the one on screen —
|
|
24
|
+
// defence in depth behind the client's own cancel guard.
|
|
25
|
+
const requestRef = (0, _react2.useRef)(0);
|
|
26
|
+
|
|
27
|
+
// Deltas land here and reach React on a timer, so the transcript renders at a
|
|
28
|
+
// steady rate however fast the model answers.
|
|
29
|
+
const pending = (0, _react2.useRef)('');
|
|
30
|
+
const flushTimer = (0, _react2.useRef)(undefined);
|
|
31
|
+
const flushMs = options.flushIntervalMs ?? DEFAULT_FLUSH_MS;
|
|
32
|
+
const stopFlushing = (0, _react2.useCallback)(() => {
|
|
33
|
+
if (flushTimer.current !== undefined) {
|
|
34
|
+
clearTimeout(flushTimer.current);
|
|
35
|
+
flushTimer.current = undefined;
|
|
36
|
+
}
|
|
37
|
+
}, []);
|
|
38
|
+
const flush = (0, _react2.useCallback)(() => {
|
|
39
|
+
flushTimer.current = undefined;
|
|
40
|
+
const buffered = pending.current;
|
|
41
|
+
if (buffered === '') {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
pending.current = '';
|
|
45
|
+
setText(previous => previous + buffered);
|
|
46
|
+
}, []);
|
|
47
|
+
(0, _react2.useEffect)(() => stopFlushing, [stopFlushing]);
|
|
48
|
+
const send = (0, _react2.useCallback)(request => {
|
|
49
|
+
handleRef.current?.cancel();
|
|
50
|
+
const id = ++requestRef.current;
|
|
51
|
+
const current = () => requestRef.current === id;
|
|
52
|
+
stopFlushing();
|
|
53
|
+
pending.current = '';
|
|
54
|
+
setText('');
|
|
55
|
+
setError(undefined);
|
|
56
|
+
setRetryAt(undefined);
|
|
57
|
+
setStatus('loading');
|
|
58
|
+
handleRef.current = client.chat(request, {
|
|
59
|
+
onDelta: delta => {
|
|
60
|
+
if (!current()) return;
|
|
61
|
+
pending.current += delta;
|
|
62
|
+
if (flushMs <= 0) {
|
|
63
|
+
flush();
|
|
64
|
+
} else if (flushTimer.current === undefined) {
|
|
65
|
+
flushTimer.current = setTimeout(flush, flushMs);
|
|
66
|
+
}
|
|
67
|
+
// Only the first delta is a state change; the rest are text.
|
|
68
|
+
setStatus(previous => previous === 'streaming' ? previous : 'streaming');
|
|
69
|
+
},
|
|
70
|
+
onDone: result => {
|
|
71
|
+
if (!current()) return;
|
|
72
|
+
stopFlushing();
|
|
73
|
+
flush();
|
|
74
|
+
if (result.quota) setReported(result.quota);
|
|
75
|
+
setStatus('done');
|
|
76
|
+
},
|
|
77
|
+
onError: aiError => {
|
|
78
|
+
if (!current()) return;
|
|
79
|
+
stopFlushing();
|
|
80
|
+
// Whatever arrived before the failure is kept: a half-answer is
|
|
81
|
+
// still what the user was reading.
|
|
82
|
+
flush();
|
|
83
|
+
setError(aiError);
|
|
84
|
+
if (aiError.code === 'rate-limited') {
|
|
85
|
+
setStatus('rate-limited');
|
|
86
|
+
if (aiError.retryAfterSeconds !== undefined) {
|
|
87
|
+
setRetryAt(new Date(Date.now() + aiError.retryAfterSeconds * 1000));
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
setStatus('error');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}, [client, flush, flushMs, stopFlushing]);
|
|
95
|
+
const cancel = (0, _react2.useCallback)(() => {
|
|
96
|
+
requestRef.current += 1;
|
|
97
|
+
stopFlushing();
|
|
98
|
+
handleRef.current?.cancel();
|
|
99
|
+
setStatus('idle');
|
|
100
|
+
}, [stopFlushing]);
|
|
101
|
+
(0, _react2.useEffect)(() => () => {
|
|
102
|
+
requestRef.current += 1;
|
|
103
|
+
handleRef.current?.cancel();
|
|
104
|
+
}, []);
|
|
105
|
+
return {
|
|
106
|
+
send,
|
|
107
|
+
cancel,
|
|
108
|
+
status,
|
|
109
|
+
text,
|
|
110
|
+
error,
|
|
111
|
+
retryAt,
|
|
112
|
+
quota
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const noSubscription = () => () => undefined;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The quota the client last saw, from a chat's `done` event or from
|
|
119
|
+
* `getQuota()`. One source, so a figure on screen is not stale the moment a
|
|
120
|
+
* chat finishes (AI-13).
|
|
121
|
+
*/
|
|
122
|
+
function useAiQuotaValue(client) {
|
|
123
|
+
return (0, _react.useExternalStore)(client.subscribe ?? noSubscription, client.lastQuota ?? (() => undefined));
|
|
124
|
+
}
|
|
125
|
+
function useAiQuota(client) {
|
|
126
|
+
const fromClient = useAiQuotaValue(client);
|
|
127
|
+
// A client of the app's own may not keep the last quota; then this is it.
|
|
128
|
+
const [fetched, setFetched] = (0, _react2.useState)();
|
|
129
|
+
const quota = fromClient ?? fetched;
|
|
130
|
+
const [status, setStatus] = (0, _react2.useState)('loading');
|
|
131
|
+
const alive = (0, _react2.useRef)(true);
|
|
132
|
+
// Only the latest refresh may settle the state; an older, slower one that
|
|
133
|
+
// lands afterwards is stale.
|
|
134
|
+
const latest = (0, _react2.useRef)(0);
|
|
135
|
+
const refresh = (0, _react2.useCallback)(() => {
|
|
136
|
+
const id = ++latest.current;
|
|
137
|
+
const current = () => alive.current && latest.current === id;
|
|
138
|
+
setStatus('loading');
|
|
139
|
+
client.getQuota().then(snapshot => {
|
|
140
|
+
if (!current()) return;
|
|
141
|
+
setFetched(snapshot);
|
|
142
|
+
setStatus('ready');
|
|
143
|
+
}).catch(() => {
|
|
144
|
+
if (current()) setStatus('error');
|
|
145
|
+
});
|
|
146
|
+
}, [client]);
|
|
147
|
+
(0, _react2.useEffect)(() => {
|
|
148
|
+
alive.current = true;
|
|
149
|
+
refresh();
|
|
150
|
+
return () => {
|
|
151
|
+
alive.current = false;
|
|
152
|
+
};
|
|
153
|
+
}, [refresh]);
|
|
154
|
+
|
|
155
|
+
// A quota that arrived through a chat is an answer too: nothing is loading.
|
|
156
|
+
return {
|
|
157
|
+
quota,
|
|
158
|
+
status: status === 'loading' && quota ? 'ready' : status,
|
|
159
|
+
refresh
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* The client's behavior state (config source and whether AI is enabled), live:
|
|
165
|
+
* re-renders when the kill switch flips or the config state moves (AI-09).
|
|
166
|
+
*/
|
|
167
|
+
function useAiBehaviorState(client) {
|
|
168
|
+
return (0, _react.useExternalStore)(client.subscribe ?? noSubscription, client.getBehaviorState);
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_react2","DEFAULT_FLUSH_MS","useAiChat","client","options","status","setStatus","useState","text","setText","error","setError","retryAt","setRetryAt","fromClient","useAiQuotaValue","reported","setReported","quota","handleRef","useRef","requestRef","pending","flushTimer","undefined","flushMs","flushIntervalMs","stopFlushing","useCallback","current","clearTimeout","flush","buffered","previous","useEffect","send","request","cancel","id","chat","onDelta","delta","setTimeout","onDone","result","onError","aiError","code","retryAfterSeconds","Date","now","noSubscription","useExternalStore","subscribe","lastQuota","useAiQuota","fetched","setFetched","alive","latest","refresh","getQuota","then","snapshot","catch","useAiBehaviorState","getBehaviorState"],"sourceRoot":"../../../src","sources":["react/hooks.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.drainSseEvents = drainSseEvents;
|
|
7
|
+
exports.requestSse = requestSse;
|
|
8
|
+
/**
|
|
9
|
+
* Minimal SSE reader over XMLHttpRequest (research R2).
|
|
10
|
+
*
|
|
11
|
+
* React Native's fetch does not reliably expose ReadableStream on Hermes, so
|
|
12
|
+
* we use XHR incremental text delivery (readyState LOADING + onprogress) —
|
|
13
|
+
* the same mechanism community SSE libraries use — with zero dependencies.
|
|
14
|
+
* The gateway never compresses SSE responses (contract), which keeps
|
|
15
|
+
* incremental delivery intact on both platforms.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** What the response said besides its body. Absent for a failure with no response. */
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The transport port: how this package makes a streaming request.
|
|
22
|
+
*
|
|
23
|
+
* A published port rather than `typeof requestSse`, so the default reader's
|
|
24
|
+
* own signature is not part of the public API (AI-18): an app may inject its
|
|
25
|
+
* own transport, and this package may change how `requestSse` is written
|
|
26
|
+
* without that being a breaking change.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Parse complete `data:` events out of `text` starting at `fromIndex`.
|
|
31
|
+
*
|
|
32
|
+
* Both line endings are accepted. A proxy that normalises to CRLF — an API
|
|
33
|
+
* gateway or a corporate middlebox — used to make every event invisible until
|
|
34
|
+
* the stream closed, because only `\n\n` counted as a separator (AI-22).
|
|
35
|
+
*/
|
|
36
|
+
function drainSseEvents(text, fromIndex, emit) {
|
|
37
|
+
let cursor = fromIndex;
|
|
38
|
+
for (;;) {
|
|
39
|
+
const separator = /\r\n\r\n|\n\n|\r\r/.exec(text.slice(cursor));
|
|
40
|
+
if (!separator) {
|
|
41
|
+
return cursor; // incomplete event stays buffered
|
|
42
|
+
}
|
|
43
|
+
const rawEvent = text.slice(cursor, cursor + separator.index);
|
|
44
|
+
cursor += separator.index + separator[0].length;
|
|
45
|
+
const dataLines = rawEvent.split(/\r\n|\n|\r/).filter(line => line.startsWith('data:')).map(line => line.slice(5).trimStart());
|
|
46
|
+
if (dataLines.length > 0) {
|
|
47
|
+
emit(dataLines.join('\n'));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function requestSse(request, handlers) {
|
|
52
|
+
const xhr = new XMLHttpRequest();
|
|
53
|
+
let seen = 0;
|
|
54
|
+
let finished = false;
|
|
55
|
+
let cancelled = false;
|
|
56
|
+
|
|
57
|
+
// One timer, re-armed as the request progresses: the connect limit until
|
|
58
|
+
// headers arrive, then the idle limit, restarted by every chunk.
|
|
59
|
+
let stallTimer;
|
|
60
|
+
const disarm = () => {
|
|
61
|
+
if (stallTimer !== undefined) {
|
|
62
|
+
clearTimeout(stallTimer);
|
|
63
|
+
stallTimer = undefined;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/** The response's own headers, for `Retry-After` on a 429 (AI-11). */
|
|
68
|
+
const response = {
|
|
69
|
+
getHeader(name) {
|
|
70
|
+
try {
|
|
71
|
+
return xhr.getResponseHeader(name);
|
|
72
|
+
} catch {
|
|
73
|
+
// Headers are unavailable before they arrive, and on some polyfills.
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const finish = fn => {
|
|
79
|
+
disarm();
|
|
80
|
+
if (!finished && !cancelled) {
|
|
81
|
+
finished = true;
|
|
82
|
+
fn();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const stalled = () => {
|
|
86
|
+
stallTimer = undefined;
|
|
87
|
+
if (finished || cancelled) return;
|
|
88
|
+
finished = true;
|
|
89
|
+
try {
|
|
90
|
+
xhr.abort();
|
|
91
|
+
} catch {
|
|
92
|
+
// already settled
|
|
93
|
+
}
|
|
94
|
+
handlers.onError(0, 'timeout');
|
|
95
|
+
};
|
|
96
|
+
const arm = ms => {
|
|
97
|
+
disarm();
|
|
98
|
+
if (ms && !finished && !cancelled) stallTimer = setTimeout(stalled, ms);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Drains whatever has arrived. `onprogress` and `readyState === 3` both fire
|
|
103
|
+
* for the same chunk, and which of the two fires at all has been platform
|
|
104
|
+
* dependent, so both stay registered; the length check makes the second call
|
|
105
|
+
* for one chunk free rather than another full `responseText` drain (AI-V1).
|
|
106
|
+
*/
|
|
107
|
+
let drained = -1;
|
|
108
|
+
const pump = () => {
|
|
109
|
+
if (xhr.status !== 200) return; // error path handled on load/error
|
|
110
|
+
const text = xhr.responseText ?? '';
|
|
111
|
+
if (text.length === drained) return;
|
|
112
|
+
drained = text.length;
|
|
113
|
+
arm(request.idleTimeoutMs);
|
|
114
|
+
seen = drainSseEvents(text, seen, handlers.onData);
|
|
115
|
+
};
|
|
116
|
+
xhr.open(request.method ?? 'POST', request.url, true);
|
|
117
|
+
for (const [k, v] of Object.entries(request.headers ?? {})) {
|
|
118
|
+
xhr.setRequestHeader(k, v);
|
|
119
|
+
}
|
|
120
|
+
xhr.setRequestHeader('Accept', 'text/event-stream');
|
|
121
|
+
if (request.timeoutMs) xhr.timeout = request.timeoutMs;
|
|
122
|
+
xhr.onprogress = pump;
|
|
123
|
+
xhr.onreadystatechange = () => {
|
|
124
|
+
if (xhr.readyState === 2) arm(request.connectTimeoutMs); // HEADERS_RECEIVED
|
|
125
|
+
if (xhr.readyState === 3) pump(); // LOADING: incremental text
|
|
126
|
+
};
|
|
127
|
+
xhr.onload = () => {
|
|
128
|
+
if (xhr.status === 200) {
|
|
129
|
+
pump();
|
|
130
|
+
finish(handlers.onEnd);
|
|
131
|
+
} else {
|
|
132
|
+
finish(() => handlers.onError(xhr.status, xhr.responseText ?? '', response));
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
xhr.onerror = () => finish(() => handlers.onError(0, 'network error'));
|
|
136
|
+
xhr.ontimeout = () => finish(() => handlers.onError(0, 'timeout'));
|
|
137
|
+
xhr.send(request.body);
|
|
138
|
+
arm(request.connectTimeoutMs);
|
|
139
|
+
return {
|
|
140
|
+
cancel() {
|
|
141
|
+
cancelled = true;
|
|
142
|
+
disarm();
|
|
143
|
+
try {
|
|
144
|
+
xhr.abort();
|
|
145
|
+
} catch {
|
|
146
|
+
// aborting a settled XHR is a no-op
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=sseClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["drainSseEvents","text","fromIndex","emit","cursor","separator","exec","slice","rawEvent","index","length","dataLines","split","filter","line","startsWith","map","trimStart","join","requestSse","request","handlers","xhr","XMLHttpRequest","seen","finished","cancelled","stallTimer","disarm","undefined","clearTimeout","response","getHeader","name","getResponseHeader","finish","fn","stalled","abort","onError","arm","ms","setTimeout","drained","pump","status","responseText","idleTimeoutMs","onData","open","method","url","k","v","Object","entries","headers","setRequestHeader","timeoutMs","timeout","onprogress","onreadystatechange","readyState","connectTimeoutMs","onload","onEnd","onerror","ontimeout","send","body","cancel"],"sourceRoot":"../../../src","sources":["transport/sseClient.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DEFAULT_AI_TIMEOUTS = void 0;
|
|
7
|
+
exports.withTimeout = withTimeout;
|
|
8
|
+
/**
|
|
9
|
+
* Time limits for every network call the client makes (AI-04).
|
|
10
|
+
*
|
|
11
|
+
* Without them a stalled mobile connection left `useAiChat` in `loading` or
|
|
12
|
+
* `streaming`, and `useAiQuota` in `loading`, until the user gave up.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The gateway sends headers only once the model has answered, so `connectMs`
|
|
17
|
+
* also covers time to first token on a large image prompt.
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_AI_TIMEOUTS = exports.DEFAULT_AI_TIMEOUTS = {
|
|
20
|
+
connectMs: 30_000,
|
|
21
|
+
idleMs: 30_000,
|
|
22
|
+
configMs: 10_000,
|
|
23
|
+
quotaMs: 10_000
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Runs `run` with an abort signal and rejects with `onTimeout()` after `ms`.
|
|
28
|
+
* The race matters as much as the signal: an injected `fetchFn` (or an old
|
|
29
|
+
* polyfill) may ignore the signal entirely.
|
|
30
|
+
*/
|
|
31
|
+
async function withTimeout(ms, run, onTimeout) {
|
|
32
|
+
const controller = typeof AbortController === 'undefined' ? undefined : new AbortController();
|
|
33
|
+
let timer;
|
|
34
|
+
const expired = new Promise((_, reject) => {
|
|
35
|
+
timer = setTimeout(() => {
|
|
36
|
+
controller?.abort();
|
|
37
|
+
reject(onTimeout());
|
|
38
|
+
}, ms);
|
|
39
|
+
});
|
|
40
|
+
try {
|
|
41
|
+
return await Promise.race([run(controller?.signal), expired]);
|
|
42
|
+
} finally {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=timeouts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DEFAULT_AI_TIMEOUTS","exports","connectMs","idleMs","configMs","quotaMs","withTimeout","ms","run","onTimeout","controller","AbortController","undefined","timer","expired","Promise","_","reject","setTimeout","abort","race","signal","clearTimeout"],"sourceRoot":"../../../src","sources":["transport/timeouts.ts"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA;AACA;AACA;AACO,MAAMA,mBAA+B,GAAAC,OAAA,CAAAD,mBAAA,GAAG;EAC9CE,SAAS,EAAE,MAAM;EACjBC,MAAM,EAAE,MAAM;EACdC,QAAQ,EAAE,MAAM;EAChBC,OAAO,EAAE;AACV,CAAC;;AAED;AACA;AACA;AACA;AACA;AACO,eAAeC,WAAWA,CAChCC,EAAU,EACVC,GAAoD,EACpDC,SAAsB,EACT;EACb,MAAMC,UAAU,GAAG,OAAOC,eAAe,KAAK,WAAW,GAAGC,SAAS,GAAG,IAAID,eAAe,CAAC,CAAC;EAC7F,IAAIE,KAAgD;EACpD,MAAMC,OAAO,GAAG,IAAIC,OAAO,CAAQ,CAACC,CAAC,EAAEC,MAAM,KAAK;IACjDJ,KAAK,GAAGK,UAAU,CAAC,MAAM;MACxBR,UAAU,EAAES,KAAK,CAAC,CAAC;MACnBF,MAAM,CAACR,SAAS,CAAC,CAAC,CAAC;IACpB,CAAC,EAAEF,EAAE,CAAC;EACP,CAAC,CAAC;EACF,IAAI;IACH,OAAO,MAAMQ,OAAO,CAACK,IAAI,CAAC,CAACZ,GAAG,CAACE,UAAU,EAAEW,MAAM,CAAC,EAAEP,OAAO,CAAC,CAAC;EAC9D,CAAC,SAAS;IACTQ,YAAY,CAACT,KAAK,CAAC;EACpB;AACD","ignoreList":[]}
|