@seanhogg/builderforce-memory 2026.9.30 → 2026.9.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bridges/FetchBridge.d.ts +12 -5
- package/dist/bridges/FetchBridge.d.ts.map +1 -1
- package/dist/bridges/FetchBridge.js +6 -4
- package/dist/bridges/FetchBridge.js.map +1 -1
- package/dist/bridges/OpenAIBridge.d.ts +17 -4
- package/dist/bridges/OpenAIBridge.d.ts.map +1 -1
- package/dist/bridges/OpenAIBridge.js +68 -57
- package/dist/bridges/OpenAIBridge.js.map +1 -1
- package/dist/bridges/TransformerBridge.d.ts +6 -0
- package/dist/bridges/TransformerBridge.d.ts.map +1 -1
- package/dist/evermind/index.d.ts +6 -0
- package/dist/evermind/index.d.ts.map +1 -1
- package/dist/evermind/index.js +5 -0
- package/dist/evermind/index.js.map +1 -1
- package/dist/evermind/runtime.d.ts +158 -0
- package/dist/evermind/runtime.d.ts.map +1 -0
- package/dist/evermind/runtime.js +236 -0
- package/dist/evermind/runtime.js.map +1 -0
- package/dist/evermind/textCoherence.d.ts +55 -0
- package/dist/evermind/textCoherence.d.ts.map +1 -0
- package/dist/evermind/textCoherence.js +218 -0
- package/dist/evermind/textCoherence.js.map +1 -0
- package/dist/evermind/toolCall.d.ts +175 -0
- package/dist/evermind/toolCall.d.ts.map +1 -0
- package/dist/evermind/toolCall.js +398 -0
- package/dist/evermind/toolCall.js.map +1 -0
- package/dist/evermind/wordLexicon.d.ts +103 -0
- package/dist/evermind/wordLexicon.d.ts.map +1 -0
- package/dist/evermind/wordLexicon.js +361 -0
- package/dist/evermind/wordLexicon.js.map +1 -0
- package/dist/wire/chatClient.d.ts +100 -0
- package/dist/wire/chatClient.d.ts.map +1 -0
- package/dist/wire/chatClient.js +123 -0
- package/dist/wire/chatClient.js.map +1 -0
- package/dist/wire/index.d.ts +3 -1
- package/dist/wire/index.d.ts.map +1 -1
- package/dist/wire/index.js +2 -1
- package/dist/wire/index.js.map +1 -1
- package/dist/wire/sse.d.ts +17 -9
- package/dist/wire/sse.d.ts.map +1 -1
- package/dist/wire/sse.js +45 -22
- package/dist/wire/sse.js.map +1 -1
- package/package.json +3 -3
- package/src/bridges/FetchBridge.ts +15 -6
- package/src/bridges/OpenAIBridge.ts +82 -72
- package/src/bridges/TransformerBridge.ts +6 -0
- package/src/evermind/index.ts +48 -0
- package/src/evermind/runtime.ts +364 -0
- package/src/evermind/textCoherence.ts +248 -0
- package/src/evermind/toolCall.ts +523 -0
- package/src/evermind/wordLexicon.ts +395 -0
- package/src/wire/chatClient.ts +196 -0
- package/src/wire/index.ts +3 -1
- package/src/wire/sse.ts +43 -21
package/src/wire/sse.ts
CHANGED
|
@@ -2,24 +2,38 @@
|
|
|
2
2
|
* Server-Sent-Events `data:` framing.
|
|
3
3
|
*
|
|
4
4
|
* Every consumer of an SSE LLM stream does the same line-level dance: trim the line,
|
|
5
|
-
* keep only `data:` frames,
|
|
6
|
-
* anything
|
|
7
|
-
*
|
|
5
|
+
* keep only `data:` frames, and stop at the `[DONE]` sentinel, which ends an
|
|
6
|
+
* OpenAI-style stream (anything after it is not part of the response). JSON streams
|
|
7
|
+
* then parse each payload and skip empty or malformed ones.
|
|
8
8
|
*
|
|
9
9
|
* The line rule is `slice(5).trim()`, which accepts both `data: {…}` and the
|
|
10
10
|
* spaceless `data:{…}` some providers emit — `slice(6)` silently drops the latter.
|
|
11
11
|
*
|
|
12
|
+
* Two levels, one rule: {@link readSseDataPayloads} yields payload TEXT (for callers
|
|
13
|
+
* whose frames are not all JSON, or that parse per wire shape), and
|
|
14
|
+
* {@link readSseDataFrames} yields parsed JSON on top of it.
|
|
15
|
+
*
|
|
12
16
|
* Pure and defensive: a malformed frame is skipped, never thrown.
|
|
13
17
|
*/
|
|
14
18
|
|
|
19
|
+
/** The payload text of a `data:` line, or `undefined` for any other line. */
|
|
20
|
+
export function sseDataPayload(line: string): string | undefined {
|
|
21
|
+
const trimmed = line.trim();
|
|
22
|
+
if (!trimmed.startsWith('data:')) return undefined;
|
|
23
|
+
return trimmed.slice(5).trim();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** True for the `data: [DONE]` line that ends an OpenAI-style stream. */
|
|
27
|
+
export function isSseDoneLine(line: string): boolean {
|
|
28
|
+
return sseDataPayload(line) === '[DONE]';
|
|
29
|
+
}
|
|
30
|
+
|
|
15
31
|
/**
|
|
16
32
|
* One SSE line's decoded JSON payload, or `undefined` when the line is not a usable
|
|
17
33
|
* data frame (not a `data:` line, the `[DONE]` sentinel, empty, or malformed JSON).
|
|
18
34
|
*/
|
|
19
35
|
export function parseSseDataLine(line: string): unknown | undefined {
|
|
20
|
-
const
|
|
21
|
-
if (!trimmed.startsWith('data:')) return undefined;
|
|
22
|
-
const data = trimmed.slice(5).trim();
|
|
36
|
+
const data = sseDataPayload(line);
|
|
23
37
|
if (!data || data === '[DONE]') return undefined;
|
|
24
38
|
try {
|
|
25
39
|
return JSON.parse(data);
|
|
@@ -28,12 +42,6 @@ export function parseSseDataLine(line: string): unknown | undefined {
|
|
|
28
42
|
}
|
|
29
43
|
}
|
|
30
44
|
|
|
31
|
-
/** True for the `data: [DONE]` line that ends an OpenAI-style stream. */
|
|
32
|
-
export function isSseDoneLine(line: string): boolean {
|
|
33
|
-
const trimmed = line.trim();
|
|
34
|
-
return trimmed.startsWith('data:') && trimmed.slice(5).trim() === '[DONE]';
|
|
35
|
-
}
|
|
36
|
-
|
|
37
45
|
/** Every parsed `data:` frame of a whole, already-buffered SSE body, up to `[DONE]`. */
|
|
38
46
|
export function* parseSseDataFrames(raw: string): Generator<unknown> {
|
|
39
47
|
for (const line of raw.split('\n')) {
|
|
@@ -44,11 +52,12 @@ export function* parseSseDataFrames(raw: string): Generator<unknown> {
|
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
/**
|
|
47
|
-
* Every
|
|
48
|
-
* A
|
|
49
|
-
* released however iteration ends.
|
|
55
|
+
* Every `data:` payload of a live SSE byte stream, as text, as it arrives, up to
|
|
56
|
+
* `[DONE]`. A line split across chunks is held until its newline arrives; the reader
|
|
57
|
+
* lock is released however iteration ends. A missing body yields nothing.
|
|
50
58
|
*/
|
|
51
|
-
export async function*
|
|
59
|
+
export async function* readSseDataPayloads(body: ReadableStream<Uint8Array> | null | undefined): AsyncGenerator<string> {
|
|
60
|
+
if (!body) return;
|
|
52
61
|
const reader = body.getReader();
|
|
53
62
|
const decoder = new TextDecoder();
|
|
54
63
|
let buffer = '';
|
|
@@ -60,15 +69,28 @@ export async function* readSseDataFrames(body: ReadableStream<Uint8Array>): Asyn
|
|
|
60
69
|
const lines = buffer.split('\n');
|
|
61
70
|
buffer = lines.pop() as string; // split() always yields ≥1 element
|
|
62
71
|
for (const line of lines) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (
|
|
72
|
+
const data = sseDataPayload(line);
|
|
73
|
+
if (data === undefined) continue;
|
|
74
|
+
if (data === '[DONE]') return;
|
|
75
|
+
yield data;
|
|
66
76
|
}
|
|
67
77
|
}
|
|
68
78
|
buffer += decoder.decode();
|
|
69
|
-
const tail =
|
|
70
|
-
if (tail !== undefined) yield tail;
|
|
79
|
+
const tail = sseDataPayload(buffer);
|
|
80
|
+
if (tail !== undefined && tail !== '[DONE]') yield tail;
|
|
71
81
|
} finally {
|
|
72
82
|
reader.releaseLock();
|
|
73
83
|
}
|
|
74
84
|
}
|
|
85
|
+
|
|
86
|
+
/** Every parsed JSON `data:` frame of a live SSE byte stream, up to `[DONE]`. */
|
|
87
|
+
export async function* readSseDataFrames(body: ReadableStream<Uint8Array> | null | undefined): AsyncGenerator<unknown> {
|
|
88
|
+
for await (const data of readSseDataPayloads(body)) {
|
|
89
|
+
if (!data) continue;
|
|
90
|
+
try {
|
|
91
|
+
yield JSON.parse(data);
|
|
92
|
+
} catch {
|
|
93
|
+
// Skip malformed SSE frames rather than failing the stream.
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|