@kognitivedev/vercel-ai-provider 0.1.5 → 0.1.7
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 +244 -17
- package/dist/__tests__/wrap-stream-logging.test.d.ts +1 -0
- package/dist/__tests__/wrap-stream-logging.test.js +84 -0
- package/dist/index.d.ts +50 -12
- package/dist/index.js +340 -138
- package/package.json +6 -4
- package/src/__tests__/wrap-stream-logging.test.ts +104 -0
- package/src/index.ts +441 -166
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
import { createCognitiveLayer } from "../index";
|
|
3
|
+
import { streamText } from "ai";
|
|
4
|
+
import { MockLanguageModelV3, convertArrayToReadableStream } from "ai/test";
|
|
5
|
+
|
|
6
|
+
describe("wrapStream logging", () => {
|
|
7
|
+
let fetchCalls: { url: string; body: any }[];
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
fetchCalls = [];
|
|
11
|
+
|
|
12
|
+
vi.stubGlobal(
|
|
13
|
+
"fetch",
|
|
14
|
+
vi.fn(async (url: string | URL | Request, init?: RequestInit) => {
|
|
15
|
+
const urlStr = typeof url === "string" ? url : url.toString();
|
|
16
|
+
|
|
17
|
+
if (urlStr.includes("/api/cognitive/snapshot")) {
|
|
18
|
+
return new Response(
|
|
19
|
+
JSON.stringify({ systemBlock: "", userContextBlock: "" }),
|
|
20
|
+
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (urlStr.includes("/api/cognitive/log")) {
|
|
25
|
+
const body = JSON.parse(init?.body as string);
|
|
26
|
+
fetchCalls.push({ url: urlStr, body });
|
|
27
|
+
return new Response(JSON.stringify({ ok: true }), { status: 200 });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (urlStr.includes("/api/cognitive/process")) {
|
|
31
|
+
return new Response(JSON.stringify({ ok: true }), { status: 200 });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return new Response("not found", { status: 404 });
|
|
35
|
+
})
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should include assistant message in logged conversation after streaming", async () => {
|
|
40
|
+
const mockModel = new MockLanguageModelV3({
|
|
41
|
+
doStream: async () => ({
|
|
42
|
+
stream: convertArrayToReadableStream([
|
|
43
|
+
{ type: "text-start" as const, id: "t1" },
|
|
44
|
+
{ type: "text-delta" as const, id: "t1", delta: "Hello" },
|
|
45
|
+
{ type: "text-delta" as const, id: "t1", delta: " world" },
|
|
46
|
+
{ type: "text-end" as const, id: "t1" },
|
|
47
|
+
{
|
|
48
|
+
type: "finish" as const,
|
|
49
|
+
finishReason: {
|
|
50
|
+
unified: "stop" as const,
|
|
51
|
+
raw: undefined,
|
|
52
|
+
},
|
|
53
|
+
usage: {
|
|
54
|
+
inputTokens: { total: 10, noCache: undefined, cacheRead: undefined, cacheWrite: undefined },
|
|
55
|
+
outputTokens: { total: 5, text: undefined, reasoning: undefined },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
] satisfies import("@ai-sdk/provider").LanguageModelV3StreamPart[]),
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const mockProvider = () => mockModel;
|
|
63
|
+
|
|
64
|
+
const cl = createCognitiveLayer({
|
|
65
|
+
provider: mockProvider,
|
|
66
|
+
clConfig: {
|
|
67
|
+
apiKey: "test-api-key",
|
|
68
|
+
appId: "test-app",
|
|
69
|
+
projectId: "test-project",
|
|
70
|
+
processDelayMs: 0,
|
|
71
|
+
logLevel: "none",
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const model = cl("mock-model", {
|
|
76
|
+
userId: "user-1",
|
|
77
|
+
projectId: "project-1",
|
|
78
|
+
sessionId: "session-1",
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const result = streamText({
|
|
82
|
+
model,
|
|
83
|
+
messages: [{ role: "user", content: "Hi" }],
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Fully consume the stream
|
|
87
|
+
const text = await result.text;
|
|
88
|
+
expect(text).toBe("Hello world");
|
|
89
|
+
|
|
90
|
+
// Wait for async logConversation to complete
|
|
91
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
92
|
+
|
|
93
|
+
// Find the log call
|
|
94
|
+
const logCall = fetchCalls.find((c) => c.url.includes("/api/cognitive/log"));
|
|
95
|
+
expect(logCall).toBeDefined();
|
|
96
|
+
|
|
97
|
+
const messages = logCall!.body.messages;
|
|
98
|
+
const assistantMsg = messages.find((m: any) => m.role === "assistant");
|
|
99
|
+
expect(assistantMsg).toBeDefined();
|
|
100
|
+
expect(assistantMsg.content).toEqual([
|
|
101
|
+
{ type: "text", text: "Hello world" },
|
|
102
|
+
]);
|
|
103
|
+
});
|
|
104
|
+
});
|