@buoy-gg/agent-core 7.0.35 → 7.0.38
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 +21 -14
- package/lib/commonjs/blocks/receipts.js +57 -1
- package/lib/commonjs/blocks/receipts.js.map +1 -1
- package/lib/commonjs/blocks/types.js +23 -2
- package/lib/commonjs/blocks/types.js.map +1 -1
- package/lib/commonjs/blocks/uiTool.js +423 -10
- package/lib/commonjs/blocks/uiTool.js.map +1 -1
- package/lib/commonjs/catalog/catalog.g.js +213 -48
- package/lib/commonjs/catalog/catalog.g.js.map +1 -1
- package/lib/commonjs/catalog/catalog.source.json +226 -48
- package/lib/commonjs/catalog/catalog.types.g.js +44 -0
- package/lib/commonjs/catalog/catalog.types.g.js.map +1 -0
- package/lib/commonjs/catalog/normalizeParams.js +333 -0
- package/lib/commonjs/catalog/normalizeParams.js.map +1 -0
- package/lib/commonjs/catalog/signature.js +68 -0
- package/lib/commonjs/catalog/signature.js.map +1 -0
- package/lib/commonjs/catalog/snapshotReads.js +13 -6
- package/lib/commonjs/catalog/snapshotReads.js.map +1 -1
- package/lib/commonjs/catalog/toProviderTools.js +44 -6
- package/lib/commonjs/catalog/toProviderTools.js.map +1 -1
- package/lib/commonjs/context/buildContextPack.js +367 -19
- package/lib/commonjs/context/buildContextPack.js.map +1 -1
- package/lib/commonjs/effects/digest.js +34 -0
- package/lib/commonjs/effects/digest.js.map +1 -0
- package/lib/commonjs/effects/ledger.js +98 -2
- package/lib/commonjs/effects/ledger.js.map +1 -1
- package/lib/commonjs/engine/askGate.js +287 -0
- package/lib/commonjs/engine/askGate.js.map +1 -0
- package/lib/commonjs/engine/effectFor.js +82 -1
- package/lib/commonjs/engine/effectFor.js.map +1 -1
- package/lib/commonjs/engine/evidence.js +113 -0
- package/lib/commonjs/engine/evidence.js.map +1 -0
- package/lib/commonjs/engine/historyBudget.js +363 -0
- package/lib/commonjs/engine/historyBudget.js.map +1 -0
- package/lib/commonjs/engine/retrieve.js +214 -0
- package/lib/commonjs/engine/retrieve.js.map +1 -0
- package/lib/commonjs/engine/runAgentTurn.js +1231 -120
- package/lib/commonjs/engine/runAgentTurn.js.map +1 -1
- package/lib/commonjs/engine/systemPrompt.js +103 -9
- package/lib/commonjs/engine/systemPrompt.js.map +1 -1
- package/lib/commonjs/engine/textToolCalls.js +276 -0
- package/lib/commonjs/engine/textToolCalls.js.map +1 -0
- package/lib/commonjs/engine/tokenCalibration.js +81 -0
- package/lib/commonjs/engine/tokenCalibration.js.map +1 -0
- package/lib/commonjs/engine/verify.js +300 -0
- package/lib/commonjs/engine/verify.js.map +1 -0
- package/lib/commonjs/index.js +74 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/policy/labels.js +19 -3
- package/lib/commonjs/policy/labels.js.map +1 -1
- package/lib/commonjs/policy/policy.js +6 -1
- package/lib/commonjs/policy/policy.js.map +1 -1
- package/lib/commonjs/policy/redact.js +42 -5
- package/lib/commonjs/policy/redact.js.map +1 -1
- package/lib/commonjs/providers/anthropic.js +340 -208
- package/lib/commonjs/providers/anthropic.js.map +1 -1
- package/lib/commonjs/providers/openai.js +237 -103
- package/lib/commonjs/providers/openai.js.map +1 -1
- package/lib/commonjs/providers/problem.js +98 -0
- package/lib/commonjs/providers/problem.js.map +1 -0
- package/lib/commonjs/providers/sse.js +170 -34
- package/lib/commonjs/providers/sse.js.map +1 -1
- package/lib/commonjs/providers/streamTimer.js +123 -0
- package/lib/commonjs/providers/streamTimer.js.map +1 -0
- package/lib/commonjs/providers/transport.js +123 -0
- package/lib/commonjs/providers/transport.js.map +1 -0
- package/lib/commonjs/providers/xhrStream.js +212 -0
- package/lib/commonjs/providers/xhrStream.js.map +1 -0
- package/lib/commonjs/session.js +242 -58
- package/lib/commonjs/session.js.map +1 -1
- package/lib/module/blocks/receipts.js +57 -1
- package/lib/module/blocks/receipts.js.map +1 -1
- package/lib/module/blocks/types.js +23 -2
- package/lib/module/blocks/types.js.map +1 -1
- package/lib/module/blocks/uiTool.js +421 -10
- package/lib/module/blocks/uiTool.js.map +1 -1
- package/lib/module/catalog/catalog.g.js +213 -48
- package/lib/module/catalog/catalog.g.js.map +1 -1
- package/lib/module/catalog/catalog.source.json +226 -48
- package/lib/module/catalog/catalog.types.g.js +40 -0
- package/lib/module/catalog/catalog.types.g.js.map +1 -0
- package/lib/module/catalog/normalizeParams.js +327 -0
- package/lib/module/catalog/normalizeParams.js.map +1 -0
- package/lib/module/catalog/signature.js +63 -0
- package/lib/module/catalog/signature.js.map +1 -0
- package/lib/module/catalog/snapshotReads.js +13 -6
- package/lib/module/catalog/snapshotReads.js.map +1 -1
- package/lib/module/catalog/toProviderTools.js +44 -6
- package/lib/module/catalog/toProviderTools.js.map +1 -1
- package/lib/module/context/buildContextPack.js +366 -19
- package/lib/module/context/buildContextPack.js.map +1 -1
- package/lib/module/effects/digest.js +29 -0
- package/lib/module/effects/digest.js.map +1 -0
- package/lib/module/effects/ledger.js +98 -2
- package/lib/module/effects/ledger.js.map +1 -1
- package/lib/module/engine/askGate.js +280 -0
- package/lib/module/engine/askGate.js.map +1 -0
- package/lib/module/engine/effectFor.js +83 -1
- package/lib/module/engine/effectFor.js.map +1 -1
- package/lib/module/engine/evidence.js +107 -0
- package/lib/module/engine/evidence.js.map +1 -0
- package/lib/module/engine/historyBudget.js +355 -0
- package/lib/module/engine/historyBudget.js.map +1 -0
- package/lib/module/engine/retrieve.js +210 -0
- package/lib/module/engine/retrieve.js.map +1 -0
- package/lib/module/engine/runAgentTurn.js +1227 -121
- package/lib/module/engine/runAgentTurn.js.map +1 -1
- package/lib/module/engine/systemPrompt.js +101 -9
- package/lib/module/engine/systemPrompt.js.map +1 -1
- package/lib/module/engine/textToolCalls.js +270 -0
- package/lib/module/engine/textToolCalls.js.map +1 -0
- package/lib/module/engine/tokenCalibration.js +75 -0
- package/lib/module/engine/tokenCalibration.js.map +1 -0
- package/lib/module/engine/verify.js +292 -0
- package/lib/module/engine/verify.js.map +1 -0
- package/lib/module/index.js +7 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/policy/labels.js +19 -3
- package/lib/module/policy/labels.js.map +1 -1
- package/lib/module/policy/policy.js +6 -1
- package/lib/module/policy/policy.js.map +1 -1
- package/lib/module/policy/redact.js +42 -5
- package/lib/module/policy/redact.js.map +1 -1
- package/lib/module/providers/anthropic.js +341 -209
- package/lib/module/providers/anthropic.js.map +1 -1
- package/lib/module/providers/openai.js +238 -104
- package/lib/module/providers/openai.js.map +1 -1
- package/lib/module/providers/problem.js +92 -0
- package/lib/module/providers/problem.js.map +1 -0
- package/lib/module/providers/sse.js +166 -34
- package/lib/module/providers/sse.js.map +1 -1
- package/lib/module/providers/streamTimer.js +118 -0
- package/lib/module/providers/streamTimer.js.map +1 -0
- package/lib/module/providers/transport.js +119 -0
- package/lib/module/providers/transport.js.map +1 -0
- package/lib/module/providers/xhrStream.js +207 -0
- package/lib/module/providers/xhrStream.js.map +1 -0
- package/lib/module/session.js +226 -60
- package/lib/module/session.js.map +1 -1
- package/lib/typescript/blocks/receipts.d.ts +5 -0
- package/lib/typescript/blocks/receipts.d.ts.map +1 -1
- package/lib/typescript/blocks/types.d.ts +23 -2
- package/lib/typescript/blocks/types.d.ts.map +1 -1
- package/lib/typescript/blocks/uiTool.d.ts +11 -2
- package/lib/typescript/blocks/uiTool.d.ts.map +1 -1
- package/lib/typescript/catalog/catalog.g.d.ts +2 -2
- package/lib/typescript/catalog/catalog.g.d.ts.map +1 -1
- package/lib/typescript/catalog/catalog.types.g.d.ts +40 -0
- package/lib/typescript/catalog/catalog.types.g.d.ts.map +1 -0
- package/lib/typescript/catalog/normalizeParams.d.ts +43 -0
- package/lib/typescript/catalog/normalizeParams.d.ts.map +1 -0
- package/lib/typescript/catalog/signature.d.ts +29 -0
- package/lib/typescript/catalog/signature.d.ts.map +1 -0
- package/lib/typescript/catalog/snapshotReads.d.ts.map +1 -1
- package/lib/typescript/catalog/toProviderTools.d.ts +28 -15
- package/lib/typescript/catalog/toProviderTools.d.ts.map +1 -1
- package/lib/typescript/context/buildContextPack.d.ts +24 -2
- package/lib/typescript/context/buildContextPack.d.ts.map +1 -1
- package/lib/typescript/effects/digest.d.ts +10 -0
- package/lib/typescript/effects/digest.d.ts.map +1 -0
- package/lib/typescript/effects/ledger.d.ts +73 -0
- package/lib/typescript/effects/ledger.d.ts.map +1 -1
- package/lib/typescript/engine/askGate.d.ts +29 -0
- package/lib/typescript/engine/askGate.d.ts.map +1 -0
- package/lib/typescript/engine/effectFor.d.ts +6 -1
- package/lib/typescript/engine/effectFor.d.ts.map +1 -1
- package/lib/typescript/engine/evidence.d.ts +67 -0
- package/lib/typescript/engine/evidence.d.ts.map +1 -0
- package/lib/typescript/engine/historyBudget.d.ts +115 -0
- package/lib/typescript/engine/historyBudget.d.ts.map +1 -0
- package/lib/typescript/engine/retrieve.d.ts +32 -0
- package/lib/typescript/engine/retrieve.d.ts.map +1 -0
- package/lib/typescript/engine/runAgentTurn.d.ts +179 -3
- package/lib/typescript/engine/runAgentTurn.d.ts.map +1 -1
- package/lib/typescript/engine/systemPrompt.d.ts +80 -0
- package/lib/typescript/engine/systemPrompt.d.ts.map +1 -1
- package/lib/typescript/engine/textToolCalls.d.ts +58 -0
- package/lib/typescript/engine/textToolCalls.d.ts.map +1 -0
- package/lib/typescript/engine/tokenCalibration.d.ts +46 -0
- package/lib/typescript/engine/tokenCalibration.d.ts.map +1 -0
- package/lib/typescript/engine/verify.d.ts +67 -0
- package/lib/typescript/engine/verify.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +7 -3
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/policy/labels.d.ts.map +1 -1
- package/lib/typescript/policy/policy.d.ts.map +1 -1
- package/lib/typescript/policy/redact.d.ts.map +1 -1
- package/lib/typescript/providers/anthropic.d.ts.map +1 -1
- package/lib/typescript/providers/openai.d.ts +0 -16
- package/lib/typescript/providers/openai.d.ts.map +1 -1
- package/lib/typescript/providers/problem.d.ts +50 -0
- package/lib/typescript/providers/problem.d.ts.map +1 -0
- package/lib/typescript/providers/sse.d.ts +86 -2
- package/lib/typescript/providers/sse.d.ts.map +1 -1
- package/lib/typescript/providers/streamTimer.d.ts +59 -0
- package/lib/typescript/providers/streamTimer.d.ts.map +1 -0
- package/lib/typescript/providers/transport.d.ts +48 -0
- package/lib/typescript/providers/transport.d.ts.map +1 -0
- package/lib/typescript/providers/types.d.ts +105 -3
- package/lib/typescript/providers/types.d.ts.map +1 -1
- package/lib/typescript/providers/xhrStream.d.ts +45 -0
- package/lib/typescript/providers/xhrStream.d.ts.map +1 -0
- package/lib/typescript/session.d.ts +55 -4
- package/lib/typescript/session.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +6 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +10 -10
- package/LICENSE +0 -58
|
@@ -4,7 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.errorBody = errorBody;
|
|
7
|
+
exports.framesFrom = framesFrom;
|
|
8
|
+
exports.nonStreamProblem = nonStreamProblem;
|
|
7
9
|
exports.readSse = readSse;
|
|
10
|
+
exports.truncatedMessage = truncatedMessage;
|
|
11
|
+
exports.unparseableMessage = unparseableMessage;
|
|
8
12
|
/**
|
|
9
13
|
* SSE reading, with the React Native reality baked in.
|
|
10
14
|
*
|
|
@@ -14,15 +18,24 @@ exports.readSse = readSse;
|
|
|
14
18
|
* TV-CLI lanes never had it. So `readSse` degrades to reading the whole body
|
|
15
19
|
* and replaying it as events rather than failing: a non-streaming answer is a
|
|
16
20
|
* slower chat, while a hard failure is no chat at all.
|
|
21
|
+
*
|
|
22
|
+
* THE TWO PATHS MUST AGREE. They did not. The buffered path appended "\n\n" to
|
|
23
|
+
* the body before parsing, which turns an unterminated final frame — the exact
|
|
24
|
+
* signature of a cut connection — into a well-formed event. The streaming path
|
|
25
|
+
* discarded that same frame, as the SSE spec requires. So one lane invented a
|
|
26
|
+
* complete answer where the other saw a broken one. Now both discard it and
|
|
27
|
+
* both RECORD it (`SseReadStatus.truncated`), because "was this reply whole?"
|
|
28
|
+
* is a question the engine has to answer before it runs anything.
|
|
17
29
|
*/
|
|
18
30
|
|
|
19
|
-
function* parseChunk(buffer) {
|
|
31
|
+
function* parseChunk(buffer, onFrame) {
|
|
20
32
|
let rest = buffer;
|
|
21
33
|
let idx;
|
|
22
34
|
// Frames are separated by a blank line. \r\n\r\n is legal too.
|
|
23
35
|
while ((idx = rest.search(/\r?\n\r?\n/)) !== -1) {
|
|
24
36
|
const raw = rest.slice(0, idx);
|
|
25
37
|
rest = rest.slice(idx + (rest[idx] === "\r" ? 4 : 2));
|
|
38
|
+
onFrame?.();
|
|
26
39
|
let event;
|
|
27
40
|
const dataLines = [];
|
|
28
41
|
for (const line of raw.split(/\r?\n/)) {
|
|
@@ -36,53 +49,124 @@ function* parseChunk(buffer) {
|
|
|
36
49
|
}
|
|
37
50
|
return rest;
|
|
38
51
|
}
|
|
39
|
-
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Drain complete frames out of `buffer`, returning what is left over.
|
|
55
|
+
*
|
|
56
|
+
* Shared by both paths so a framing fix can only ever be made in one place.
|
|
57
|
+
*/
|
|
58
|
+
function* drain(buffer, out, onFrame) {
|
|
59
|
+
const gen = parseChunk(buffer, onFrame);
|
|
60
|
+
let next = gen.next();
|
|
61
|
+
while (!next.done) {
|
|
62
|
+
yield next.value;
|
|
63
|
+
next = gen.next();
|
|
64
|
+
}
|
|
65
|
+
out.rest = next.value;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Turn a stream of TEXT chunks into SSE frames.
|
|
70
|
+
*
|
|
71
|
+
* The one place framing happens, whatever produced the bytes: a `fetch` body
|
|
72
|
+
* reader, an `XMLHttpRequest` progress slice, or a whole body read at once on
|
|
73
|
+
* a runtime that cannot stream. Splitting it out is what lets the XHR
|
|
74
|
+
* transport exist without a second parser to keep in step with this one.
|
|
75
|
+
*/
|
|
76
|
+
async function* framesFrom(chunks, options = {}) {
|
|
77
|
+
const {
|
|
78
|
+
status,
|
|
79
|
+
onFrame
|
|
80
|
+
} = options;
|
|
81
|
+
const leftover = {
|
|
82
|
+
rest: ""
|
|
83
|
+
};
|
|
84
|
+
let buffer = "";
|
|
85
|
+
for await (const chunk of chunks) {
|
|
86
|
+
buffer += chunk;
|
|
87
|
+
yield* drain(buffer, leftover, onFrame);
|
|
88
|
+
buffer = leftover.rest;
|
|
89
|
+
}
|
|
90
|
+
if (status && leftover.rest.trim()) status.truncated = true;
|
|
91
|
+
}
|
|
92
|
+
async function* readSse(response, options = {}) {
|
|
93
|
+
const {
|
|
94
|
+
status,
|
|
95
|
+
onFrame,
|
|
96
|
+
signal
|
|
97
|
+
} = options;
|
|
40
98
|
const body = response.body;
|
|
99
|
+
const leftover = {
|
|
100
|
+
rest: ""
|
|
101
|
+
};
|
|
41
102
|
if (!body || typeof body.getReader !== "function") {
|
|
42
|
-
// No streaming on this platform — read it all, then replay.
|
|
103
|
+
// No streaming on this platform — read it all, then replay. Note there is
|
|
104
|
+
// no "\n\n" here any more: an unterminated tail is discarded exactly as
|
|
105
|
+
// the streaming path discards it (see the header).
|
|
43
106
|
const text = await response.text();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
let next = gen.next();
|
|
47
|
-
while (!next.done) {
|
|
48
|
-
yield next.value;
|
|
49
|
-
next = gen.next();
|
|
50
|
-
}
|
|
51
|
-
rest = next.value;
|
|
52
|
-
if (rest.trim()) {
|
|
53
|
-
const tail = parseChunk(rest + "\n\n");
|
|
54
|
-
let t = tail.next();
|
|
55
|
-
while (!t.done) {
|
|
56
|
-
yield t.value;
|
|
57
|
-
t = tail.next();
|
|
58
|
-
}
|
|
59
|
-
}
|
|
107
|
+
yield* drain(text, leftover, onFrame);
|
|
108
|
+
if (status && leftover.rest.trim()) status.truncated = true;
|
|
60
109
|
return;
|
|
61
110
|
}
|
|
62
111
|
const reader = body.getReader();
|
|
63
112
|
const decoder = new TextDecoder();
|
|
64
113
|
let buffer = "";
|
|
114
|
+
let finished = false;
|
|
115
|
+
/**
|
|
116
|
+
* One promise for the whole read, not one per chunk.
|
|
117
|
+
*
|
|
118
|
+
* It never resolves — only rejects — so racing it is free apart from the
|
|
119
|
+
* `Promise.race` allocation, and an answer of a few hundred frames pays far
|
|
120
|
+
* more for `JSON.parse` than for this.
|
|
121
|
+
*/
|
|
122
|
+
const aborted = signal ? new Promise((_resolve, reject) => {
|
|
123
|
+
const fail = () => {
|
|
124
|
+
const err = new Error("Aborted");
|
|
125
|
+
err.name = "AbortError";
|
|
126
|
+
reject(err);
|
|
127
|
+
};
|
|
128
|
+
if (signal.aborted) fail();else signal.addEventListener?.("abort", fail, {
|
|
129
|
+
once: true
|
|
130
|
+
});
|
|
131
|
+
}) : undefined;
|
|
132
|
+
// Nothing awaits this until the race below, and a rejection with no handler
|
|
133
|
+
// is an unhandled rejection on some runtimes. This is the handler.
|
|
134
|
+
aborted?.catch(() => {});
|
|
65
135
|
try {
|
|
66
136
|
for (;;) {
|
|
137
|
+
const read = reader.read();
|
|
67
138
|
const {
|
|
68
139
|
done,
|
|
69
140
|
value
|
|
70
|
-
} = await
|
|
141
|
+
} = aborted ? await Promise.race([read, aborted]) : await read;
|
|
71
142
|
if (done) break;
|
|
72
143
|
buffer += decoder.decode(value, {
|
|
73
144
|
stream: true
|
|
74
145
|
});
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
while (!next.done) {
|
|
78
|
-
yield next.value;
|
|
79
|
-
next = gen.next();
|
|
80
|
-
}
|
|
81
|
-
buffer = next.value;
|
|
146
|
+
yield* drain(buffer, leftover, onFrame);
|
|
147
|
+
buffer = leftover.rest;
|
|
82
148
|
}
|
|
149
|
+
// Flush the decoder: a multi-byte character split across the last two
|
|
150
|
+
// chunks is only completed here, and an INCOMPLETE one at EOF is itself
|
|
151
|
+
// evidence the connection was cut.
|
|
152
|
+
buffer += decoder.decode();
|
|
153
|
+
yield* drain(buffer, leftover, onFrame);
|
|
154
|
+
if (status && leftover.rest.trim()) status.truncated = true;
|
|
155
|
+
finished = true;
|
|
83
156
|
} finally {
|
|
84
|
-
|
|
85
|
-
|
|
157
|
+
if (!finished) {
|
|
158
|
+
// The consumer left early — an abort, a timeout, or a `break` in the
|
|
159
|
+
// provider. `releaseLock` alone leaves the socket open; only `cancel`
|
|
160
|
+
// tears the request down, and it must come first because cancelling a
|
|
161
|
+
// locked reader is the only way to reach the underlying stream.
|
|
162
|
+
try {
|
|
163
|
+
// Not awaited: the consumer is already leaving, and a cancel that
|
|
164
|
+
// rejects (an errored stream) must not become an unhandled rejection.
|
|
165
|
+
void Promise.resolve(reader.cancel()).catch(() => {});
|
|
166
|
+
} catch {
|
|
167
|
+
/* already cancelled or errored */
|
|
168
|
+
}
|
|
169
|
+
}
|
|
86
170
|
try {
|
|
87
171
|
reader.releaseLock();
|
|
88
172
|
} catch {
|
|
@@ -91,14 +175,66 @@ async function* readSse(response) {
|
|
|
91
175
|
}
|
|
92
176
|
}
|
|
93
177
|
|
|
94
|
-
/**
|
|
178
|
+
/**
|
|
179
|
+
* A 200 that is not a stream at all.
|
|
180
|
+
*
|
|
181
|
+
* Gateways in front of a model do this: an auth proxy that has lost its
|
|
182
|
+
* upstream serves an HTML error page, a misrouted path serves an SPA shell,
|
|
183
|
+
* and a gateway that ignored `stream: true` serves one JSON object. Every one
|
|
184
|
+
* of those parses to zero SSE frames, so the old code read it as a model that
|
|
185
|
+
* had nothing to say and ended the turn with a blank bubble.
|
|
186
|
+
*
|
|
187
|
+
* Returns a message when the body should be treated as an error, and undefined
|
|
188
|
+
* when it looks like something the SSE reader can work with. Consumes the body
|
|
189
|
+
* only in the failing case.
|
|
190
|
+
*/
|
|
191
|
+
async function nonStreamProblem(response) {
|
|
192
|
+
const type = response.headers?.get?.("content-type") ?? "";
|
|
193
|
+
if (!type) return undefined; // No header to judge by — let the parser try.
|
|
194
|
+
const lowered = type.toLowerCase();
|
|
195
|
+
if (lowered.includes("event-stream")) return undefined;
|
|
196
|
+
// A JSON body is either a non-streaming reply or a structured error; both
|
|
197
|
+
// are worth reporting with their own text rather than guessing.
|
|
198
|
+
const detail = (await response.text().catch(() => "")).slice(0, 600);
|
|
199
|
+
if (lowered.includes("json")) {
|
|
200
|
+
return `The endpoint answered with JSON instead of a stream — it may not support "stream": true.${detail ? ` — ${detail}` : ""}`;
|
|
201
|
+
}
|
|
202
|
+
return `The endpoint answered with ${type} instead of an event stream.${detail ? ` — ${detail}` : ""}`;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Body text for a failed response, trimmed to something a user can read.
|
|
207
|
+
* The detail alone — the transport prefixes the status and classifies it.
|
|
208
|
+
*/
|
|
95
209
|
async function errorBody(response) {
|
|
96
|
-
let detail = "";
|
|
97
210
|
try {
|
|
98
|
-
|
|
211
|
+
return (await response.text()).slice(0, 600);
|
|
99
212
|
} catch {
|
|
100
|
-
|
|
213
|
+
return ""; // body already consumed or unreadable
|
|
101
214
|
}
|
|
102
|
-
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* The message for a stream that stopped before the provider said it was done.
|
|
219
|
+
*
|
|
220
|
+
* `truncated` distinguishes the two shapes: cut mid-frame (a dropped
|
|
221
|
+
* connection) versus a clean frame boundary with no terminal marker (a gateway
|
|
222
|
+
* that closes the socket instead of sending one). The second is a
|
|
223
|
+
* compatibility problem worth naming, because retrying it will not help.
|
|
224
|
+
*/
|
|
225
|
+
function truncatedMessage(truncated) {
|
|
226
|
+
return truncated ? "The connection dropped before the answer finished." : "The endpoint closed the stream without saying the answer was finished.";
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* The message for arguments that would not parse, with enough in it to act on.
|
|
231
|
+
* `stopReason` "length" is the common cause — a reasoning model spends its
|
|
232
|
+
* budget thinking and the tool call is truncated mid-JSON — and the tail of
|
|
233
|
+
* the raw arguments says immediately whether that is what happened.
|
|
234
|
+
*/
|
|
235
|
+
function unparseableMessage(name, args, stopReason) {
|
|
236
|
+
const truncated = stopReason === "length";
|
|
237
|
+
const tail = args.length > 160 ? `…${args.slice(-160)}` : args;
|
|
238
|
+
return `Model sent unparseable arguments for ${name}` + (truncated ? " (cut off at max_tokens — raise it or reduce thinking budget)" : "") + ` [stop: ${stopReason ?? "none"}, ${args.length} chars] ${tail}`;
|
|
103
239
|
}
|
|
104
240
|
//# sourceMappingURL=sse.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["parseChunk","buffer","rest","idx","search","raw","slice","event","dataLines","line","split","startsWith","trim","push","replace","length","data","join","readSse","response","body","getReader","text","
|
|
1
|
+
{"version":3,"names":["parseChunk","buffer","onFrame","rest","idx","search","raw","slice","event","dataLines","line","split","startsWith","trim","push","replace","length","data","join","drain","out","gen","next","done","value","framesFrom","chunks","options","status","leftover","chunk","truncated","readSse","response","signal","body","getReader","text","reader","decoder","TextDecoder","finished","aborted","Promise","_resolve","reject","fail","err","Error","name","addEventListener","once","undefined","catch","read","race","decode","stream","resolve","cancel","releaseLock","nonStreamProblem","type","headers","get","lowered","toLowerCase","includes","detail","errorBody","truncatedMessage","unparseableMessage","args","stopReason","tail"],"sourceRoot":"../../../src","sources":["providers/sse.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DEFAULT_IDLE_TIMEOUT_MS = exports.DEFAULT_CONNECT_TIMEOUT_MS = void 0;
|
|
7
|
+
exports.createStreamTimer = createStreamTimer;
|
|
8
|
+
/**
|
|
9
|
+
* The clock on a model request.
|
|
10
|
+
*
|
|
11
|
+
* There was none. A gateway that accepted the socket and then said nothing —
|
|
12
|
+
* an overloaded proxy, a dropped VPN, a laptop that slept mid-answer — left
|
|
13
|
+
* the turn running with the thinking strip animating until a person pressed
|
|
14
|
+
* Stop. The 180s turn deadline did not help: it is read at the TOP of a step
|
|
15
|
+
* (`runAgentTurn`), and a step parked inside `await fetch(...)` never reaches
|
|
16
|
+
* the next one.
|
|
17
|
+
*
|
|
18
|
+
* Two clocks, because the two silences mean different things:
|
|
19
|
+
*
|
|
20
|
+
* - CONNECT covers "no headers yet". Nothing has been generated, so nothing is
|
|
21
|
+
* lost by giving up; 30s is already long for a gateway to acknowledge a POST.
|
|
22
|
+
* - IDLE covers "headers arrived, then nothing". This one has to be generous.
|
|
23
|
+
* Anthropic sends `ping` frames, but an OpenAI-protocol reasoning model can
|
|
24
|
+
* legitimately emit nothing for a long stretch while it thinks, and cutting
|
|
25
|
+
* that off would look like a broken product. Any frame at all — a keepalive
|
|
26
|
+
* comment included — resets it, so only total silence trips it.
|
|
27
|
+
*
|
|
28
|
+
* A timeout is NOT a retry. Nothing is re-sent: the request may have reached
|
|
29
|
+
* the model, and a duplicate turn is a duplicate bill and possibly duplicate
|
|
30
|
+
* writes. The turn ends with an honest notice and a Continue button.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
const DEFAULT_CONNECT_TIMEOUT_MS = exports.DEFAULT_CONNECT_TIMEOUT_MS = 30_000;
|
|
34
|
+
const DEFAULT_IDLE_TIMEOUT_MS = exports.DEFAULT_IDLE_TIMEOUT_MS = 90_000;
|
|
35
|
+
/**
|
|
36
|
+
* A timer over an optional caller signal.
|
|
37
|
+
*
|
|
38
|
+
* When no `AbortController` exists (a runtime old enough to lack it) this
|
|
39
|
+
* degrades to passing the caller's signal straight through with no clocks,
|
|
40
|
+
* rather than failing to send anything at all.
|
|
41
|
+
*/
|
|
42
|
+
function createStreamTimer(callerSignal, options = {}) {
|
|
43
|
+
const connectMs = options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
44
|
+
const idleMs = options.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
|
|
45
|
+
const Controller = typeof AbortController === "function" ? AbortController : undefined;
|
|
46
|
+
if (!Controller) {
|
|
47
|
+
return {
|
|
48
|
+
signal: callerSignal,
|
|
49
|
+
connected() {},
|
|
50
|
+
activity() {},
|
|
51
|
+
expired: undefined,
|
|
52
|
+
message: () => undefined,
|
|
53
|
+
dispose() {}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const controller = new Controller();
|
|
57
|
+
let expired;
|
|
58
|
+
let handle;
|
|
59
|
+
let disposed = false;
|
|
60
|
+
const clear = () => {
|
|
61
|
+
if (handle !== undefined) {
|
|
62
|
+
clearTimeout(handle);
|
|
63
|
+
handle = undefined;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const arm = (ms, which) => {
|
|
67
|
+
clear();
|
|
68
|
+
if (disposed || !Number.isFinite(ms) || ms <= 0) return;
|
|
69
|
+
handle = setTimeout(() => {
|
|
70
|
+
handle = undefined;
|
|
71
|
+
expired = which;
|
|
72
|
+
// The abort is what actually unblocks `fetch` / `reader.read()`. The
|
|
73
|
+
// reason is tracked here rather than read back off the signal because
|
|
74
|
+
// `AbortSignal.reason` is not reliably present on React Native.
|
|
75
|
+
try {
|
|
76
|
+
controller.abort();
|
|
77
|
+
} catch {
|
|
78
|
+
/* already aborted */
|
|
79
|
+
}
|
|
80
|
+
}, ms);
|
|
81
|
+
};
|
|
82
|
+
const onCallerAbort = () => {
|
|
83
|
+
clear();
|
|
84
|
+
try {
|
|
85
|
+
controller.abort();
|
|
86
|
+
} catch {
|
|
87
|
+
/* already aborted */
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
if (callerSignal) {
|
|
91
|
+
if (callerSignal.aborted) onCallerAbort();else callerSignal.addEventListener?.("abort", onCallerAbort);
|
|
92
|
+
}
|
|
93
|
+
arm(connectMs, "connect");
|
|
94
|
+
return {
|
|
95
|
+
signal: controller.signal,
|
|
96
|
+
connected() {
|
|
97
|
+
arm(idleMs, "idle");
|
|
98
|
+
},
|
|
99
|
+
activity() {
|
|
100
|
+
// Only rearm a clock that is already running: a provider that reports
|
|
101
|
+
// activity after `dispose` must not resurrect the timer.
|
|
102
|
+
if (!disposed) arm(idleMs, "idle");
|
|
103
|
+
},
|
|
104
|
+
get expired() {
|
|
105
|
+
return expired;
|
|
106
|
+
},
|
|
107
|
+
message() {
|
|
108
|
+
if (expired === "connect") {
|
|
109
|
+
return `The model endpoint did not respond within ${Math.round(connectMs / 1000)}s. Nothing was generated, and nothing was re-sent.`;
|
|
110
|
+
}
|
|
111
|
+
if (expired === "idle") {
|
|
112
|
+
return `The model endpoint stopped sending after ${Math.round(idleMs / 1000)}s of silence. Whatever arrived is above; nothing was re-sent.`;
|
|
113
|
+
}
|
|
114
|
+
return undefined;
|
|
115
|
+
},
|
|
116
|
+
dispose() {
|
|
117
|
+
disposed = true;
|
|
118
|
+
clear();
|
|
119
|
+
callerSignal?.removeEventListener?.("abort", onCallerAbort);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=streamTimer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DEFAULT_CONNECT_TIMEOUT_MS","exports","DEFAULT_IDLE_TIMEOUT_MS","createStreamTimer","callerSignal","options","connectMs","connectTimeoutMs","idleMs","idleTimeoutMs","Controller","AbortController","undefined","signal","connected","activity","expired","message","dispose","controller","handle","disposed","clear","clearTimeout","arm","ms","which","Number","isFinite","setTimeout","abort","onCallerAbort","aborted","addEventListener","Math","round","removeEventListener"],"sourceRoot":"../../../src","sources":["providers/streamTimer.ts"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO,MAAMA,0BAA0B,GAAAC,OAAA,CAAAD,0BAAA,GAAG,MAAM;AACzC,MAAME,uBAAuB,GAAAD,OAAA,CAAAC,uBAAA,GAAG,MAAM;AA4B7C;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,iBAAiBA,CAC/BC,YAAqC,EACrCC,OAA2B,GAAG,CAAC,CAAC,EACnB;EACb,MAAMC,SAAS,GAAGD,OAAO,CAACE,gBAAgB,IAAIP,0BAA0B;EACxE,MAAMQ,MAAM,GAAGH,OAAO,CAACI,aAAa,IAAIP,uBAAuB;EAE/D,MAAMQ,UAAU,GAAG,OAAOC,eAAe,KAAK,UAAU,GAAGA,eAAe,GAAGC,SAAS;EACtF,IAAI,CAACF,UAAU,EAAE;IACf,OAAO;MACLG,MAAM,EAAET,YAAY;MACpBU,SAASA,CAAA,EAAG,CAAC,CAAC;MACdC,QAAQA,CAAA,EAAG,CAAC,CAAC;MACbC,OAAO,EAAEJ,SAAS;MAClBK,OAAO,EAAEA,CAAA,KAAML,SAAS;MACxBM,OAAOA,CAAA,EAAG,CAAC;IACb,CAAC;EACH;EAEA,MAAMC,UAAU,GAAG,IAAIT,UAAU,CAAC,CAAC;EACnC,IAAIM,OAAuC;EAC3C,IAAII,MAAiD;EACrD,IAAIC,QAAQ,GAAG,KAAK;EAEpB,MAAMC,KAAK,GAAGA,CAAA,KAAM;IAClB,IAAIF,MAAM,KAAKR,SAAS,EAAE;MACxBW,YAAY,CAACH,MAAM,CAAC;MACpBA,MAAM,GAAGR,SAAS;IACpB;EACF,CAAC;EAED,MAAMY,GAAG,GAAGA,CAACC,EAAU,EAAEC,KAAyB,KAAK;IACrDJ,KAAK,CAAC,CAAC;IACP,IAAID,QAAQ,IAAI,CAACM,MAAM,CAACC,QAAQ,CAACH,EAAE,CAAC,IAAIA,EAAE,IAAI,CAAC,EAAE;IACjDL,MAAM,GAAGS,UAAU,CAAC,MAAM;MACxBT,MAAM,GAAGR,SAAS;MAClBI,OAAO,GAAGU,KAAK;MACf;MACA;MACA;MACA,IAAI;QACFP,UAAU,CAACW,KAAK,CAAC,CAAC;MACpB,CAAC,CAAC,MAAM;QACN;MAAA;IAEJ,CAAC,EAAEL,EAAE,CAAC;EACR,CAAC;EAED,MAAMM,aAAa,GAAGA,CAAA,KAAM;IAC1BT,KAAK,CAAC,CAAC;IACP,IAAI;MACFH,UAAU,CAACW,KAAK,CAAC,CAAC;IACpB,CAAC,CAAC,MAAM;MACN;IAAA;EAEJ,CAAC;EAED,IAAI1B,YAAY,EAAE;IAChB,IAAIA,YAAY,CAAC4B,OAAO,EAAED,aAAa,CAAC,CAAC,CAAC,KACrC3B,YAAY,CAAC6B,gBAAgB,GAAG,OAAO,EAAEF,aAAa,CAAC;EAC9D;EAEAP,GAAG,CAAClB,SAAS,EAAE,SAAS,CAAC;EAEzB,OAAO;IACLO,MAAM,EAAEM,UAAU,CAACN,MAAM;IACzBC,SAASA,CAAA,EAAG;MACVU,GAAG,CAAChB,MAAM,EAAE,MAAM,CAAC;IACrB,CAAC;IACDO,QAAQA,CAAA,EAAG;MACT;MACA;MACA,IAAI,CAACM,QAAQ,EAAEG,GAAG,CAAChB,MAAM,EAAE,MAAM,CAAC;IACpC,CAAC;IACD,IAAIQ,OAAOA,CAAA,EAAG;MACZ,OAAOA,OAAO;IAChB,CAAC;IACDC,OAAOA,CAAA,EAAG;MACR,IAAID,OAAO,KAAK,SAAS,EAAE;QACzB,OAAO,6CAA6CkB,IAAI,CAACC,KAAK,CAAC7B,SAAS,GAAG,IAAI,CAAC,oDAAoD;MACtI;MACA,IAAIU,OAAO,KAAK,MAAM,EAAE;QACtB,OAAO,4CAA4CkB,IAAI,CAACC,KAAK,CAAC3B,MAAM,GAAG,IAAI,CAAC,+DAA+D;MAC7I;MACA,OAAOI,SAAS;IAClB,CAAC;IACDM,OAAOA,CAAA,EAAG;MACRG,QAAQ,GAAG,IAAI;MACfC,KAAK,CAAC,CAAC;MACPlB,YAAY,EAAEgC,mBAAmB,GAAG,OAAO,EAAEL,aAAa,CAAC;IAC7D;EACF,CAAC;AACH","ignoreList":[]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createTransport = createTransport;
|
|
7
|
+
var _sse = require("./sse");
|
|
8
|
+
var _xhrStream = require("./xhrStream");
|
|
9
|
+
var _problem = require("./problem");
|
|
10
|
+
/**
|
|
11
|
+
* How a request is SENT, decided before it is sent.
|
|
12
|
+
*
|
|
13
|
+
* The obvious place to add XHR was inside `readSse`, once a missing
|
|
14
|
+
* `response.body` had already proved that `fetch` could not stream. That is
|
|
15
|
+
* the wrong boundary and would have been a real bug: the POST has already
|
|
16
|
+
* happened by then, the reader has neither the URL nor the headers nor the
|
|
17
|
+
* body to repeat it, and issuing a second one would ask the model to generate
|
|
18
|
+
* the same answer twice — billed twice, and for a turn that writes, acted on
|
|
19
|
+
* twice. Transport is chosen up front; a response that has started is consumed
|
|
20
|
+
* exactly once, whatever it turns out to be.
|
|
21
|
+
*
|
|
22
|
+
* `auto` therefore learns rather than probes. The first request goes through
|
|
23
|
+
* `fetch`; if that response has no reader, the answer is buffered (as it
|
|
24
|
+
* always was on that runtime) and the SESSION remembers, so every later
|
|
25
|
+
* request uses XHR and streams. One buffered reply at the start of a bare-RN
|
|
26
|
+
* session, and nothing to configure.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
const EMPTY = async function* () {};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* One transport per provider instance, because the `auto` decision is worth
|
|
33
|
+
* remembering: re-learning it would buffer the first reply of every turn.
|
|
34
|
+
*/
|
|
35
|
+
function createTransport(config) {
|
|
36
|
+
const requested = config.transport ?? "auto";
|
|
37
|
+
/**
|
|
38
|
+
* Set once a `fetch` response has come back with no reader. Only ever
|
|
39
|
+
* flipped one way: a runtime does not gain streaming mid-session.
|
|
40
|
+
*/
|
|
41
|
+
let fetchCannotStream = false;
|
|
42
|
+
const useXhr = () => {
|
|
43
|
+
// A host-supplied `fetch` is never bypassed. It is how a harness keeps
|
|
44
|
+
// model traffic off the global (and out of the network interceptor), and
|
|
45
|
+
// routing around it would defeat the reason it was passed in.
|
|
46
|
+
if (config.fetch) return requested === "xhr" && (0, _xhrStream.xhrAvailable)();
|
|
47
|
+
if (requested === "xhr") return (0, _xhrStream.xhrAvailable)();
|
|
48
|
+
if (requested === "fetch") return false;
|
|
49
|
+
return fetchCannotStream && (0, _xhrStream.xhrAvailable)();
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
async open(req) {
|
|
53
|
+
if (useXhr()) {
|
|
54
|
+
const response = await (0, _xhrStream.xhrStream)({
|
|
55
|
+
url: config.endpoint,
|
|
56
|
+
headers: req.headers,
|
|
57
|
+
body: req.body,
|
|
58
|
+
signal: req.signal
|
|
59
|
+
});
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
const detail = (await response.text()).slice(0, 600);
|
|
62
|
+
return {
|
|
63
|
+
problem: `HTTP ${response.status}${detail ? ` — ${detail}` : ""}`,
|
|
64
|
+
problemInfo: (0, _problem.classifyProblem)({
|
|
65
|
+
status: response.status,
|
|
66
|
+
type: (0, _problem.errorTypeOf)(detail),
|
|
67
|
+
message: detail,
|
|
68
|
+
retryAfter: response.retryAfter
|
|
69
|
+
}),
|
|
70
|
+
frames: EMPTY
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const type = response.contentType.toLowerCase();
|
|
74
|
+
if (type && !type.includes("event-stream")) {
|
|
75
|
+
const detail = (await response.text()).slice(0, 600);
|
|
76
|
+
return {
|
|
77
|
+
problem: type.includes("json") ? `The endpoint answered with JSON instead of a stream — it may not support "stream": true.${detail ? ` — ${detail}` : ""}` : `The endpoint answered with ${response.contentType} instead of an event stream.${detail ? ` — ${detail}` : ""}`,
|
|
78
|
+
frames: EMPTY
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
frames: options => response.frames(options)
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const response = await (config.fetch ?? fetch)(config.endpoint, {
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: req.headers,
|
|
88
|
+
signal: req.signal,
|
|
89
|
+
body: req.body
|
|
90
|
+
});
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
const detail = await (0, _sse.errorBody)(response);
|
|
93
|
+
return {
|
|
94
|
+
problem: `HTTP ${response.status}${detail ? ` — ${detail}` : ""}`,
|
|
95
|
+
problemInfo: (0, _problem.classifyProblem)({
|
|
96
|
+
status: response.status,
|
|
97
|
+
type: (0, _problem.errorTypeOf)(detail),
|
|
98
|
+
message: detail,
|
|
99
|
+
retryAfter: response.headers?.get?.("retry-after") ?? null
|
|
100
|
+
}),
|
|
101
|
+
frames: EMPTY
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const problem = await (0, _sse.nonStreamProblem)(response);
|
|
105
|
+
if (problem) return {
|
|
106
|
+
problem,
|
|
107
|
+
frames: EMPTY
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// Learn, for the NEXT request. This one is already in flight and is read
|
|
111
|
+
// through the buffered path — re-sending it is what this file exists to
|
|
112
|
+
// avoid.
|
|
113
|
+
const body = response.body;
|
|
114
|
+
if ((!body || typeof body.getReader !== "function") && !config.fetch) {
|
|
115
|
+
fetchCannotStream = true;
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
frames: options => (0, _sse.readSse)(response, options)
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_sse","require","_xhrStream","_problem","EMPTY","createTransport","config","requested","transport","fetchCannotStream","useXhr","fetch","xhrAvailable","open","req","response","xhrStream","url","endpoint","headers","body","signal","ok","detail","text","slice","problem","status","problemInfo","classifyProblem","type","errorTypeOf","message","retryAfter","frames","contentType","toLowerCase","includes","options","method","errorBody","get","nonStreamProblem","getReader","readSse"],"sourceRoot":"../../../src","sources":["providers/transport.ts"],"mappings":"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","ignoreList":[]}
|