@kernl-sdk/ai 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/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +10 -0
- package/LICENSE +201 -0
- package/dist/__tests__/integration.test.d.ts +2 -0
- package/dist/__tests__/integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration.test.js +388 -0
- package/dist/convert/__tests__/message.test.d.ts +2 -0
- package/dist/convert/__tests__/message.test.d.ts.map +1 -0
- package/dist/convert/__tests__/message.test.js +300 -0
- package/dist/convert/__tests__/response.test.d.ts +2 -0
- package/dist/convert/__tests__/response.test.d.ts.map +1 -0
- package/dist/convert/__tests__/response.test.js +49 -0
- package/dist/convert/__tests__/settings.test.d.ts +2 -0
- package/dist/convert/__tests__/settings.test.d.ts.map +1 -0
- package/dist/convert/__tests__/settings.test.js +144 -0
- package/dist/convert/__tests__/stream.test.d.ts +2 -0
- package/dist/convert/__tests__/stream.test.d.ts.map +1 -0
- package/dist/convert/__tests__/stream.test.js +389 -0
- package/dist/convert/__tests__/tools.test.d.ts +2 -0
- package/dist/convert/__tests__/tools.test.d.ts.map +1 -0
- package/dist/convert/__tests__/tools.test.js +152 -0
- package/dist/convert/message.d.ts +4 -0
- package/dist/convert/message.d.ts.map +1 -0
- package/dist/convert/message.js +122 -0
- package/dist/convert/messages.d.ts +4 -0
- package/dist/convert/messages.d.ts.map +1 -0
- package/dist/convert/messages.js +130 -0
- package/dist/convert/response.d.ts +15 -0
- package/dist/convert/response.d.ts.map +1 -0
- package/dist/convert/response.js +105 -0
- package/dist/convert/settings.d.ts +16 -0
- package/dist/convert/settings.d.ts.map +1 -0
- package/dist/convert/settings.js +36 -0
- package/dist/convert/stream.d.ts +11 -0
- package/dist/convert/stream.d.ts.map +1 -0
- package/dist/convert/stream.js +154 -0
- package/dist/convert/tools.d.ts +5 -0
- package/dist/convert/tools.d.ts.map +1 -0
- package/dist/convert/tools.js +42 -0
- package/dist/error.d.ts +8 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +15 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/language-model.d.ts +21 -0
- package/dist/language-model.d.ts.map +1 -0
- package/dist/language-model.js +60 -0
- package/dist/providers/anthropic.d.ts +14 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +17 -0
- package/dist/providers/google.d.ts +14 -0
- package/dist/providers/google.d.ts.map +1 -0
- package/dist/providers/google.js +17 -0
- package/dist/providers/openai.d.ts +14 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +17 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +79 -0
- package/src/__tests__/integration.test.ts +447 -0
- package/src/convert/__tests__/message.test.ts +336 -0
- package/src/convert/__tests__/response.test.ts +63 -0
- package/src/convert/__tests__/settings.test.ts +188 -0
- package/src/convert/__tests__/stream.test.ts +460 -0
- package/src/convert/__tests__/tools.test.ts +179 -0
- package/src/convert/message.ts +150 -0
- package/src/convert/response.ts +144 -0
- package/src/convert/settings.ts +62 -0
- package/src/convert/stream.ts +181 -0
- package/src/convert/tools.ts +59 -0
- package/src/error.ts +16 -0
- package/src/index.ts +22 -0
- package/src/language-model.ts +77 -0
- package/src/providers/anthropic.ts +18 -0
- package/src/providers/google.ts +18 -0
- package/src/providers/openai.ts +18 -0
- package/src/types.ts +0 -0
- package/tsconfig.json +13 -0
- package/vitest.config.ts +14 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
encode: (kernlItems) => {
|
|
3
|
+
const aiMessages = [];
|
|
4
|
+
for (const item of kernlItems) {
|
|
5
|
+
if (item.kind === "message") {
|
|
6
|
+
// Convert Kernl Message to AI SDK Message
|
|
7
|
+
if (item.role === "system") {
|
|
8
|
+
// System messages must have string content in AI SDK
|
|
9
|
+
const textContent = item.content
|
|
10
|
+
.filter((part) => part.kind === "text")
|
|
11
|
+
.map((part) => (part.kind === "text" ? part.text : ""))
|
|
12
|
+
.join("\n");
|
|
13
|
+
aiMessages.push({
|
|
14
|
+
role: "system",
|
|
15
|
+
content: textContent,
|
|
16
|
+
providerOptions: item.providerMetadata,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
else if (item.role === "user") {
|
|
20
|
+
// User messages have array of text/file parts
|
|
21
|
+
const content = [];
|
|
22
|
+
for (const part of item.content) {
|
|
23
|
+
if (part.kind === "text") {
|
|
24
|
+
content.push({
|
|
25
|
+
type: "text",
|
|
26
|
+
text: part.text,
|
|
27
|
+
providerOptions: part.providerMetadata,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else if (part.kind === "file") {
|
|
31
|
+
content.push({
|
|
32
|
+
type: "file",
|
|
33
|
+
filename: part.filename,
|
|
34
|
+
data: part.data,
|
|
35
|
+
mediaType: part.mimeType,
|
|
36
|
+
providerOptions: part.providerMetadata,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// TODO: Handle DataPart
|
|
40
|
+
}
|
|
41
|
+
aiMessages.push({
|
|
42
|
+
role: "user",
|
|
43
|
+
content,
|
|
44
|
+
providerOptions: item.providerMetadata,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else if (item.role === "assistant") {
|
|
48
|
+
// Assistant messages can have text, file, reasoning, tool call parts
|
|
49
|
+
const content = [];
|
|
50
|
+
for (const part of item.content) {
|
|
51
|
+
if (part.kind === "text") {
|
|
52
|
+
content.push({
|
|
53
|
+
type: "text",
|
|
54
|
+
text: part.text,
|
|
55
|
+
providerOptions: part.providerMetadata,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
else if (part.kind === "file") {
|
|
59
|
+
content.push({
|
|
60
|
+
type: "file",
|
|
61
|
+
filename: part.filename,
|
|
62
|
+
data: part.data,
|
|
63
|
+
mediaType: part.mimeType,
|
|
64
|
+
providerOptions: part.providerMetadata,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// TODO: Handle DataPart
|
|
68
|
+
}
|
|
69
|
+
aiMessages.push({
|
|
70
|
+
role: "assistant",
|
|
71
|
+
content,
|
|
72
|
+
providerOptions: item.providerMetadata,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else if (item.kind === "reasoning") {
|
|
77
|
+
// Reasoning should be part of an assistant message
|
|
78
|
+
// For now, create a standalone assistant message with reasoning
|
|
79
|
+
aiMessages.push({
|
|
80
|
+
role: "assistant",
|
|
81
|
+
content: [
|
|
82
|
+
{
|
|
83
|
+
type: "reasoning",
|
|
84
|
+
text: item.text,
|
|
85
|
+
providerOptions: item.providerMetadata,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else if (item.kind === "tool-call") {
|
|
91
|
+
// Tool calls should be part of an assistant message
|
|
92
|
+
// For now, create a standalone assistant message with tool call
|
|
93
|
+
aiMessages.push({
|
|
94
|
+
role: "assistant",
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: "tool-call",
|
|
98
|
+
toolCallId: item.callId,
|
|
99
|
+
toolName: item.toolId,
|
|
100
|
+
input: JSON.parse(item.arguments),
|
|
101
|
+
providerOptions: item.providerMetadata,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
else if (item.kind === "tool-result") {
|
|
107
|
+
// Tool results go into a separate 'tool' role message
|
|
108
|
+
aiMessages.push({
|
|
109
|
+
role: "tool",
|
|
110
|
+
content: [
|
|
111
|
+
{
|
|
112
|
+
type: "tool-result",
|
|
113
|
+
toolCallId: item.callId,
|
|
114
|
+
toolName: item.toolId,
|
|
115
|
+
output: {
|
|
116
|
+
type: "json",
|
|
117
|
+
value: item.result,
|
|
118
|
+
},
|
|
119
|
+
providerOptions: item.providerMetadata,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return aiMessages;
|
|
126
|
+
},
|
|
127
|
+
decode: () => {
|
|
128
|
+
throw new Error("codec:unimplemented");
|
|
129
|
+
},
|
|
130
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Codec, LanguageModelResponse, LanguageModelWarning } from "@kernl-sdk/protocol";
|
|
2
|
+
import type { LanguageModelV3Content, LanguageModelV3FinishReason, LanguageModelV3Usage, LanguageModelV3CallWarning } from "@ai-sdk/provider";
|
|
3
|
+
/**
|
|
4
|
+
* AI SDK generate result structure
|
|
5
|
+
*/
|
|
6
|
+
export interface AISdkGenerateResult {
|
|
7
|
+
content: Array<LanguageModelV3Content>;
|
|
8
|
+
finishReason: LanguageModelV3FinishReason;
|
|
9
|
+
usage: LanguageModelV3Usage;
|
|
10
|
+
providerMetadata?: Record<string, unknown>;
|
|
11
|
+
warnings: Array<LanguageModelV3CallWarning>;
|
|
12
|
+
}
|
|
13
|
+
export declare const MODEL_RESPONSE: Codec<LanguageModelResponse, AISdkGenerateResult>;
|
|
14
|
+
export declare const WARNING: Codec<LanguageModelWarning, LanguageModelV3CallWarning>;
|
|
15
|
+
//# sourceMappingURL=response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/convert/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,qBAAqB,EAIrB,oBAAoB,EAErB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EACV,sBAAsB,EACtB,2BAA2B,EAC3B,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,kBAAkB,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACvC,YAAY,EAAE,2BAA2B,CAAC;IAC1C,KAAK,EAAE,oBAAoB,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,EAAE,KAAK,CAAC,0BAA0B,CAAC,CAAC;CAC7C;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,qBAAqB,EAAE,mBAAmB,CAsE1E,CAAC;AAmBJ,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,oBAAoB,EAAE,0BAA0B,CA0BzE,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { randomID } from "@kernl-sdk/shared/lib";
|
|
2
|
+
export const MODEL_RESPONSE = {
|
|
3
|
+
encode: () => {
|
|
4
|
+
throw new Error("codec:unimplemented");
|
|
5
|
+
},
|
|
6
|
+
decode: (result) => {
|
|
7
|
+
const content = [];
|
|
8
|
+
for (const item of result.content) {
|
|
9
|
+
if (item.type === "text") {
|
|
10
|
+
content.push({
|
|
11
|
+
kind: "message",
|
|
12
|
+
role: "assistant",
|
|
13
|
+
id: randomID(),
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
kind: "text",
|
|
17
|
+
text: item.text,
|
|
18
|
+
providerMetadata: item.providerMetadata,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
providerMetadata: item.providerMetadata,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else if (item.type === "reasoning") {
|
|
25
|
+
content.push({
|
|
26
|
+
kind: "reasoning",
|
|
27
|
+
text: item.text,
|
|
28
|
+
providerMetadata: item.providerMetadata,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
else if (item.type === "tool-call") {
|
|
32
|
+
content.push({
|
|
33
|
+
kind: "tool-call",
|
|
34
|
+
callId: item.toolCallId,
|
|
35
|
+
toolId: item.toolName,
|
|
36
|
+
state: "completed",
|
|
37
|
+
arguments: JSON.stringify(item.input),
|
|
38
|
+
providerMetadata: item.providerMetadata,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else if (item.type === "file") {
|
|
42
|
+
content.push({
|
|
43
|
+
kind: "message",
|
|
44
|
+
role: "assistant",
|
|
45
|
+
id: randomID(),
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
kind: "file",
|
|
49
|
+
mimeType: item.mediaType,
|
|
50
|
+
data: item.data,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// TODO: Handle other content types (source, tool-result)
|
|
56
|
+
}
|
|
57
|
+
const finishReason = FINISH_REASON.decode(result.finishReason);
|
|
58
|
+
const usage = USAGE.decode(result.usage);
|
|
59
|
+
const warnings = result.warnings.map(WARNING.decode);
|
|
60
|
+
return {
|
|
61
|
+
content,
|
|
62
|
+
finishReason,
|
|
63
|
+
usage,
|
|
64
|
+
warnings,
|
|
65
|
+
providerMetadata: result.providerMetadata,
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
const FINISH_REASON = {
|
|
70
|
+
encode: () => {
|
|
71
|
+
throw new Error("codec:unimplemented");
|
|
72
|
+
},
|
|
73
|
+
decode: (reason) => reason,
|
|
74
|
+
};
|
|
75
|
+
const USAGE = {
|
|
76
|
+
encode: () => {
|
|
77
|
+
throw new Error("codec:unimplemented");
|
|
78
|
+
},
|
|
79
|
+
decode: (usage) => usage,
|
|
80
|
+
};
|
|
81
|
+
export const WARNING = {
|
|
82
|
+
encode: () => {
|
|
83
|
+
throw new Error("codec:unimplemented");
|
|
84
|
+
},
|
|
85
|
+
decode: (warning) => {
|
|
86
|
+
switch (warning.type) {
|
|
87
|
+
case "unsupported-setting":
|
|
88
|
+
return {
|
|
89
|
+
type: "unsupported-setting",
|
|
90
|
+
setting: warning.setting,
|
|
91
|
+
details: warning.details,
|
|
92
|
+
};
|
|
93
|
+
case "other":
|
|
94
|
+
return {
|
|
95
|
+
type: "other",
|
|
96
|
+
message: warning.message,
|
|
97
|
+
};
|
|
98
|
+
default:
|
|
99
|
+
return {
|
|
100
|
+
type: "other",
|
|
101
|
+
message: "Unknown warning type",
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Codec, LanguageModelRequestSettings } from "@kernl-sdk/protocol";
|
|
2
|
+
import type { LanguageModelV3ToolChoice, SharedV3ProviderOptions } from "@ai-sdk/provider";
|
|
3
|
+
/**
|
|
4
|
+
* Partial AI SDK call options extracted from settings.
|
|
5
|
+
*/
|
|
6
|
+
export interface AISdkCallOptions {
|
|
7
|
+
temperature?: number;
|
|
8
|
+
topP?: number;
|
|
9
|
+
maxOutputTokens?: number;
|
|
10
|
+
frequencyPenalty?: number;
|
|
11
|
+
presencePenalty?: number;
|
|
12
|
+
toolChoice?: LanguageModelV3ToolChoice;
|
|
13
|
+
providerOptions?: SharedV3ProviderOptions;
|
|
14
|
+
}
|
|
15
|
+
export declare const MODEL_SETTINGS: Codec<LanguageModelRequestSettings, AISdkCallOptions>;
|
|
16
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/convert/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,kBAAkB,CAAC;AAI1B;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,eAAe,CAAC,EAAE,uBAAuB,CAAC;CAC3C;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAChC,4BAA4B,EAC5B,gBAAgB,CAsCjB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { TOOL_CHOICE } from "./tools";
|
|
2
|
+
export const MODEL_SETTINGS = {
|
|
3
|
+
encode: (settings) => {
|
|
4
|
+
const options = {};
|
|
5
|
+
if (settings.temperature !== undefined) {
|
|
6
|
+
options.temperature = settings.temperature;
|
|
7
|
+
}
|
|
8
|
+
if (settings.topP !== undefined) {
|
|
9
|
+
options.topP = settings.topP;
|
|
10
|
+
}
|
|
11
|
+
if (settings.maxTokens !== undefined) {
|
|
12
|
+
options.maxOutputTokens = settings.maxTokens;
|
|
13
|
+
}
|
|
14
|
+
if (settings.frequencyPenalty !== undefined) {
|
|
15
|
+
options.frequencyPenalty = settings.frequencyPenalty;
|
|
16
|
+
}
|
|
17
|
+
if (settings.presencePenalty !== undefined) {
|
|
18
|
+
options.presencePenalty = settings.presencePenalty;
|
|
19
|
+
}
|
|
20
|
+
if (settings.toolChoice !== undefined) {
|
|
21
|
+
options.toolChoice = TOOL_CHOICE.encode(settings.toolChoice);
|
|
22
|
+
}
|
|
23
|
+
if (settings.providerOptions !== undefined) {
|
|
24
|
+
options.providerOptions =
|
|
25
|
+
settings.providerOptions;
|
|
26
|
+
}
|
|
27
|
+
// TODO: Handle reasoning settings (settings.reasoning)
|
|
28
|
+
// TODO: Handle text settings (settings.text)
|
|
29
|
+
// TODO: Handle parallelToolCalls (not in AI SDK v3 base interface)
|
|
30
|
+
// These may need to be mapped to provider-specific options
|
|
31
|
+
return options;
|
|
32
|
+
},
|
|
33
|
+
decode: () => {
|
|
34
|
+
throw new Error("codec:unimplemented");
|
|
35
|
+
},
|
|
36
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Codec, LanguageModelStreamEvent } from "@kernl-sdk/protocol";
|
|
2
|
+
import type { LanguageModelV3StreamPart } from "@ai-sdk/provider";
|
|
3
|
+
/**
|
|
4
|
+
* Convert AI SDK stream to async iterable of kernl stream events.
|
|
5
|
+
*/
|
|
6
|
+
export declare function convertStream(stream: ReadableStream<LanguageModelV3StreamPart>): AsyncIterable<LanguageModelStreamEvent>;
|
|
7
|
+
/**
|
|
8
|
+
* Codec for converting individual stream parts.
|
|
9
|
+
*/
|
|
10
|
+
export declare const STREAM_PART: Codec<LanguageModelStreamEvent | null, LanguageModelV3StreamPart>;
|
|
11
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/convert/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAGlE;;GAEG;AACH,wBAAuB,aAAa,CAClC,MAAM,EAAE,cAAc,CAAC,yBAAyB,CAAC,GAChD,aAAa,CAAC,wBAAwB,CAAC,CAgBzC;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAC7B,wBAAwB,GAAG,IAAI,EAC/B,yBAAyB,CAoJ1B,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { WARNING } from "./response";
|
|
2
|
+
/**
|
|
3
|
+
* Convert AI SDK stream to async iterable of kernl stream events.
|
|
4
|
+
*/
|
|
5
|
+
export async function* convertStream(stream) {
|
|
6
|
+
const reader = stream.getReader();
|
|
7
|
+
try {
|
|
8
|
+
while (true) {
|
|
9
|
+
const { done, value } = await reader.read();
|
|
10
|
+
if (done)
|
|
11
|
+
break;
|
|
12
|
+
const event = STREAM_PART.decode(value);
|
|
13
|
+
if (event) {
|
|
14
|
+
yield event;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
reader.releaseLock();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Codec for converting individual stream parts.
|
|
24
|
+
*/
|
|
25
|
+
export const STREAM_PART = {
|
|
26
|
+
encode: () => {
|
|
27
|
+
throw new Error("codec:unimplemented");
|
|
28
|
+
},
|
|
29
|
+
decode: (part) => {
|
|
30
|
+
switch (part.type) {
|
|
31
|
+
case "text-start":
|
|
32
|
+
return {
|
|
33
|
+
kind: "text-start",
|
|
34
|
+
id: part.id,
|
|
35
|
+
providerMetadata: part.providerMetadata,
|
|
36
|
+
};
|
|
37
|
+
case "text-delta":
|
|
38
|
+
return {
|
|
39
|
+
kind: "text-delta",
|
|
40
|
+
id: part.id,
|
|
41
|
+
text: part.delta,
|
|
42
|
+
providerMetadata: part.providerMetadata,
|
|
43
|
+
};
|
|
44
|
+
case "text-end":
|
|
45
|
+
return {
|
|
46
|
+
kind: "text-end",
|
|
47
|
+
id: part.id,
|
|
48
|
+
providerMetadata: part.providerMetadata,
|
|
49
|
+
};
|
|
50
|
+
case "reasoning-start":
|
|
51
|
+
return {
|
|
52
|
+
kind: "reasoning-start",
|
|
53
|
+
id: part.id,
|
|
54
|
+
providerMetadata: part.providerMetadata,
|
|
55
|
+
};
|
|
56
|
+
case "reasoning-delta":
|
|
57
|
+
return {
|
|
58
|
+
kind: "reasoning-delta",
|
|
59
|
+
id: part.id,
|
|
60
|
+
text: part.delta,
|
|
61
|
+
providerMetadata: part.providerMetadata,
|
|
62
|
+
};
|
|
63
|
+
case "reasoning-end":
|
|
64
|
+
return {
|
|
65
|
+
kind: "reasoning-end",
|
|
66
|
+
id: part.id,
|
|
67
|
+
providerMetadata: part.providerMetadata,
|
|
68
|
+
};
|
|
69
|
+
case "tool-input-start":
|
|
70
|
+
return {
|
|
71
|
+
kind: "tool-input-start",
|
|
72
|
+
id: part.id,
|
|
73
|
+
toolName: part.toolName,
|
|
74
|
+
title: part.title,
|
|
75
|
+
providerMetadata: part.providerMetadata,
|
|
76
|
+
};
|
|
77
|
+
case "tool-input-delta":
|
|
78
|
+
return {
|
|
79
|
+
kind: "tool-input-delta",
|
|
80
|
+
id: part.id,
|
|
81
|
+
delta: part.delta,
|
|
82
|
+
providerMetadata: part.providerMetadata,
|
|
83
|
+
};
|
|
84
|
+
case "tool-input-end":
|
|
85
|
+
return {
|
|
86
|
+
kind: "tool-input-end",
|
|
87
|
+
id: part.id,
|
|
88
|
+
providerMetadata: part.providerMetadata,
|
|
89
|
+
};
|
|
90
|
+
case "tool-call":
|
|
91
|
+
return {
|
|
92
|
+
kind: "tool-call",
|
|
93
|
+
id: part.toolCallId,
|
|
94
|
+
toolName: part.toolName,
|
|
95
|
+
arguments: part.input,
|
|
96
|
+
providerMetadata: part.providerMetadata,
|
|
97
|
+
};
|
|
98
|
+
case "tool-result":
|
|
99
|
+
// Provider-defined tools can stream tool results
|
|
100
|
+
return {
|
|
101
|
+
kind: "tool-result",
|
|
102
|
+
callId: part.toolCallId,
|
|
103
|
+
toolId: part.toolName,
|
|
104
|
+
state: part.isError ? "failed" : "completed",
|
|
105
|
+
result: part.result,
|
|
106
|
+
error: part.isError ? String(part.result) : null,
|
|
107
|
+
providerMetadata: part.providerMetadata,
|
|
108
|
+
};
|
|
109
|
+
case "file":
|
|
110
|
+
case "source":
|
|
111
|
+
// These don't have direct Kernl equivalents in streaming
|
|
112
|
+
// Could be handled as raw events
|
|
113
|
+
return {
|
|
114
|
+
kind: "raw",
|
|
115
|
+
rawValue: part,
|
|
116
|
+
};
|
|
117
|
+
case "stream-start":
|
|
118
|
+
return {
|
|
119
|
+
kind: "stream-start",
|
|
120
|
+
warnings: part.warnings.map(WARNING.decode),
|
|
121
|
+
};
|
|
122
|
+
case "finish":
|
|
123
|
+
return {
|
|
124
|
+
kind: "finish",
|
|
125
|
+
finishReason: part.finishReason, // Types should match
|
|
126
|
+
usage: {
|
|
127
|
+
inputTokens: part.usage.inputTokens,
|
|
128
|
+
outputTokens: part.usage.outputTokens,
|
|
129
|
+
totalTokens: part.usage.totalTokens,
|
|
130
|
+
reasoningTokens: part.usage.reasoningTokens,
|
|
131
|
+
cachedInputTokens: part.usage.cachedInputTokens,
|
|
132
|
+
},
|
|
133
|
+
providerMetadata: part.providerMetadata,
|
|
134
|
+
};
|
|
135
|
+
case "error":
|
|
136
|
+
return {
|
|
137
|
+
kind: "error",
|
|
138
|
+
error: part.error,
|
|
139
|
+
};
|
|
140
|
+
case "raw":
|
|
141
|
+
return {
|
|
142
|
+
kind: "raw",
|
|
143
|
+
rawValue: part.rawValue,
|
|
144
|
+
};
|
|
145
|
+
case "response-metadata":
|
|
146
|
+
// Kernl doesn't have a specific event for response metadata
|
|
147
|
+
// Could be passed through as raw or ignored
|
|
148
|
+
return null;
|
|
149
|
+
default:
|
|
150
|
+
// Unknown event type
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Codec, LanguageModelTool, LanguageModelToolChoice } from "@kernl-sdk/protocol";
|
|
2
|
+
import type { LanguageModelV3FunctionTool, LanguageModelV3ProviderDefinedTool, LanguageModelV3ToolChoice } from "@ai-sdk/provider";
|
|
3
|
+
export declare const TOOL: Codec<LanguageModelTool, LanguageModelV3FunctionTool | LanguageModelV3ProviderDefinedTool>;
|
|
4
|
+
export declare const TOOL_CHOICE: Codec<LanguageModelToolChoice, LanguageModelV3ToolChoice>;
|
|
5
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/convert/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,iBAAiB,EACjB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,2BAA2B,EAC3B,kCAAkC,EAClC,yBAAyB,EAC1B,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,IAAI,EAAE,KAAK,CACtB,iBAAiB,EACjB,2BAA2B,GAAG,kCAAkC,CAwBjE,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAAK,CAC7B,uBAAuB,EACvB,yBAAyB,CAiB1B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const TOOL = {
|
|
2
|
+
encode: (tool) => {
|
|
3
|
+
if (tool.kind === "function") {
|
|
4
|
+
return {
|
|
5
|
+
type: "function",
|
|
6
|
+
name: tool.name,
|
|
7
|
+
description: tool.description,
|
|
8
|
+
inputSchema: tool.parameters,
|
|
9
|
+
providerOptions: tool.providerOptions,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
// provider-defined
|
|
14
|
+
return {
|
|
15
|
+
type: "provider-defined",
|
|
16
|
+
id: tool.id,
|
|
17
|
+
name: tool.name,
|
|
18
|
+
args: tool.args,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
decode: () => {
|
|
23
|
+
throw new Error("codec:unimplemented");
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export const TOOL_CHOICE = {
|
|
27
|
+
encode: (choice) => {
|
|
28
|
+
switch (choice.kind) {
|
|
29
|
+
case "auto":
|
|
30
|
+
return { type: "auto" };
|
|
31
|
+
case "none":
|
|
32
|
+
return { type: "none" };
|
|
33
|
+
case "required":
|
|
34
|
+
return { type: "required" };
|
|
35
|
+
case "tool":
|
|
36
|
+
return { type: "tool", toolName: choice.toolId };
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
decode: () => {
|
|
40
|
+
throw new Error("codec:unimplemented");
|
|
41
|
+
},
|
|
42
|
+
};
|
package/dist/error.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrap AI SDK errors with additional context.
|
|
3
|
+
*
|
|
4
|
+
* @param error - The error from AI SDK
|
|
5
|
+
* @param context - Additional context about where the error occurred
|
|
6
|
+
*/
|
|
7
|
+
export declare function wrapError(error: unknown, context: string): Error;
|
|
8
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAShE"}
|
package/dist/error.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrap AI SDK errors with additional context.
|
|
3
|
+
*
|
|
4
|
+
* @param error - The error from AI SDK
|
|
5
|
+
* @param context - Additional context about where the error occurred
|
|
6
|
+
*/
|
|
7
|
+
export function wrapError(error, context) {
|
|
8
|
+
if (error instanceof Error) {
|
|
9
|
+
const wrapped = new Error(`AI SDK error in ${context}: ${error.message}`);
|
|
10
|
+
wrapped.stack = error.stack;
|
|
11
|
+
wrapped.cause = error;
|
|
12
|
+
return wrapped;
|
|
13
|
+
}
|
|
14
|
+
return new Error(`AI SDK error in ${context}: ${String(error)}`);
|
|
15
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @kernl-sdk/ai - AI SDK adapter for Kernl
|
|
3
|
+
*
|
|
4
|
+
* Universal provider support via Vercel AI SDK v5.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { anthropic } from '@kernl-sdk/ai/anthropic';
|
|
9
|
+
*
|
|
10
|
+
* const claude = anthropic('claude-3-5-sonnet-20241022');
|
|
11
|
+
* const response = await claude.generate([...], {});
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export { AISDKLanguageModel } from "./language-model";
|
|
15
|
+
export { MESSAGE } from "./convert/message";
|
|
16
|
+
export { TOOL, TOOL_CHOICE } from "./convert/tools";
|
|
17
|
+
export { MODEL_SETTINGS } from "./convert/settings";
|
|
18
|
+
export { MODEL_RESPONSE, WARNING } from "./convert/response";
|
|
19
|
+
export { convertStream } from "./convert/stream";
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @kernl-sdk/ai - AI SDK adapter for Kernl
|
|
3
|
+
*
|
|
4
|
+
* Universal provider support via Vercel AI SDK v5.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { anthropic } from '@kernl-sdk/ai/anthropic';
|
|
9
|
+
*
|
|
10
|
+
* const claude = anthropic('claude-3-5-sonnet-20241022');
|
|
11
|
+
* const response = await claude.generate([...], {});
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export { AISDKLanguageModel } from "./language-model";
|
|
15
|
+
// Re-export codecs for custom provider implementations
|
|
16
|
+
export { MESSAGE } from "./convert/message";
|
|
17
|
+
export { TOOL, TOOL_CHOICE } from "./convert/tools";
|
|
18
|
+
export { MODEL_SETTINGS } from "./convert/settings";
|
|
19
|
+
export { MODEL_RESPONSE, WARNING } from "./convert/response";
|
|
20
|
+
export { convertStream } from "./convert/stream";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LanguageModelV3 } from "@ai-sdk/provider";
|
|
2
|
+
import type { LanguageModel, LanguageModelRequest, LanguageModelResponse, LanguageModelStreamEvent } from "@kernl-sdk/protocol";
|
|
3
|
+
/**
|
|
4
|
+
* LanguageModel adapter for the AI SDK LanguageModelV3.
|
|
5
|
+
*/
|
|
6
|
+
export declare class AISDKLanguageModel implements LanguageModel {
|
|
7
|
+
private model;
|
|
8
|
+
readonly spec: "1.0";
|
|
9
|
+
readonly provider: string;
|
|
10
|
+
readonly modelId: string;
|
|
11
|
+
constructor(model: LanguageModelV3);
|
|
12
|
+
/**
|
|
13
|
+
* Get a response from the model.
|
|
14
|
+
*/
|
|
15
|
+
generate(request: LanguageModelRequest): Promise<LanguageModelResponse>;
|
|
16
|
+
/**
|
|
17
|
+
* Get a streamed response from the model.
|
|
18
|
+
*/
|
|
19
|
+
stream(request: LanguageModelRequest): AsyncIterable<LanguageModelStreamEvent>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=language-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language-model.d.ts","sourceRoot":"","sources":["../src/language-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAS7B;;GAEG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IAK1C,OAAO,CAAC,KAAK;IAJzB,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEL,KAAK,EAAE,eAAe;IAK1C;;OAEG;IACG,QAAQ,CACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAmBjC;;OAEG;IACI,MAAM,CACX,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CAAC,wBAAwB,CAAC;CAkB3C"}
|