lynkr 8.0.0 → 9.0.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/.lynkr/telemetry.db +0 -0
- package/.lynkr/telemetry.db-shm +0 -0
- package/.lynkr/telemetry.db-wal +0 -0
- package/README.md +196 -322
- package/lynkr-skill.tar.gz +0 -0
- package/package.json +4 -3
- package/src/api/openai-router.js +64 -13
- package/src/api/providers-handler.js +171 -3
- package/src/api/router.js +9 -2
- package/src/clients/circuit-breaker.js +10 -247
- package/src/clients/codex-process.js +342 -0
- package/src/clients/codex-utils.js +143 -0
- package/src/clients/databricks.js +210 -63
- package/src/clients/resilience.js +540 -0
- package/src/clients/retry.js +22 -167
- package/src/clients/standard-tools.js +23 -0
- package/src/config/index.js +77 -0
- package/src/context/compression.js +42 -9
- package/src/context/distill.js +492 -0
- package/src/orchestrator/index.js +48 -8
- package/src/routing/complexity-analyzer.js +258 -5
- package/src/routing/index.js +12 -2
- package/src/routing/latency-tracker.js +148 -0
- package/src/routing/model-tiers.js +2 -0
- package/src/routing/quality-scorer.js +113 -0
- package/src/routing/telemetry.js +464 -0
- package/src/server.js +13 -12
- package/src/tools/code-graph.js +538 -0
- package/src/tools/code-mode.js +304 -0
- package/src/tools/index.js +4 -0
- package/src/tools/lazy-loader.js +18 -0
- package/src/tools/mcp-remote.js +7 -0
- package/src/tools/smart-selection.js +11 -0
- package/src/tools/tinyfish.js +358 -0
- package/src/tools/truncate.js +1 -0
- package/src/utils/payload.js +206 -0
- package/src/utils/perf-timer.js +80 -0
- package/.github/FUNDING.yml +0 -15
- package/.github/workflows/README.md +0 -215
- package/.github/workflows/ci.yml +0 -69
- package/.github/workflows/index.yml +0 -62
- package/.github/workflows/web-tools-tests.yml +0 -56
- package/CITATIONS.bib +0 -6
- package/DEPLOYMENT.md +0 -1001
- package/LYNKR-TUI-PLAN.md +0 -984
- package/PERFORMANCE-REPORT.md +0 -866
- package/PLAN-per-client-model-routing.md +0 -252
- package/docs/42642f749da6234f41b6b425c3bb07c9.txt +0 -1
- package/docs/BingSiteAuth.xml +0 -4
- package/docs/docs-style.css +0 -478
- package/docs/docs.html +0 -198
- package/docs/google5be250e608e6da39.html +0 -1
- package/docs/index.html +0 -577
- package/docs/index.md +0 -584
- package/docs/robots.txt +0 -4
- package/docs/sitemap.xml +0 -44
- package/docs/style.css +0 -1223
- package/docs/toon-integration-spec.md +0 -130
- package/documentation/README.md +0 -101
- package/documentation/api.md +0 -806
- package/documentation/claude-code-cli.md +0 -679
- package/documentation/codex-cli.md +0 -397
- package/documentation/contributing.md +0 -571
- package/documentation/cursor-integration.md +0 -734
- package/documentation/docker.md +0 -874
- package/documentation/embeddings.md +0 -762
- package/documentation/faq.md +0 -713
- package/documentation/features.md +0 -403
- package/documentation/headroom.md +0 -519
- package/documentation/installation.md +0 -758
- package/documentation/memory-system.md +0 -476
- package/documentation/production.md +0 -636
- package/documentation/providers.md +0 -1009
- package/documentation/routing.md +0 -476
- package/documentation/testing.md +0 -629
- package/documentation/token-optimization.md +0 -325
- package/documentation/tools.md +0 -697
- package/documentation/troubleshooting.md +0 -969
- package/final-test.js +0 -33
- package/headroom-sidecar/config.py +0 -93
- package/headroom-sidecar/requirements.txt +0 -14
- package/headroom-sidecar/server.py +0 -451
- package/monitor-agents.sh +0 -31
- package/scripts/audit-log-reader.js +0 -399
- package/scripts/compact-dictionary.js +0 -204
- package/scripts/test-deduplication.js +0 -448
- package/src/db/database.sqlite +0 -0
- package/te +0 -11622
- package/test/README.md +0 -212
- package/test/azure-openai-config.test.js +0 -213
- package/test/azure-openai-error-resilience.test.js +0 -238
- package/test/azure-openai-format-conversion.test.js +0 -354
- package/test/azure-openai-integration.test.js +0 -287
- package/test/azure-openai-routing.test.js +0 -175
- package/test/azure-openai-streaming.test.js +0 -171
- package/test/bedrock-integration.test.js +0 -457
- package/test/comprehensive-test-suite.js +0 -928
- package/test/config-validation.test.js +0 -207
- package/test/cursor-integration.test.js +0 -484
- package/test/format-conversion.test.js +0 -578
- package/test/hybrid-routing-integration.test.js +0 -269
- package/test/hybrid-routing-performance.test.js +0 -428
- package/test/llamacpp-integration.test.js +0 -882
- package/test/lmstudio-integration.test.js +0 -347
- package/test/memory/extractor.test.js +0 -398
- package/test/memory/retriever.test.js +0 -613
- package/test/memory/retriever.test.js.bak +0 -585
- package/test/memory/search.test.js +0 -537
- package/test/memory/search.test.js.bak +0 -389
- package/test/memory/store.test.js +0 -344
- package/test/memory/store.test.js.bak +0 -312
- package/test/memory/surprise.test.js +0 -300
- package/test/memory-performance.test.js +0 -472
- package/test/openai-integration.test.js +0 -683
- package/test/openrouter-error-resilience.test.js +0 -418
- package/test/passthrough-mode.test.js +0 -385
- package/test/performance-benchmark.js +0 -351
- package/test/performance-tests.js +0 -528
- package/test/routing.test.js +0 -225
- package/test/toon-compression.test.js +0 -131
- package/test/web-tools.test.js +0 -329
- package/test-agents-simple.js +0 -43
- package/test-cli-connection.sh +0 -33
- package/test-learning-unit.js +0 -126
- package/test-learning.js +0 -112
- package/test-parallel-agents.sh +0 -124
- package/test-parallel-direct.js +0 -155
- package/test-subagents.sh +0 -117
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
const assert = require("assert");
|
|
2
|
-
const { describe, it, beforeEach, afterEach } = require("node:test");
|
|
3
|
-
|
|
4
|
-
describe("Azure OpenAI Routing Tests", () => {
|
|
5
|
-
let routing;
|
|
6
|
-
let originalConfig;
|
|
7
|
-
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
// Clear module cache
|
|
10
|
-
delete require.cache[require.resolve("../src/config")];
|
|
11
|
-
delete require.cache[require.resolve("../src/clients/routing")];
|
|
12
|
-
delete require.cache[require.resolve("../src/routing/index.js")];
|
|
13
|
-
delete require.cache[require.resolve("../src/routing/model-tiers")];
|
|
14
|
-
delete require.cache[require.resolve("../src/routing/complexity-analyzer")];
|
|
15
|
-
delete require.cache[require.resolve("../src/routing/cost-optimizer")];
|
|
16
|
-
delete require.cache[require.resolve("../src/routing/agentic-detector")];
|
|
17
|
-
|
|
18
|
-
// Store original config
|
|
19
|
-
originalConfig = { ...process.env };
|
|
20
|
-
|
|
21
|
-
// Clean OpenRouter config from previous tests
|
|
22
|
-
delete process.env.OPENROUTER_API_KEY;
|
|
23
|
-
|
|
24
|
-
// Base config for routing tests
|
|
25
|
-
process.env.MODEL_PROVIDER = "databricks"; // Set default to avoid validation errors
|
|
26
|
-
process.env.DATABRICKS_API_KEY = "test-key";
|
|
27
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
28
|
-
|
|
29
|
-
// Explicitly set valid fallback to override any local .env pollution (e.g. lmstudio)
|
|
30
|
-
process.env.FALLBACK_PROVIDER = "databricks";
|
|
31
|
-
|
|
32
|
-
// Ensure no TIER_* vars leak between tests
|
|
33
|
-
process.env.TIER_SIMPLE = "";
|
|
34
|
-
process.env.TIER_MEDIUM = "";
|
|
35
|
-
process.env.TIER_COMPLEX = "";
|
|
36
|
-
process.env.TIER_REASONING = "";
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
afterEach(() => {
|
|
40
|
-
// Restore original environment
|
|
41
|
-
process.env = originalConfig;
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe("Primary Provider Routing", () => {
|
|
45
|
-
it("should route to azure-openai when set as MODEL_PROVIDER", async () => {
|
|
46
|
-
process.env.MODEL_PROVIDER = "azure-openai";
|
|
47
|
-
process.env.AZURE_OPENAI_ENDPOINT = "https://test.openai.azure.com";
|
|
48
|
-
process.env.AZURE_OPENAI_API_KEY = "test-key";
|
|
49
|
-
|
|
50
|
-
routing = require("../src/clients/routing");
|
|
51
|
-
|
|
52
|
-
const result = await routing.determineProviderSmart({
|
|
53
|
-
messages: [{ role: "user", content: "test" }],
|
|
54
|
-
tools: []
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
assert.strictEqual(result.provider, "azure-openai");
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
describe("Static Routing with Azure OpenAI", () => {
|
|
62
|
-
it("should return primary provider regardless of tool count (tier routing disabled)", async () => {
|
|
63
|
-
process.env.MODEL_PROVIDER = "azure-openai";
|
|
64
|
-
process.env.AZURE_OPENAI_ENDPOINT = "https://test.openai.azure.com";
|
|
65
|
-
process.env.AZURE_OPENAI_API_KEY = "test-key";
|
|
66
|
-
|
|
67
|
-
// Clear cache after env setup
|
|
68
|
-
delete require.cache[require.resolve("../src/config/index.js")];
|
|
69
|
-
delete require.cache[require.resolve("../src/clients/routing")];
|
|
70
|
-
delete require.cache[require.resolve("../src/routing/index.js")];
|
|
71
|
-
|
|
72
|
-
routing = require("../src/clients/routing");
|
|
73
|
-
|
|
74
|
-
const result = await routing.determineProviderSmart({
|
|
75
|
-
messages: [{ role: "user", content: "test" }],
|
|
76
|
-
tools: [{}, {}, {}, {}, {}]
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
assert.strictEqual(result.provider, "azure-openai");
|
|
80
|
-
assert.strictEqual(result.method, "static");
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("should return primary provider for simple requests", async () => {
|
|
84
|
-
process.env.MODEL_PROVIDER = "azure-openai";
|
|
85
|
-
process.env.AZURE_OPENAI_ENDPOINT = "https://test.openai.azure.com";
|
|
86
|
-
process.env.AZURE_OPENAI_API_KEY = "test-key";
|
|
87
|
-
|
|
88
|
-
// Clear cache after env setup
|
|
89
|
-
delete require.cache[require.resolve("../src/config/index.js")];
|
|
90
|
-
delete require.cache[require.resolve("../src/clients/routing")];
|
|
91
|
-
delete require.cache[require.resolve("../src/routing/index.js")];
|
|
92
|
-
|
|
93
|
-
routing = require("../src/clients/routing");
|
|
94
|
-
|
|
95
|
-
const result = await routing.determineProviderSmart({
|
|
96
|
-
messages: [{ role: "user", content: "test" }],
|
|
97
|
-
tools: [{}, {}]
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
assert.strictEqual(result.provider, "azure-openai");
|
|
101
|
-
assert.strictEqual(result.method, "static");
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("should return static routing from determineProviderSmart when tiers disabled", async () => {
|
|
105
|
-
process.env.MODEL_PROVIDER = "azure-openai";
|
|
106
|
-
process.env.AZURE_OPENAI_ENDPOINT = "https://test.openai.azure.com";
|
|
107
|
-
process.env.AZURE_OPENAI_API_KEY = "test-key";
|
|
108
|
-
|
|
109
|
-
// Clear cache after env setup
|
|
110
|
-
delete require.cache[require.resolve("../src/config/index.js")];
|
|
111
|
-
delete require.cache[require.resolve("../src/clients/routing")];
|
|
112
|
-
delete require.cache[require.resolve("../src/routing/index.js")];
|
|
113
|
-
|
|
114
|
-
routing = require("../src/clients/routing");
|
|
115
|
-
|
|
116
|
-
const result = await routing.determineProviderSmart({
|
|
117
|
-
messages: [{ role: "user", content: "test" }],
|
|
118
|
-
tools: [{}, {}]
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
assert.strictEqual(result.provider, "azure-openai");
|
|
122
|
-
assert.strictEqual(result.method, "static");
|
|
123
|
-
assert.strictEqual(result.reason, "tier_routing_disabled");
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
describe("Fallback Configuration", () => {
|
|
128
|
-
it("should support azure-openai as fallback provider", () => {
|
|
129
|
-
process.env.MODEL_PROVIDER = "ollama";
|
|
130
|
-
process.env.OLLAMA_ENDPOINT = "http://localhost:11434";
|
|
131
|
-
process.env.OLLAMA_MODEL = "qwen2.5-coder:latest";
|
|
132
|
-
process.env.FALLBACK_ENABLED = "true";
|
|
133
|
-
process.env.FALLBACK_PROVIDER = "azure-openai";
|
|
134
|
-
process.env.AZURE_OPENAI_ENDPOINT = "https://test.openai.azure.com";
|
|
135
|
-
process.env.AZURE_OPENAI_API_KEY = "test-key";
|
|
136
|
-
|
|
137
|
-
// Clear cache after env setup
|
|
138
|
-
delete require.cache[require.resolve("../src/config/index.js")];
|
|
139
|
-
delete require.cache[require.resolve("../src/clients/routing")];
|
|
140
|
-
delete require.cache[require.resolve("../src/routing/index.js")];
|
|
141
|
-
|
|
142
|
-
routing = require("../src/clients/routing");
|
|
143
|
-
|
|
144
|
-
const fallbackProvider = routing.getFallbackProvider();
|
|
145
|
-
|
|
146
|
-
assert.strictEqual(fallbackProvider, "azure-openai");
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it("should return true for fallback enabled", () => {
|
|
150
|
-
process.env.FALLBACK_ENABLED = "true";
|
|
151
|
-
|
|
152
|
-
// Clear cache after env setup
|
|
153
|
-
delete require.cache[require.resolve("../src/config/index.js")];
|
|
154
|
-
delete require.cache[require.resolve("../src/clients/routing")];
|
|
155
|
-
delete require.cache[require.resolve("../src/routing/index.js")];
|
|
156
|
-
|
|
157
|
-
routing = require("../src/clients/routing");
|
|
158
|
-
|
|
159
|
-
assert.strictEqual(routing.isFallbackEnabled(), true);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("should return false when fallback disabled", () => {
|
|
163
|
-
process.env.FALLBACK_ENABLED = "false";
|
|
164
|
-
|
|
165
|
-
// Clear cache after env setup
|
|
166
|
-
delete require.cache[require.resolve("../src/config/index.js")];
|
|
167
|
-
delete require.cache[require.resolve("../src/clients/routing")];
|
|
168
|
-
delete require.cache[require.resolve("../src/routing/index.js")];
|
|
169
|
-
|
|
170
|
-
routing = require("../src/clients/routing");
|
|
171
|
-
|
|
172
|
-
assert.strictEqual(routing.isFallbackEnabled(), false);
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
});
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
const assert = require("assert");
|
|
2
|
-
const { describe, it } = require("node:test");
|
|
3
|
-
|
|
4
|
-
describe("Azure OpenAI Streaming Tests", () => {
|
|
5
|
-
describe("Streaming Response Structure", () => {
|
|
6
|
-
it("should recognize Azure OpenAI SSE streaming format", () => {
|
|
7
|
-
const streamChunk = {
|
|
8
|
-
id: "chatcmpl-123",
|
|
9
|
-
object: "chat.completion.chunk",
|
|
10
|
-
created: 1677652288,
|
|
11
|
-
model: "gpt-4o",
|
|
12
|
-
choices: [
|
|
13
|
-
{
|
|
14
|
-
index: 0,
|
|
15
|
-
delta: {
|
|
16
|
-
content: "Hello"
|
|
17
|
-
},
|
|
18
|
-
finish_reason: null
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
assert.strictEqual(streamChunk.object, "chat.completion.chunk");
|
|
24
|
-
assert.ok(streamChunk.choices[0].delta);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("should handle streaming delta with tool_calls", () => {
|
|
28
|
-
const streamChunk = {
|
|
29
|
-
id: "chatcmpl-123",
|
|
30
|
-
object: "chat.completion.chunk",
|
|
31
|
-
model: "gpt-4o",
|
|
32
|
-
choices: [
|
|
33
|
-
{
|
|
34
|
-
index: 0,
|
|
35
|
-
delta: {
|
|
36
|
-
tool_calls: [
|
|
37
|
-
{
|
|
38
|
-
index: 0,
|
|
39
|
-
id: "call_abc123",
|
|
40
|
-
type: "function",
|
|
41
|
-
function: {
|
|
42
|
-
name: "Read",
|
|
43
|
-
arguments: "{\"file"
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
]
|
|
47
|
-
},
|
|
48
|
-
finish_reason: null
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
assert.ok(streamChunk.choices[0].delta.tool_calls);
|
|
54
|
-
assert.strictEqual(streamChunk.choices[0].delta.tool_calls[0].function.name, "Read");
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("should handle final streaming chunk with finish_reason", () => {
|
|
58
|
-
const finalChunk = {
|
|
59
|
-
id: "chatcmpl-123",
|
|
60
|
-
object: "chat.completion.chunk",
|
|
61
|
-
model: "gpt-4o",
|
|
62
|
-
choices: [
|
|
63
|
-
{
|
|
64
|
-
index: 0,
|
|
65
|
-
delta: {},
|
|
66
|
-
finish_reason: "stop"
|
|
67
|
-
}
|
|
68
|
-
]
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
assert.strictEqual(finalChunk.choices[0].finish_reason, "stop");
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("should handle tool_calls finish_reason in streaming", () => {
|
|
75
|
-
const toolCallFinish = {
|
|
76
|
-
id: "chatcmpl-123",
|
|
77
|
-
object: "chat.completion.chunk",
|
|
78
|
-
model: "gpt-4o",
|
|
79
|
-
choices: [
|
|
80
|
-
{
|
|
81
|
-
index: 0,
|
|
82
|
-
delta: {},
|
|
83
|
-
finish_reason: "tool_calls"
|
|
84
|
-
}
|
|
85
|
-
]
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
assert.strictEqual(toolCallFinish.choices[0].finish_reason, "tool_calls");
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe("Stream Flag in Requests", () => {
|
|
93
|
-
it("should set stream:false by default for buffered requests", () => {
|
|
94
|
-
const requestBody = {
|
|
95
|
-
messages: [{ role: "user", content: "Hello" }],
|
|
96
|
-
temperature: 0.7
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
// Default stream value
|
|
100
|
-
const stream = requestBody.stream ?? false;
|
|
101
|
-
|
|
102
|
-
assert.strictEqual(stream, false);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it("should set stream:true for streaming requests", () => {
|
|
106
|
-
const requestBody = {
|
|
107
|
-
messages: [{ role: "user", content: "Hello" }],
|
|
108
|
-
stream: true
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
assert.strictEqual(requestBody.stream, true);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
describe("SSE Format Validation", () => {
|
|
116
|
-
it("should recognize SSE event format with data prefix", () => {
|
|
117
|
-
const sseChunk = 'data: {"id":"chatcmpl-123","object":"chat.completion.chunk","choices":[{"delta":{"content":"Hi"}}]}';
|
|
118
|
-
|
|
119
|
-
assert.ok(sseChunk.startsWith("data:"));
|
|
120
|
-
|
|
121
|
-
// Extract JSON after "data: "
|
|
122
|
-
const jsonStr = sseChunk.substring(6);
|
|
123
|
-
const parsed = JSON.parse(jsonStr);
|
|
124
|
-
|
|
125
|
-
assert.strictEqual(parsed.object, "chat.completion.chunk");
|
|
126
|
-
assert.strictEqual(parsed.choices[0].delta.content, "Hi");
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it("should handle SSE done signal", () => {
|
|
130
|
-
const doneSig = "data: [DONE]";
|
|
131
|
-
|
|
132
|
-
assert.strictEqual(doneSig, "data: [DONE]");
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
describe("Chunk Accumulation", () => {
|
|
137
|
-
it("should accumulate tool arguments across multiple chunks", () => {
|
|
138
|
-
const chunks = [
|
|
139
|
-
{ delta: { tool_calls: [{ index: 0, function: { arguments: "{\"file_" } }] } },
|
|
140
|
-
{ delta: { tool_calls: [{ index: 0, function: { arguments: "path\":" } }] } },
|
|
141
|
-
{ delta: { tool_calls: [{ index: 0, function: { arguments: "\"/test.js" } }] } },
|
|
142
|
-
{ delta: { tool_calls: [{ index: 0, function: { arguments: "\"}" } }] } }
|
|
143
|
-
];
|
|
144
|
-
|
|
145
|
-
let accumulated = "";
|
|
146
|
-
for (const chunk of chunks) {
|
|
147
|
-
accumulated += chunk.delta.tool_calls[0].function.arguments;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
assert.strictEqual(accumulated, '{"file_path":"/test.js"}');
|
|
151
|
-
const parsed = JSON.parse(accumulated);
|
|
152
|
-
assert.strictEqual(parsed.file_path, "/test.js");
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it("should accumulate content across multiple chunks", () => {
|
|
156
|
-
const chunks = [
|
|
157
|
-
{ delta: { content: "Hello" } },
|
|
158
|
-
{ delta: { content: ", " } },
|
|
159
|
-
{ delta: { content: "world" } },
|
|
160
|
-
{ delta: { content: "!" } }
|
|
161
|
-
];
|
|
162
|
-
|
|
163
|
-
let accumulated = "";
|
|
164
|
-
for (const chunk of chunks) {
|
|
165
|
-
accumulated += chunk.delta.content;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
assert.strictEqual(accumulated, "Hello, world!");
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
});
|