@miguelduran14/knowflow 0.1.1
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/LICENSE +201 -0
- package/README.md +182 -0
- package/dist/advisories.d.ts +16 -0
- package/dist/advisories.js +364 -0
- package/dist/advisories.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +104 -0
- package/dist/cli.js.map +1 -0
- package/dist/copy-resolver.d.ts +22 -0
- package/dist/copy-resolver.js +74 -0
- package/dist/copy-resolver.js.map +1 -0
- package/dist/dataflow.d.ts +2 -0
- package/dist/dataflow.js +88 -0
- package/dist/dataflow.js.map +1 -0
- package/dist/dossier.d.ts +20 -0
- package/dist/dossier.js +331 -0
- package/dist/dossier.js.map +1 -0
- package/dist/explain/claude.d.ts +14 -0
- package/dist/explain/claude.js +91 -0
- package/dist/explain/claude.js.map +1 -0
- package/dist/explain/explain.d.ts +72 -0
- package/dist/explain/explain.js +126 -0
- package/dist/explain/explain.js.map +1 -0
- package/dist/explain/facts.d.ts +23 -0
- package/dist/explain/facts.js +266 -0
- package/dist/explain/facts.js.map +1 -0
- package/dist/explain/fake.d.ts +14 -0
- package/dist/explain/fake.js +27 -0
- package/dist/explain/fake.js.map +1 -0
- package/dist/explain/openai.d.ts +42 -0
- package/dist/explain/openai.js +102 -0
- package/dist/explain/openai.js.map +1 -0
- package/dist/explain/provider.d.ts +19 -0
- package/dist/explain/provider.js +2 -0
- package/dist/explain/provider.js.map +1 -0
- package/dist/explain/sse.d.ts +10 -0
- package/dist/explain/sse.js +44 -0
- package/dist/explain/sse.js.map +1 -0
- package/dist/flow-parser.d.ts +10 -0
- package/dist/flow-parser.js +503 -0
- package/dist/flow-parser.js.map +1 -0
- package/dist/glossary.d.ts +54 -0
- package/dist/glossary.js +340 -0
- package/dist/glossary.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +7 -0
- package/dist/inventory.js +453 -0
- package/dist/inventory.js.map +1 -0
- package/dist/lines.d.ts +15 -0
- package/dist/lines.js +53 -0
- package/dist/lines.js.map +1 -0
- package/dist/linker.d.ts +17 -0
- package/dist/linker.js +56 -0
- package/dist/linker.js.map +1 -0
- package/dist/mermaid.d.ts +27 -0
- package/dist/mermaid.js +133 -0
- package/dist/mermaid.js.map +1 -0
- package/dist/parser.d.ts +19 -0
- package/dist/parser.js +442 -0
- package/dist/parser.js.map +1 -0
- package/dist/pic.d.ts +29 -0
- package/dist/pic.js +197 -0
- package/dist/pic.js.map +1 -0
- package/dist/references.d.ts +24 -0
- package/dist/references.js +906 -0
- package/dist/references.js.map +1 -0
- package/dist/source-lines.d.ts +56 -0
- package/dist/source-lines.js +114 -0
- package/dist/source-lines.js.map +1 -0
- package/dist/types.d.ts +499 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/gui/dist/assets/ChainCanvas-C37KyhnE.js +1 -0
- package/gui/dist/assets/FlowCanvas-BRklWBCp.js +3 -0
- package/gui/dist/assets/RobotProfessor-BtTDTBDq.js +4220 -0
- package/gui/dist/assets/fira-code-cyrillic-400-normal-UC0NFL4U.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-400-normal-dc1q3VD7.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-500-normal-Bu7VCL72.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-500-normal-CX35h3Mg.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-600-normal-BD56RyRT.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-600-normal-CPRdbepc.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-400-normal-Buh61xzB.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-400-normal-txZ9Fk_1.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-500-normal-CYRspHgm.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-500-normal-CwtLmSFD.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-600-normal-B9wE0zmr.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-600-normal-DldcyWhZ.woff +0 -0
- package/gui/dist/assets/fira-code-greek-400-normal-B2Gh_Y8s.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-400-normal-DobhaxvF.woff +0 -0
- package/gui/dist/assets/fira-code-greek-500-normal-CVO0IRNt.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-500-normal-DEXIWiey.woff +0 -0
- package/gui/dist/assets/fira-code-greek-600-normal-D_h3X2X5.woff +0 -0
- package/gui/dist/assets/fira-code-greek-600-normal-Dxp52_By.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-ext-400-normal-DR7mBgIM.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-ext-400-normal-DSPUheWg.woff +0 -0
- package/gui/dist/assets/fira-code-greek-ext-500-normal-BO3iq16n.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-ext-500-normal-CMiNLXER.woff +0 -0
- package/gui/dist/assets/fira-code-greek-ext-600-normal-C-cQDoOk.woff +0 -0
- package/gui/dist/assets/fira-code-greek-ext-600-normal-DtBpFRLc.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-400-normal-C-QZfXAs.woff +0 -0
- package/gui/dist/assets/fira-code-latin-400-normal-DGosTW8U.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-500-normal-B6gioGu8.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-500-normal-aMLC2AMm.woff +0 -0
- package/gui/dist/assets/fira-code-latin-600-normal-BmSSHshu.woff +0 -0
- package/gui/dist/assets/fira-code-latin-600-normal-CvYZpPHg.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-ext-400-normal-DG73JjOf.woff +0 -0
- package/gui/dist/assets/fira-code-latin-ext-400-normal-KSMg0QLl.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-ext-500-normal-CaANqXjI.woff +0 -0
- package/gui/dist/assets/fira-code-latin-ext-500-normal-Crd9e_oI.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-ext-600-normal-0PFQL1eg.woff +0 -0
- package/gui/dist/assets/fira-code-latin-ext-600-normal-Cb7jxoAi.woff2 +0 -0
- package/gui/dist/assets/fira-code-symbols2-400-normal-_QEZCEwe.woff +0 -0
- package/gui/dist/assets/fira-code-symbols2-500-normal-DwsgbIjQ.woff +0 -0
- package/gui/dist/assets/fira-code-symbols2-600-normal-Dvq6IQE5.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-300-normal-BO7tmGom.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-300-normal-BtNmWoqn.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-400-normal-CKu2TFQr.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-400-normal-D9eUeF-O.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-500-normal-CXfldnQ8.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-500-normal-Daski1k2.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-600-normal-CJ5P9t7t.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-600-normal-JSBvCpTs.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-700-normal-Bl-HczEO.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-700-normal-KyW5QH4H.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-300-normal-BRn8Tsce.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-300-normal-DOtRq9zH.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-400-normal-Cycyekte.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-400-normal-Dd5dApAy.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-500-normal-Cixivk4R.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-500-normal-Dkk5LlrU.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-600-normal-BKgjRriM.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-600-normal-CE6oUZE1.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-700-normal-BfO9TR-w.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-700-normal-Gcpdxicj.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-300-normal-D3JfF3y9.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-300-normal-DSgcXl_1.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-400-normal-BFCFncbp.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-400-normal-DQ8sF22y.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-500-normal-C9KT8sAy.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-500-normal-Cy-TUuxE.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-600-normal-BlqpLOpF.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-600-normal-DfHu91YF.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-700-normal-BVfcrbV7.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-700-normal-CJu31rC4.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-300-normal-CodlqOxk.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-300-normal-DVDwbKuK.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-400-normal-ByG7UNQ2.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-400-normal-ClCfNE6D.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-500-normal-Bem4H9fH.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-500-normal-nq-cjB3m.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-600-normal-DPxZoeHL.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-600-normal-fS0evUH3.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-700-normal-C1m6bE4Q.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-700-normal-C8J5qYMq.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-300-normal-B2LrTgQS.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-300-normal-Dwkm-oZ7.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-400-normal-66xCkunx.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-400-normal-a0AnQzuD.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-500-normal-Bkfzcwmr.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-500-normal-Bvbxc8ch.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-600-normal-CXKlxLG9.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-600-normal-DtSgd811.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-700-normal-CRhwpWTq.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-700-normal-DgqLm3Fi.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-300-normal-CAROBYR0.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-300-normal-GNF4Ac3G.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-400-normal-BCUwhuGB.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-400-normal-BLG_mAEf.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-500-normal-CFRf4jcC.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-500-normal-OO1QnNpY.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-600-normal-DLMQsaV4.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-600-normal-DTQBTt1m.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-700-normal-cfTxGFzJ.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-700-normal-g2Yrd4J5.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-300-normal-BO7He0nF.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-300-normal-CeyOCBN-.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-400-normal-DUVG35gE.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-400-normal-ljDTQFsx.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-500-normal-ChEXCnJy.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-500-normal-UV7M6ot_.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-600-normal-Bxjaclsw.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-600-normal-Dh2KAvU8.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-700-normal-DFi88MGY.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-700-normal-j5oLGLJY.woff2 +0 -0
- package/gui/dist/assets/index-CwQzep9r.js +413 -0
- package/gui/dist/assets/index-DUFjnEFT.css +1 -0
- package/gui/dist/assets/theme-BnuhLJ6X.css +1 -0
- package/gui/dist/assets/theme-G7EkTZY2.js +30 -0
- package/gui/dist/index.html +13 -0
- package/package.json +62 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { readSseStream } from './sse.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convierte un fallo del gateway en un mensaje accionable. Cubre los tres
|
|
4
|
+
* modos de fallo típicos de una pasarela corporativa cuyo shape no controlas:
|
|
5
|
+
* código de error HTTP, respuesta que no es JSON (URL mal, página de login),
|
|
6
|
+
* y JSON que no sigue el formato OpenAI (falta `choices`).
|
|
7
|
+
*/
|
|
8
|
+
async function readError(response) {
|
|
9
|
+
const raw = await response.text().catch(() => '');
|
|
10
|
+
let detail = raw;
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(raw);
|
|
13
|
+
if (parsed.error?.message)
|
|
14
|
+
detail = parsed.error.message;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// No era JSON.
|
|
18
|
+
}
|
|
19
|
+
const hint = response.status === 401 || response.status === 403
|
|
20
|
+
? ' — revisa la clave/token y la cabecera de auth.'
|
|
21
|
+
: response.status === 404
|
|
22
|
+
? ' — revisa el endpoint y el nombre del modelo.'
|
|
23
|
+
: response.status === 429
|
|
24
|
+
? ' — límite de tasa o cuota agotada.'
|
|
25
|
+
: '';
|
|
26
|
+
return `El endpoint respondió ${response.status}${hint} ${detail.slice(0, 300)}`.trim();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Adaptador para cualquier API compatible con OpenAI (`/chat/completions`).
|
|
30
|
+
* Vía "lista para conectar" a una IA corporativa cuyo shape exacto aún no se
|
|
31
|
+
* conoce: casi todos los gateways (Azure OpenAI, pasarelas internas, la
|
|
32
|
+
* mayoría de endpoints tipo CODEX/AXET) hablan este formato.
|
|
33
|
+
*
|
|
34
|
+
* Mismo contrato BYOK/local-first que el adaptador Claude: la llamada va
|
|
35
|
+
* directa del navegador del usuario al `endpoint` que él configure. Que ese
|
|
36
|
+
* endpoint acepte código de clientes es su decisión (restricción de IP).
|
|
37
|
+
* Si el gateway NO fuese compatible, la interfaz `ExplanationProvider`
|
|
38
|
+
* permite un adaptador a medida sin tocar el resto del motor.
|
|
39
|
+
*/
|
|
40
|
+
export function createOpenAICompatibleProvider(options) {
|
|
41
|
+
const authName = options.auth?.name ?? 'Authorization';
|
|
42
|
+
const authPrefix = options.auth?.prefix ?? 'Bearer ';
|
|
43
|
+
const maxTokens = options.maxTokens ?? 2000;
|
|
44
|
+
const headers = () => ({
|
|
45
|
+
'content-type': 'application/json',
|
|
46
|
+
[authName]: `${authPrefix}${options.apiKey}`,
|
|
47
|
+
...options.headers,
|
|
48
|
+
});
|
|
49
|
+
const body = (system, user, stream) => JSON.stringify({
|
|
50
|
+
model: options.model,
|
|
51
|
+
max_tokens: maxTokens,
|
|
52
|
+
messages: [
|
|
53
|
+
{ role: 'system', content: system },
|
|
54
|
+
{ role: 'user', content: user },
|
|
55
|
+
],
|
|
56
|
+
...(stream ? { stream: true } : {}),
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
id: options.id ?? 'openai-compatible',
|
|
60
|
+
async complete(system, user) {
|
|
61
|
+
const response = await fetch(options.endpoint, { method: 'POST', headers: headers(), body: body(system, user, false) });
|
|
62
|
+
if (!response.ok)
|
|
63
|
+
throw new Error(await readError(response));
|
|
64
|
+
const raw = await response.text();
|
|
65
|
+
let data;
|
|
66
|
+
try {
|
|
67
|
+
data = JSON.parse(raw);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new Error('El endpoint respondió, pero no en JSON. Revisa que la URL apunte al chat de completions y no a una página de login o a otra ruta.');
|
|
71
|
+
}
|
|
72
|
+
if (!Array.isArray(data.choices)) {
|
|
73
|
+
const why = data.error?.message ? `: ${data.error.message}` : '';
|
|
74
|
+
throw new Error(`El endpoint respondió pero no en formato compatible con OpenAI (falta "choices")${why}. Confirma que es un endpoint de chat completions.`);
|
|
75
|
+
}
|
|
76
|
+
const text = data.choices[0]?.message?.content ?? '';
|
|
77
|
+
if (text === '')
|
|
78
|
+
throw new Error('El proveedor devolvió una respuesta vacía');
|
|
79
|
+
return text;
|
|
80
|
+
},
|
|
81
|
+
async stream(system, user, onChunk) {
|
|
82
|
+
const response = await fetch(options.endpoint, { method: 'POST', headers: headers(), body: body(system, user, true) });
|
|
83
|
+
if (!response.ok)
|
|
84
|
+
throw new Error(await readError(response));
|
|
85
|
+
if (!response.body)
|
|
86
|
+
throw new Error('El endpoint no devolvió un cuerpo en streaming');
|
|
87
|
+
let text = '';
|
|
88
|
+
await readSseStream(response.body, event => {
|
|
89
|
+
const e = event;
|
|
90
|
+
const chunk = e.choices?.[0]?.delta?.content;
|
|
91
|
+
if (chunk) {
|
|
92
|
+
text += chunk;
|
|
93
|
+
onChunk(chunk);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
if (text === '')
|
|
97
|
+
throw new Error('El proveedor devolvió una respuesta vacía');
|
|
98
|
+
return text;
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/explain/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interfaz agnóstica de proveedor de explicación (ADR: capa de IA
|
|
3
|
+
* pluggable, BYOK). El motor no sabe qué proveedor hay detrás; cualquier
|
|
4
|
+
* implementación que cumpla esto sirve — Claude, OpenAI/GPT, o un fake
|
|
5
|
+
* para tests.
|
|
6
|
+
*/
|
|
7
|
+
export interface ExplanationProvider {
|
|
8
|
+
/** Identificador estable del proveedor ('claude', 'fake', …) */
|
|
9
|
+
readonly id: string;
|
|
10
|
+
/** Envía system + mensaje de usuario y devuelve el texto de respuesta */
|
|
11
|
+
complete(system: string, user: string): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Variante en streaming, opcional: emite fragmentos de texto con `onChunk`
|
|
14
|
+
* a medida que llegan y resuelve con el texto completo. Un proveedor que no
|
|
15
|
+
* la implemente hace que la capa superior use `complete` (sin token a
|
|
16
|
+
* token). La salida final es idéntica a la de `complete`.
|
|
17
|
+
*/
|
|
18
|
+
stream?(system: string, user: string, onChunk: (chunk: string) => void): Promise<string>;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/explain/provider.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lectura de un stream de Server-Sent Events sobre `fetch`. Compartido por
|
|
3
|
+
* los adaptadores Claude y OpenAI-compatible: ambos entregan la respuesta en
|
|
4
|
+
* streaming como líneas `data: {json}` separadas por líneas en blanco.
|
|
5
|
+
* Funciona igual en navegador y en Node 18+ (fetch trae `body` como stream).
|
|
6
|
+
*
|
|
7
|
+
* Llama a `onEvent` con el objeto JSON de cada `data:`; ignora `data: [DONE]`
|
|
8
|
+
* y las líneas que no sean JSON (comentarios `:` de keep-alive, `event:`…).
|
|
9
|
+
*/
|
|
10
|
+
export declare function readSseStream(body: ReadableStream<Uint8Array>, onEvent: (data: unknown) => void): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lectura de un stream de Server-Sent Events sobre `fetch`. Compartido por
|
|
3
|
+
* los adaptadores Claude y OpenAI-compatible: ambos entregan la respuesta en
|
|
4
|
+
* streaming como líneas `data: {json}` separadas por líneas en blanco.
|
|
5
|
+
* Funciona igual en navegador y en Node 18+ (fetch trae `body` como stream).
|
|
6
|
+
*
|
|
7
|
+
* Llama a `onEvent` con el objeto JSON de cada `data:`; ignora `data: [DONE]`
|
|
8
|
+
* y las líneas que no sean JSON (comentarios `:` de keep-alive, `event:`…).
|
|
9
|
+
*/
|
|
10
|
+
export async function readSseStream(body, onEvent) {
|
|
11
|
+
const reader = body.getReader();
|
|
12
|
+
const decoder = new TextDecoder();
|
|
13
|
+
let buffer = '';
|
|
14
|
+
try {
|
|
15
|
+
for (;;) {
|
|
16
|
+
const { done, value } = await reader.read();
|
|
17
|
+
if (done)
|
|
18
|
+
break;
|
|
19
|
+
buffer += decoder.decode(value, { stream: true });
|
|
20
|
+
// Los eventos SSE terminan en línea en blanco; procesamos por líneas
|
|
21
|
+
// `data:` sueltas, que es como los emiten estos dos proveedores.
|
|
22
|
+
let newline;
|
|
23
|
+
while ((newline = buffer.indexOf('\n')) !== -1) {
|
|
24
|
+
const line = buffer.slice(0, newline).trim();
|
|
25
|
+
buffer = buffer.slice(newline + 1);
|
|
26
|
+
if (!line.startsWith('data:'))
|
|
27
|
+
continue;
|
|
28
|
+
const payload = line.slice(5).trim();
|
|
29
|
+
if (payload === '' || payload === '[DONE]')
|
|
30
|
+
continue;
|
|
31
|
+
try {
|
|
32
|
+
onEvent(JSON.parse(payload));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Fragmento no-JSON (keep-alive u otro): se ignora.
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
reader.releaseLock();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=sse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/explain/sse.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAgC,EAChC,OAAgC;IAEhC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;IAC/B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;IACjC,IAAI,MAAM,GAAG,EAAE,CAAA;IAEf,IAAI,CAAC;QACH,SAAS,CAAC;YACR,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;YAC3C,IAAI,IAAI;gBAAE,MAAK;YACf,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;YAEjD,qEAAqE;YACrE,iEAAiE;YACjE,IAAI,OAAe,CAAA;YACnB,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAA;gBAC5C,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;gBAClC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;oBAAE,SAAQ;gBACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;gBACpC,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,QAAQ;oBAAE,SAAQ;gBACpD,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;gBAC9B,CAAC;gBAAC,MAAM,CAAC;oBACP,oDAAoD;gBACtD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,WAAW,EAAE,CAAA;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FlowResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extrae los hechos de flujo de la PROCEDURE DIVISION: párrafos/secciones
|
|
4
|
+
* en orden de fuente y aristas PERFORM/CALL/GO TO, cada una anclada a la
|
|
5
|
+
* línea donde aparece. Todo lo no verificable se marca, no se rellena:
|
|
6
|
+
* un CALL con variable es `dynamic` (el destino real solo se conoce en
|
|
7
|
+
* ejecución), un destino que no existe en el fuente va a `missingTargets`,
|
|
8
|
+
* y un fuente sin cabecera PROCEDURE DIVISION queda como `fragment`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseFlow(source: string): FlowResult;
|