@osdk/aip-core 0.2.0
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/CHANGELOG.md +20 -0
- package/README.md +211 -0
- package/ai-sdk.d.ts +17 -0
- package/build/browser/ai-sdk/convert-prompt.js +136 -0
- package/build/browser/ai-sdk/convert-prompt.js.map +1 -0
- package/build/browser/ai-sdk/foundry-chat-language-model.js +386 -0
- package/build/browser/ai-sdk/foundry-chat-language-model.js.map +1 -0
- package/build/browser/ai-sdk/map-finish-reason.js +42 -0
- package/build/browser/ai-sdk/map-finish-reason.js.map +1 -0
- package/build/browser/ai-sdk/provider.js +62 -0
- package/build/browser/ai-sdk/provider.js.map +1 -0
- package/build/browser/ai-sdk/types.js +2 -0
- package/build/browser/ai-sdk/types.js.map +1 -0
- package/build/browser/generateText.js +76 -0
- package/build/browser/generateText.js.map +1 -0
- package/build/browser/index.js +23 -0
- package/build/browser/index.js.map +1 -0
- package/build/browser/internal/__test__/mockPlatformClient.js +36 -0
- package/build/browser/internal/__test__/mockPlatformClient.js.map +1 -0
- package/build/browser/internal/ids.js +23 -0
- package/build/browser/internal/ids.js.map +1 -0
- package/build/browser/internal/openAi.js +293 -0
- package/build/browser/internal/openAi.js.map +1 -0
- package/build/browser/internal/options.js +58 -0
- package/build/browser/internal/options.js.map +1 -0
- package/build/browser/internal/runStep.js +107 -0
- package/build/browser/internal/runStep.js.map +1 -0
- package/build/browser/internal/streamStep.js +223 -0
- package/build/browser/internal/streamStep.js.map +1 -0
- package/build/browser/internal/uiMessageBridge.js +55 -0
- package/build/browser/internal/uiMessageBridge.js.map +1 -0
- package/build/browser/lmsChatTransport.js +185 -0
- package/build/browser/lmsChatTransport.js.map +1 -0
- package/build/browser/model.js +74 -0
- package/build/browser/model.js.map +1 -0
- package/build/browser/public/ai-sdk.js +18 -0
- package/build/browser/public/ai-sdk.js.map +1 -0
- package/build/browser/streamText.js +210 -0
- package/build/browser/streamText.js.map +1 -0
- package/build/browser/types.js +2 -0
- package/build/browser/types.js.map +1 -0
- package/build/browser/uiMessage.js +34 -0
- package/build/browser/uiMessage.js.map +1 -0
- package/build/cjs/index.cjs +1012 -0
- package/build/cjs/index.cjs.map +1 -0
- package/build/cjs/index.d.cts +467 -0
- package/build/cjs/model-B5uS56VB.d.cts +45 -0
- package/build/cjs/public/ai-sdk.cjs +534 -0
- package/build/cjs/public/ai-sdk.cjs.map +1 -0
- package/build/cjs/public/ai-sdk.d.cts +49 -0
- package/build/esm/ai-sdk/convert-prompt.js +136 -0
- package/build/esm/ai-sdk/convert-prompt.js.map +1 -0
- package/build/esm/ai-sdk/foundry-chat-language-model.js +386 -0
- package/build/esm/ai-sdk/foundry-chat-language-model.js.map +1 -0
- package/build/esm/ai-sdk/map-finish-reason.js +42 -0
- package/build/esm/ai-sdk/map-finish-reason.js.map +1 -0
- package/build/esm/ai-sdk/provider.js +62 -0
- package/build/esm/ai-sdk/provider.js.map +1 -0
- package/build/esm/ai-sdk/types.js +2 -0
- package/build/esm/ai-sdk/types.js.map +1 -0
- package/build/esm/generateText.js +76 -0
- package/build/esm/generateText.js.map +1 -0
- package/build/esm/index.js +23 -0
- package/build/esm/index.js.map +1 -0
- package/build/esm/internal/__test__/mockPlatformClient.js +36 -0
- package/build/esm/internal/__test__/mockPlatformClient.js.map +1 -0
- package/build/esm/internal/ids.js +23 -0
- package/build/esm/internal/ids.js.map +1 -0
- package/build/esm/internal/openAi.js +293 -0
- package/build/esm/internal/openAi.js.map +1 -0
- package/build/esm/internal/options.js +58 -0
- package/build/esm/internal/options.js.map +1 -0
- package/build/esm/internal/runStep.js +107 -0
- package/build/esm/internal/runStep.js.map +1 -0
- package/build/esm/internal/streamStep.js +223 -0
- package/build/esm/internal/streamStep.js.map +1 -0
- package/build/esm/internal/uiMessageBridge.js +55 -0
- package/build/esm/internal/uiMessageBridge.js.map +1 -0
- package/build/esm/lmsChatTransport.js +185 -0
- package/build/esm/lmsChatTransport.js.map +1 -0
- package/build/esm/model.js +74 -0
- package/build/esm/model.js.map +1 -0
- package/build/esm/public/ai-sdk.js +18 -0
- package/build/esm/public/ai-sdk.js.map +1 -0
- package/build/esm/streamText.js +210 -0
- package/build/esm/streamText.js.map +1 -0
- package/build/esm/types.js +2 -0
- package/build/esm/types.js.map +1 -0
- package/build/esm/uiMessage.js +34 -0
- package/build/esm/uiMessage.js.map +1 -0
- package/build/types/ai-sdk/convert-prompt.d.ts +19 -0
- package/build/types/ai-sdk/convert-prompt.d.ts.map +1 -0
- package/build/types/ai-sdk/foundry-chat-language-model.d.ts +20 -0
- package/build/types/ai-sdk/foundry-chat-language-model.d.ts.map +1 -0
- package/build/types/ai-sdk/map-finish-reason.d.ts +2 -0
- package/build/types/ai-sdk/map-finish-reason.d.ts.map +1 -0
- package/build/types/ai-sdk/provider.d.ts +46 -0
- package/build/types/ai-sdk/provider.d.ts.map +1 -0
- package/build/types/ai-sdk/types.d.ts +1 -0
- package/build/types/ai-sdk/types.d.ts.map +1 -0
- package/build/types/generateText.d.ts +56 -0
- package/build/types/generateText.d.ts.map +1 -0
- package/build/types/index.d.ts +12 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/internal/__test__/mockPlatformClient.d.ts +13 -0
- package/build/types/internal/__test__/mockPlatformClient.d.ts.map +1 -0
- package/build/types/internal/ids.d.ts +1 -0
- package/build/types/internal/ids.d.ts.map +1 -0
- package/build/types/internal/openAi.d.ts +107 -0
- package/build/types/internal/openAi.d.ts.map +1 -0
- package/build/types/internal/options.d.ts +4 -0
- package/build/types/internal/options.d.ts.map +1 -0
- package/build/types/internal/runStep.d.ts +29 -0
- package/build/types/internal/runStep.d.ts.map +1 -0
- package/build/types/internal/streamStep.d.ts +52 -0
- package/build/types/internal/streamStep.d.ts.map +1 -0
- package/build/types/internal/uiMessageBridge.d.ts +15 -0
- package/build/types/internal/uiMessageBridge.d.ts.map +1 -0
- package/build/types/lmsChatTransport.d.ts +35 -0
- package/build/types/lmsChatTransport.d.ts.map +1 -0
- package/build/types/model.d.ts +42 -0
- package/build/types/model.d.ts.map +1 -0
- package/build/types/public/ai-sdk.d.ts +2 -0
- package/build/types/public/ai-sdk.d.ts.map +1 -0
- package/build/types/streamText.d.ts +82 -0
- package/build/types/streamText.d.ts.map +1 -0
- package/build/types/types.d.ts +189 -0
- package/build/types/types.d.ts.map +1 -0
- package/build/types/uiMessage.d.ts +85 -0
- package/build/types/uiMessage.d.ts.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { _getFoundryInternal } from "../model.js";
|
|
18
|
+
import { buildAssistantContent, buildOpenAiRequestBody, EMPTY_USAGE, getModelApiName, mapFinishReason, mapUsage, parseToolArguments, postChatCompletions } from "./openAi.js";
|
|
19
|
+
export async function streamStep(input) {
|
|
20
|
+
const apiName = getModelApiName(_getFoundryInternal(input.model).identifier);
|
|
21
|
+
const body = buildOpenAiRequestBody({
|
|
22
|
+
apiName,
|
|
23
|
+
...input
|
|
24
|
+
}, true);
|
|
25
|
+
const res = await postChatCompletions({
|
|
26
|
+
model: input.model,
|
|
27
|
+
body,
|
|
28
|
+
accept: "text/event-stream",
|
|
29
|
+
headers: input.headers,
|
|
30
|
+
abortSignal: input.abortSignal
|
|
31
|
+
});
|
|
32
|
+
if (res.body == null) {
|
|
33
|
+
throw new Error("LMS chat/completions response had no streaming body");
|
|
34
|
+
}
|
|
35
|
+
return parseSseStream({
|
|
36
|
+
body: res.body,
|
|
37
|
+
onChunk: input.onChunk,
|
|
38
|
+
warnings: input.warnings,
|
|
39
|
+
request: {
|
|
40
|
+
body
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const TEXT_PART_ID = "text-0";
|
|
45
|
+
const REASONING_PART_ID = "reasoning-0";
|
|
46
|
+
async function parseSseStream(args) {
|
|
47
|
+
const reader = args.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
48
|
+
let buffer = "";
|
|
49
|
+
let textBuf = "";
|
|
50
|
+
let reasoningStarted = false;
|
|
51
|
+
let reasoningBuf = "";
|
|
52
|
+
let finishReason = "other";
|
|
53
|
+
let rawFinishReason;
|
|
54
|
+
let usage;
|
|
55
|
+
const toolCallAcc = new Map();
|
|
56
|
+
let responseInitialized = false;
|
|
57
|
+
let responseId;
|
|
58
|
+
let responseModel;
|
|
59
|
+
let responseCreated;
|
|
60
|
+
try {
|
|
61
|
+
while (true) {
|
|
62
|
+
const {
|
|
63
|
+
value,
|
|
64
|
+
done
|
|
65
|
+
} = await reader.read();
|
|
66
|
+
if (done) {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
buffer += value.replace(/\r\n/g, "\n");
|
|
70
|
+
let frameEnd = buffer.indexOf("\n\n");
|
|
71
|
+
while (frameEnd !== -1) {
|
|
72
|
+
const frame = buffer.slice(0, frameEnd);
|
|
73
|
+
buffer = buffer.slice(frameEnd + 2);
|
|
74
|
+
for (const line of frame.split("\n")) {
|
|
75
|
+
if (!line.startsWith("data:")) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const payload = line.slice(5).trim();
|
|
79
|
+
if (payload === "") {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (payload === "[DONE]") {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
let parsed;
|
|
86
|
+
try {
|
|
87
|
+
parsed = JSON.parse(payload);
|
|
88
|
+
} catch {
|
|
89
|
+
args.warnings.push({
|
|
90
|
+
type: "other",
|
|
91
|
+
message: `Skipped malformed SSE frame: ${payload.slice(0, 80)}`
|
|
92
|
+
});
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (isErrorFrame(parsed)) {
|
|
96
|
+
throw new Error(extractErrorMessage(parsed));
|
|
97
|
+
}
|
|
98
|
+
const chunk = parsed;
|
|
99
|
+
if (!responseInitialized) {
|
|
100
|
+
responseId = chunk.id;
|
|
101
|
+
responseModel = chunk.model;
|
|
102
|
+
responseCreated = chunk.created;
|
|
103
|
+
responseInitialized = true;
|
|
104
|
+
}
|
|
105
|
+
if (chunk.usage != null) {
|
|
106
|
+
usage = mapUsage(chunk.usage);
|
|
107
|
+
}
|
|
108
|
+
for (const choice of chunk.choices ?? []) {
|
|
109
|
+
const delta = choice.delta;
|
|
110
|
+
const contentDelta = delta.content;
|
|
111
|
+
if (typeof contentDelta === "string" && contentDelta.length > 0) {
|
|
112
|
+
textBuf += contentDelta;
|
|
113
|
+
await args.onChunk({
|
|
114
|
+
type: "text-delta",
|
|
115
|
+
id: TEXT_PART_ID,
|
|
116
|
+
delta: contentDelta
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const reasoningDelta = delta.reasoning ?? delta.reasoning_content;
|
|
120
|
+
if (typeof reasoningDelta === "string" && reasoningDelta.length > 0) {
|
|
121
|
+
reasoningStarted = true;
|
|
122
|
+
reasoningBuf += reasoningDelta;
|
|
123
|
+
await args.onChunk({
|
|
124
|
+
type: "reasoning-delta",
|
|
125
|
+
id: REASONING_PART_ID,
|
|
126
|
+
delta: reasoningDelta
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (delta.tool_calls != null) {
|
|
130
|
+
for (const tc of delta.tool_calls) {
|
|
131
|
+
if (typeof tc.index !== "number") {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const acc = toolCallAcc.get(tc.index) ?? {
|
|
135
|
+
id: "",
|
|
136
|
+
name: "",
|
|
137
|
+
args: ""
|
|
138
|
+
};
|
|
139
|
+
if (tc.id != null) {
|
|
140
|
+
acc.id = tc.id;
|
|
141
|
+
}
|
|
142
|
+
if (tc.function?.name != null) {
|
|
143
|
+
acc.name = tc.function.name;
|
|
144
|
+
}
|
|
145
|
+
if (tc.function?.arguments != null) {
|
|
146
|
+
acc.args += tc.function.arguments;
|
|
147
|
+
}
|
|
148
|
+
toolCallAcc.set(tc.index, acc);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (choice.finish_reason != null) {
|
|
152
|
+
rawFinishReason = choice.finish_reason;
|
|
153
|
+
finishReason = mapFinishReason(choice.finish_reason);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
frameEnd = buffer.indexOf("\n\n");
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} finally {
|
|
161
|
+
reader.releaseLock();
|
|
162
|
+
}
|
|
163
|
+
const finalUsage = usage ?? EMPTY_USAGE;
|
|
164
|
+
|
|
165
|
+
// A connection drop or non-conformant provider that closes the stream
|
|
166
|
+
// without finish_reason should still surface tool calls to fullStream.
|
|
167
|
+
const toolCalls = Array.from(toolCallAcc.entries()).map(([index, acc]) => ({
|
|
168
|
+
type: "tool-call",
|
|
169
|
+
toolCallId: acc.id !== "" ? acc.id : `tool_call_${index}`,
|
|
170
|
+
toolName: acc.name,
|
|
171
|
+
input: parseToolArguments(acc.args, args.warnings)
|
|
172
|
+
}));
|
|
173
|
+
for (const tc of toolCalls) {
|
|
174
|
+
await args.onChunk({
|
|
175
|
+
type: "tool-call",
|
|
176
|
+
toolCallId: tc.toolCallId,
|
|
177
|
+
toolName: tc.toolName,
|
|
178
|
+
input: tc.input
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
await args.onChunk({
|
|
182
|
+
type: "finish",
|
|
183
|
+
finishReason,
|
|
184
|
+
rawFinishReason,
|
|
185
|
+
usage: finalUsage
|
|
186
|
+
});
|
|
187
|
+
const response = {
|
|
188
|
+
id: responseId,
|
|
189
|
+
modelId: responseModel,
|
|
190
|
+
timestamp: responseCreated != null ? new Date(responseCreated * 1000) : undefined,
|
|
191
|
+
messages: [{
|
|
192
|
+
role: "assistant",
|
|
193
|
+
content: buildAssistantContent(textBuf, toolCalls)
|
|
194
|
+
}]
|
|
195
|
+
};
|
|
196
|
+
return {
|
|
197
|
+
text: textBuf,
|
|
198
|
+
reasoningText: reasoningStarted ? reasoningBuf : undefined,
|
|
199
|
+
toolCalls,
|
|
200
|
+
finishReason,
|
|
201
|
+
rawFinishReason,
|
|
202
|
+
usage: finalUsage,
|
|
203
|
+
request: args.request,
|
|
204
|
+
response
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function isErrorFrame(payload) {
|
|
208
|
+
return typeof payload === "object" && payload != null && "error" in payload && payload.error != null;
|
|
209
|
+
}
|
|
210
|
+
function extractErrorMessage(payload) {
|
|
211
|
+
const err = payload.error;
|
|
212
|
+
if (typeof err === "string") {
|
|
213
|
+
return err;
|
|
214
|
+
}
|
|
215
|
+
if (typeof err === "object" && err != null) {
|
|
216
|
+
const message = err.message;
|
|
217
|
+
if (typeof message === "string") {
|
|
218
|
+
return message;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return "LMS chat/completions stream emitted an error frame";
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=streamStep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamStep.js","names":["_getFoundryInternal","buildAssistantContent","buildOpenAiRequestBody","EMPTY_USAGE","getModelApiName","mapFinishReason","mapUsage","parseToolArguments","postChatCompletions","streamStep","input","apiName","model","identifier","body","res","accept","headers","abortSignal","Error","parseSseStream","onChunk","warnings","request","TEXT_PART_ID","REASONING_PART_ID","args","reader","pipeThrough","TextDecoderStream","getReader","buffer","textBuf","reasoningStarted","reasoningBuf","finishReason","rawFinishReason","usage","toolCallAcc","Map","responseInitialized","responseId","responseModel","responseCreated","value","done","read","replace","frameEnd","indexOf","frame","slice","line","split","startsWith","payload","trim","parsed","JSON","parse","push","type","message","isErrorFrame","extractErrorMessage","chunk","id","created","choice","choices","delta","contentDelta","content","length","reasoningDelta","reasoning","reasoning_content","tool_calls","tc","index","acc","get","name","function","arguments","set","finish_reason","releaseLock","finalUsage","toolCalls","Array","from","entries","map","toolCallId","toolName","response","modelId","timestamp","Date","undefined","messages","role","text","reasoningText","error","err"],"sources":["streamStep.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _getFoundryInternal, type LanguageModel } from \"../model.js\";\nimport type {\n FinishReason,\n LanguageModelUsage,\n ModelMessage,\n RequestMetadata,\n ResponseMetadata,\n ToolCall,\n ToolChoice,\n ToolSet,\n Warning,\n} from \"../types.js\";\nimport {\n buildAssistantContent,\n buildOpenAiRequestBody,\n EMPTY_USAGE,\n getModelApiName,\n mapFinishReason,\n mapUsage,\n parseToolArguments,\n postChatCompletions,\n} from \"./openAi.js\";\n\nexport type StreamChunkEvent =\n | { type: \"text-delta\"; id: string; delta: string }\n | { type: \"reasoning-delta\"; id: string; delta: string }\n | {\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n input: unknown;\n }\n | {\n type: \"finish\";\n finishReason: FinishReason;\n rawFinishReason: string | undefined;\n usage: LanguageModelUsage;\n }\n | { type: \"error\"; error: Error };\n\nexport interface StreamStepInput<TOOLS extends ToolSet> {\n model: LanguageModel;\n messages: ReadonlyArray<ModelMessage>;\n tools: TOOLS | undefined;\n toolChoice: ToolChoice<TOOLS> | undefined;\n maxOutputTokens: number | undefined;\n temperature: number | undefined;\n topP: number | undefined;\n stopSequences: ReadonlyArray<string> | undefined;\n seed: number | undefined;\n presencePenalty: number | undefined;\n frequencyPenalty: number | undefined;\n abortSignal: AbortSignal | undefined;\n headers: Record<string, string | undefined> | undefined;\n warnings: Array<Warning>;\n onChunk: (chunk: StreamChunkEvent) => void | Promise<void>;\n}\n\nexport interface StreamStepResult {\n text: string;\n reasoningText: string | undefined;\n toolCalls: Array<ToolCall>;\n finishReason: FinishReason;\n rawFinishReason: string | undefined;\n usage: LanguageModelUsage;\n request: RequestMetadata;\n response: ResponseMetadata;\n}\n\ninterface OpenAiStreamChunk {\n id: string;\n object: \"chat.completion.chunk\";\n created: number;\n model: string;\n choices: Array<{\n index: number;\n delta: {\n role?: \"assistant\";\n content?: string | null;\n reasoning?: string;\n reasoning_content?: string;\n tool_calls?: Array<{\n index: number;\n id?: string;\n type?: \"function\";\n function?: { name?: string; arguments?: string };\n }>;\n };\n finish_reason: string | null;\n }>;\n usage?: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n completion_tokens_details?: { reasoning_tokens?: number };\n prompt_tokens_details?: { cached_tokens?: number };\n };\n}\n\ninterface ToolCallAccumulator {\n id: string;\n name: string;\n args: string;\n}\n\nexport async function streamStep<TOOLS extends ToolSet>(\n input: StreamStepInput<TOOLS>,\n): Promise<StreamStepResult> {\n const apiName = getModelApiName(_getFoundryInternal(input.model).identifier);\n const body = buildOpenAiRequestBody<TOOLS>({ apiName, ...input }, true);\n\n const res = await postChatCompletions({\n model: input.model,\n body,\n accept: \"text/event-stream\",\n headers: input.headers,\n abortSignal: input.abortSignal,\n });\n\n if (res.body == null) {\n throw new Error(\"LMS chat/completions response had no streaming body\");\n }\n\n return parseSseStream({\n body: res.body,\n onChunk: input.onChunk,\n warnings: input.warnings,\n request: { body },\n });\n}\n\ninterface ParseSseStreamArgs {\n body: ReadableStream<Uint8Array>;\n onChunk: (chunk: StreamChunkEvent) => void | Promise<void>;\n warnings: Array<Warning>;\n request: RequestMetadata;\n}\n\nconst TEXT_PART_ID = \"text-0\";\nconst REASONING_PART_ID = \"reasoning-0\";\n\nasync function parseSseStream(\n args: ParseSseStreamArgs,\n): Promise<StreamStepResult> {\n const reader = args.body\n .pipeThrough(new TextDecoderStream())\n .getReader();\n\n let buffer = \"\";\n let textBuf = \"\";\n let reasoningStarted = false;\n let reasoningBuf = \"\";\n let finishReason: FinishReason = \"other\";\n let rawFinishReason: string | undefined;\n let usage: LanguageModelUsage | undefined;\n const toolCallAcc = new Map<number, ToolCallAccumulator>();\n let responseInitialized = false;\n let responseId: string | undefined;\n let responseModel: string | undefined;\n let responseCreated: number | undefined;\n\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n break;\n }\n buffer += value.replace(/\\r\\n/g, \"\\n\");\n\n let frameEnd = buffer.indexOf(\"\\n\\n\");\n while (frameEnd !== -1) {\n const frame = buffer.slice(0, frameEnd);\n buffer = buffer.slice(frameEnd + 2);\n\n for (const line of frame.split(\"\\n\")) {\n if (!line.startsWith(\"data:\")) {\n continue;\n }\n const payload = line.slice(5).trim();\n if (payload === \"\") {\n continue;\n }\n if (payload === \"[DONE]\") {\n continue;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(payload);\n } catch {\n args.warnings.push({\n type: \"other\",\n message: `Skipped malformed SSE frame: ${payload.slice(0, 80)}`,\n });\n continue;\n }\n\n if (isErrorFrame(parsed)) {\n throw new Error(extractErrorMessage(parsed));\n }\n\n const chunk = parsed as OpenAiStreamChunk;\n\n if (!responseInitialized) {\n responseId = chunk.id;\n responseModel = chunk.model;\n responseCreated = chunk.created;\n responseInitialized = true;\n }\n\n if (chunk.usage != null) {\n usage = mapUsage(chunk.usage);\n }\n\n for (const choice of chunk.choices ?? []) {\n const delta = choice.delta;\n const contentDelta = delta.content;\n if (typeof contentDelta === \"string\" && contentDelta.length > 0) {\n textBuf += contentDelta;\n await args.onChunk({\n type: \"text-delta\",\n id: TEXT_PART_ID,\n delta: contentDelta,\n });\n }\n\n const reasoningDelta = delta.reasoning ?? delta.reasoning_content;\n if (\n typeof reasoningDelta === \"string\" && reasoningDelta.length > 0\n ) {\n reasoningStarted = true;\n reasoningBuf += reasoningDelta;\n await args.onChunk({\n type: \"reasoning-delta\",\n id: REASONING_PART_ID,\n delta: reasoningDelta,\n });\n }\n\n if (delta.tool_calls != null) {\n for (const tc of delta.tool_calls) {\n if (typeof tc.index !== \"number\") {\n continue;\n }\n const acc = toolCallAcc.get(tc.index)\n ?? { id: \"\", name: \"\", args: \"\" };\n if (tc.id != null) {\n acc.id = tc.id;\n }\n if (tc.function?.name != null) {\n acc.name = tc.function.name;\n }\n if (tc.function?.arguments != null) {\n acc.args += tc.function.arguments;\n }\n toolCallAcc.set(tc.index, acc);\n }\n }\n\n if (choice.finish_reason != null) {\n rawFinishReason = choice.finish_reason;\n finishReason = mapFinishReason(choice.finish_reason);\n }\n }\n }\n frameEnd = buffer.indexOf(\"\\n\\n\");\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n const finalUsage: LanguageModelUsage = usage ?? EMPTY_USAGE;\n\n // A connection drop or non-conformant provider that closes the stream\n // without finish_reason should still surface tool calls to fullStream.\n const toolCalls: Array<ToolCall> = Array.from(toolCallAcc.entries()).map(\n ([index, acc]) => ({\n type: \"tool-call\" as const,\n toolCallId: acc.id !== \"\" ? acc.id : `tool_call_${index}`,\n toolName: acc.name,\n input: parseToolArguments(acc.args, args.warnings),\n }),\n );\n for (const tc of toolCalls) {\n await args.onChunk({\n type: \"tool-call\",\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n });\n }\n\n await args.onChunk({\n type: \"finish\",\n finishReason,\n rawFinishReason,\n usage: finalUsage,\n });\n\n const response: ResponseMetadata = {\n id: responseId,\n modelId: responseModel,\n timestamp: responseCreated != null\n ? new Date(responseCreated * 1000)\n : undefined,\n messages: [{\n role: \"assistant\",\n content: buildAssistantContent(textBuf, toolCalls),\n }],\n };\n\n return {\n text: textBuf,\n reasoningText: reasoningStarted ? reasoningBuf : undefined,\n toolCalls,\n finishReason,\n rawFinishReason,\n usage: finalUsage,\n request: args.request,\n response,\n };\n}\n\nfunction isErrorFrame(payload: unknown): payload is { error: unknown } {\n return (\n typeof payload === \"object\"\n && payload != null\n && \"error\" in payload\n && (payload as { error: unknown }).error != null\n );\n}\n\nfunction extractErrorMessage(payload: { error: unknown }): string {\n const err = payload.error;\n if (typeof err === \"string\") {\n return err;\n }\n if (typeof err === \"object\" && err != null) {\n const message = (err as { message?: unknown }).message;\n if (typeof message === \"string\") {\n return message;\n }\n }\n return \"LMS chat/completions stream emitted an error frame\";\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { getUIMessageText } from "../uiMessage.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Convert `UIMessage[]` (the conversation shape rendered in the UI) into
|
|
21
|
+
* `ModelMessage[]` (the shape `streamText` accepts).
|
|
22
|
+
*
|
|
23
|
+
* v0: text-only. File parts, reasoning parts, source parts, and tool-related
|
|
24
|
+
* parts are dropped. Tool-result UIMessages (none in v0 either) would map to
|
|
25
|
+
* `ToolModelMessage` once tool round-trips are wired up.
|
|
26
|
+
*
|
|
27
|
+
* When `system` is provided, any system-role messages already in `ui` are
|
|
28
|
+
* dropped so the prompt isn't double-prepended — the transport-level
|
|
29
|
+
* `system` wins.
|
|
30
|
+
*/
|
|
31
|
+
export function uiMessagesToModelMessages(ui, system) {
|
|
32
|
+
const out = [];
|
|
33
|
+
const transportSystemSet = system != null && system.length > 0;
|
|
34
|
+
if (transportSystemSet) {
|
|
35
|
+
out.push({
|
|
36
|
+
role: "system",
|
|
37
|
+
content: system
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
for (const m of ui) {
|
|
41
|
+
const text = getUIMessageText(m);
|
|
42
|
+
if (text.length === 0) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (m.role === "system" && transportSystemSet) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
out.push({
|
|
49
|
+
role: m.role,
|
|
50
|
+
content: text
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=uiMessageBridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uiMessageBridge.js","names":["getUIMessageText","uiMessagesToModelMessages","ui","system","out","transportSystemSet","length","push","role","content","m","text"],"sources":["uiMessageBridge.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ModelMessage } from \"../types.js\";\nimport { getUIMessageText, type UIMessage } from \"../uiMessage.js\";\n\n/**\n * Convert `UIMessage[]` (the conversation shape rendered in the UI) into\n * `ModelMessage[]` (the shape `streamText` accepts).\n *\n * v0: text-only. File parts, reasoning parts, source parts, and tool-related\n * parts are dropped. Tool-result UIMessages (none in v0 either) would map to\n * `ToolModelMessage` once tool round-trips are wired up.\n *\n * When `system` is provided, any system-role messages already in `ui` are\n * dropped so the prompt isn't double-prepended — the transport-level\n * `system` wins.\n */\nexport function uiMessagesToModelMessages(\n ui: ReadonlyArray<UIMessage>,\n system?: string,\n): Array<ModelMessage> {\n const out: Array<ModelMessage> = [];\n const transportSystemSet = system != null && system.length > 0;\n\n if (transportSystemSet) {\n out.push({ role: \"system\", content: system });\n }\n\n for (const m of ui) {\n const text = getUIMessageText(m);\n if (text.length === 0) {\n continue;\n }\n if (m.role === \"system\" && transportSystemSet) {\n continue;\n }\n out.push({ role: m.role, content: text });\n }\n\n return out;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,SAASA,gBAAgB,QAAwB,iBAAiB;;AAElE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,yBAAyBA,CACvCC,EAA4B,EAC5BC,MAAe,EACM;EACrB,MAAMC,GAAwB,GAAG,EAAE;EACnC,MAAMC,kBAAkB,GAAGF,MAAM,IAAI,IAAI,IAAIA,MAAM,CAACG,MAAM,GAAG,CAAC;EAE9D,IAAID,kBAAkB,EAAE;IACtBD,GAAG,CAACG,IAAI,CAAC;MAAEC,IAAI,EAAE,QAAQ;MAAEC,OAAO,EAAEN;IAAO,CAAC,CAAC;EAC/C;EAEA,KAAK,MAAMO,CAAC,IAAIR,EAAE,EAAE;IAClB,MAAMS,IAAI,GAAGX,gBAAgB,CAACU,CAAC,CAAC;IAChC,IAAIC,IAAI,CAACL,MAAM,KAAK,CAAC,EAAE;MACrB;IACF;IACA,IAAII,CAAC,CAACF,IAAI,KAAK,QAAQ,IAAIH,kBAAkB,EAAE;MAC7C;IACF;IACAD,GAAG,CAACG,IAAI,CAAC;MAAEC,IAAI,EAAEE,CAAC,CAACF,IAAI;MAAEC,OAAO,EAAEE;IAAK,CAAC,CAAC;EAC3C;EAEA,OAAOP,GAAG;AACZ","ignoreList":[]}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { uiMessagesToModelMessages } from "./internal/uiMessageBridge.js";
|
|
18
|
+
import { streamText } from "./streamText.js";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Options for {@link LmsChatTransport}. Configures the streamed chat
|
|
22
|
+
* completion against the Foundry Language Model Service.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Stream chat completions through the Foundry Language Model Service via
|
|
27
|
+
* `streamText`. Implements `ChatTransport`, so any consumer that accepts a
|
|
28
|
+
* transport can plug it in (e.g. to inject custom sampling).
|
|
29
|
+
*/
|
|
30
|
+
export class LmsChatTransport {
|
|
31
|
+
constructor(opts) {
|
|
32
|
+
this.opts = opts;
|
|
33
|
+
}
|
|
34
|
+
sendMessages = async args => {
|
|
35
|
+
const result = streamText({
|
|
36
|
+
model: this.opts.model,
|
|
37
|
+
// System prompt is folded into the model-message list by the bridge so
|
|
38
|
+
// it isn't double-prepended (transport.system + system messages from
|
|
39
|
+
// args.messages would both land otherwise).
|
|
40
|
+
messages: uiMessagesToModelMessages(args.messages, this.opts.system),
|
|
41
|
+
temperature: this.opts.temperature,
|
|
42
|
+
maxOutputTokens: this.opts.maxOutputTokens,
|
|
43
|
+
topP: this.opts.topP,
|
|
44
|
+
presencePenalty: this.opts.presencePenalty,
|
|
45
|
+
frequencyPenalty: this.opts.frequencyPenalty,
|
|
46
|
+
stopSequences: this.opts.stopSequences,
|
|
47
|
+
seed: this.opts.seed,
|
|
48
|
+
headers: mergeHeaders(this.opts.headers, args.headers),
|
|
49
|
+
abortSignal: args.abortSignal
|
|
50
|
+
});
|
|
51
|
+
const assistantId = args.messageId;
|
|
52
|
+
const textPartId = `${assistantId}-text-0`;
|
|
53
|
+
const reasoningPartId = `${assistantId}-reasoning-0`;
|
|
54
|
+
let textOpen = false;
|
|
55
|
+
let reasoningOpen = false;
|
|
56
|
+
let startEmitted = false;
|
|
57
|
+
return result.fullStream.pipeThrough(new TransformStream({
|
|
58
|
+
transform(chunk, controller) {
|
|
59
|
+
if (!startEmitted) {
|
|
60
|
+
startEmitted = true;
|
|
61
|
+
controller.enqueue({
|
|
62
|
+
type: "start",
|
|
63
|
+
messageId: assistantId
|
|
64
|
+
});
|
|
65
|
+
controller.enqueue({
|
|
66
|
+
type: "start-step"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const closeText = () => {
|
|
70
|
+
if (textOpen) {
|
|
71
|
+
textOpen = false;
|
|
72
|
+
controller.enqueue({
|
|
73
|
+
type: "text-end",
|
|
74
|
+
id: textPartId
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const closeReasoning = () => {
|
|
79
|
+
if (reasoningOpen) {
|
|
80
|
+
reasoningOpen = false;
|
|
81
|
+
controller.enqueue({
|
|
82
|
+
type: "reasoning-end",
|
|
83
|
+
id: reasoningPartId
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
switch (chunk.type) {
|
|
88
|
+
case "text-delta":
|
|
89
|
+
{
|
|
90
|
+
if (!textOpen) {
|
|
91
|
+
textOpen = true;
|
|
92
|
+
controller.enqueue({
|
|
93
|
+
type: "text-start",
|
|
94
|
+
id: textPartId
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
controller.enqueue({
|
|
98
|
+
type: "text-delta",
|
|
99
|
+
id: textPartId,
|
|
100
|
+
delta: chunk.delta
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
case "reasoning-delta":
|
|
105
|
+
{
|
|
106
|
+
if (!reasoningOpen) {
|
|
107
|
+
reasoningOpen = true;
|
|
108
|
+
controller.enqueue({
|
|
109
|
+
type: "reasoning-start",
|
|
110
|
+
id: reasoningPartId
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
controller.enqueue({
|
|
114
|
+
type: "reasoning-delta",
|
|
115
|
+
id: reasoningPartId,
|
|
116
|
+
delta: chunk.delta
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
case "tool-call":
|
|
121
|
+
{
|
|
122
|
+
controller.enqueue({
|
|
123
|
+
type: "tool-input-available",
|
|
124
|
+
toolCallId: chunk.toolCallId,
|
|
125
|
+
toolName: chunk.toolName,
|
|
126
|
+
input: chunk.input
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
case "finish":
|
|
131
|
+
{
|
|
132
|
+
closeText();
|
|
133
|
+
closeReasoning();
|
|
134
|
+
controller.enqueue({
|
|
135
|
+
type: "finish-step"
|
|
136
|
+
});
|
|
137
|
+
controller.enqueue({
|
|
138
|
+
type: "finish",
|
|
139
|
+
messageMetadata: {
|
|
140
|
+
finishReason: chunk.finishReason,
|
|
141
|
+
usage: chunk.usage
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
case "error":
|
|
147
|
+
{
|
|
148
|
+
closeText();
|
|
149
|
+
closeReasoning();
|
|
150
|
+
controller.enqueue({
|
|
151
|
+
type: "error",
|
|
152
|
+
errorText: chunk.error.message
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
default:
|
|
157
|
+
{
|
|
158
|
+
controller.enqueue({
|
|
159
|
+
type: "error",
|
|
160
|
+
errorText: `Unhandled chunk type "${chunk.type}"`
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}));
|
|
166
|
+
};
|
|
167
|
+
reconnectToStream = async () => {
|
|
168
|
+
return null;
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function mergeHeaders(base, override) {
|
|
172
|
+
if (base == null && override == null) {
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
const out = {
|
|
176
|
+
...(base ?? {})
|
|
177
|
+
};
|
|
178
|
+
if (override != null) {
|
|
179
|
+
for (const [k, v] of Object.entries(override)) {
|
|
180
|
+
out[k] = v;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=lmsChatTransport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lmsChatTransport.js","names":["uiMessagesToModelMessages","streamText","LmsChatTransport","constructor","opts","sendMessages","args","result","model","messages","system","temperature","maxOutputTokens","topP","presencePenalty","frequencyPenalty","stopSequences","seed","headers","mergeHeaders","abortSignal","assistantId","messageId","textPartId","reasoningPartId","textOpen","reasoningOpen","startEmitted","fullStream","pipeThrough","TransformStream","transform","chunk","controller","enqueue","type","closeText","id","closeReasoning","delta","toolCallId","toolName","input","messageMetadata","finishReason","usage","errorText","error","message","reconnectToStream","base","override","undefined","out","k","v","Object","entries"],"sources":["lmsChatTransport.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { uiMessagesToModelMessages } from \"./internal/uiMessageBridge.js\";\nimport type { LanguageModel } from \"./model.js\";\nimport { streamText, type TextStreamChunk } from \"./streamText.js\";\nimport type {\n ChatTransport,\n ChatTransportReconnectArgs,\n ChatTransportSendMessagesArgs,\n UIMessage,\n UIMessageChunk,\n} from \"./uiMessage.js\";\n\ntype SendMessagesArgs = ChatTransportSendMessagesArgs<UIMessage>;\n\n/**\n * Options for {@link LmsChatTransport}. Configures the streamed chat\n * completion against the Foundry Language Model Service.\n */\nexport interface LmsChatTransportOptions {\n /** Foundry-LMS-backed language model. Build via `foundryModel(...)`. */\n model: LanguageModel;\n\n /** System prompt prepended to every request. */\n system?: string;\n\n /** Sampling controls. */\n temperature?: number;\n maxOutputTokens?: number;\n topP?: number;\n presencePenalty?: number;\n frequencyPenalty?: number;\n stopSequences?: Array<string>;\n seed?: number;\n\n /** Extra HTTP headers forwarded to LMS. */\n headers?: Record<string, string | undefined>;\n}\n\n/**\n * Stream chat completions through the Foundry Language Model Service via\n * `streamText`. Implements `ChatTransport`, so any consumer that accepts a\n * transport can plug it in (e.g. to inject custom sampling).\n */\nexport class LmsChatTransport implements ChatTransport<UIMessage> {\n private readonly opts: LmsChatTransportOptions;\n\n constructor(opts: LmsChatTransportOptions) {\n this.opts = opts;\n }\n\n sendMessages = async (\n args: SendMessagesArgs,\n ): Promise<ReadableStream<UIMessageChunk>> => {\n const result = streamText({\n model: this.opts.model,\n // System prompt is folded into the model-message list by the bridge so\n // it isn't double-prepended (transport.system + system messages from\n // args.messages would both land otherwise).\n messages: uiMessagesToModelMessages(args.messages, this.opts.system),\n temperature: this.opts.temperature,\n maxOutputTokens: this.opts.maxOutputTokens,\n topP: this.opts.topP,\n presencePenalty: this.opts.presencePenalty,\n frequencyPenalty: this.opts.frequencyPenalty,\n stopSequences: this.opts.stopSequences,\n seed: this.opts.seed,\n headers: mergeHeaders(this.opts.headers, args.headers),\n abortSignal: args.abortSignal,\n });\n\n const assistantId = args.messageId;\n const textPartId = `${assistantId}-text-0`;\n const reasoningPartId = `${assistantId}-reasoning-0`;\n let textOpen = false;\n let reasoningOpen = false;\n let startEmitted = false;\n\n return result.fullStream.pipeThrough(\n new TransformStream<TextStreamChunk, UIMessageChunk>({\n transform(chunk, controller) {\n if (!startEmitted) {\n startEmitted = true;\n controller.enqueue({ type: \"start\", messageId: assistantId });\n controller.enqueue({ type: \"start-step\" });\n }\n const closeText = (): void => {\n if (textOpen) {\n textOpen = false;\n controller.enqueue({ type: \"text-end\", id: textPartId });\n }\n };\n const closeReasoning = (): void => {\n if (reasoningOpen) {\n reasoningOpen = false;\n controller.enqueue({\n type: \"reasoning-end\",\n id: reasoningPartId,\n });\n }\n };\n switch (chunk.type) {\n case \"text-delta\": {\n if (!textOpen) {\n textOpen = true;\n controller.enqueue({ type: \"text-start\", id: textPartId });\n }\n controller.enqueue({\n type: \"text-delta\",\n id: textPartId,\n delta: chunk.delta,\n });\n return;\n }\n case \"reasoning-delta\": {\n if (!reasoningOpen) {\n reasoningOpen = true;\n controller.enqueue({\n type: \"reasoning-start\",\n id: reasoningPartId,\n });\n }\n controller.enqueue({\n type: \"reasoning-delta\",\n id: reasoningPartId,\n delta: chunk.delta,\n });\n return;\n }\n case \"tool-call\": {\n controller.enqueue({\n type: \"tool-input-available\",\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n input: chunk.input,\n });\n return;\n }\n case \"finish\": {\n closeText();\n closeReasoning();\n controller.enqueue({ type: \"finish-step\" });\n controller.enqueue({\n type: \"finish\",\n messageMetadata: {\n finishReason: chunk.finishReason,\n usage: chunk.usage,\n },\n });\n return;\n }\n case \"error\": {\n closeText();\n closeReasoning();\n controller.enqueue({\n type: \"error\",\n errorText: chunk.error.message,\n });\n return;\n }\n default: {\n const unhandled: { type: string } = chunk;\n controller.enqueue({\n type: \"error\",\n errorText: `Unhandled chunk type \"${unhandled.type}\"`,\n });\n }\n }\n },\n }),\n );\n };\n\n reconnectToStream = async (\n _args: ChatTransportReconnectArgs,\n ): Promise<ReadableStream<UIMessageChunk> | null> => {\n return null;\n };\n}\n\nfunction mergeHeaders(\n base: Record<string, string | undefined> | undefined,\n override: Record<string, string> | undefined,\n): Record<string, string | undefined> | undefined {\n if (base == null && override == null) {\n return undefined;\n }\n const out: Record<string, string | undefined> = { ...(base ?? {}) };\n if (override != null) {\n for (const [k, v] of Object.entries(override)) {\n out[k] = v;\n }\n }\n return out;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Identifies a model in the Foundry Language Model Service.
|
|
19
|
+
*
|
|
20
|
+
* - `lmsModel`: a built-in LMS model addressed by `apiName` (e.g. "gpt-4o")
|
|
21
|
+
* - `registeredModel`: a customer-registered model addressed by RID
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** Opaque language model handle accepted by `generateText` / `streamText`. */
|
|
25
|
+
|
|
26
|
+
/** @internal */
|
|
27
|
+
|
|
28
|
+
const internals = new WeakMap();
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Construct a Foundry-LMS-backed {@link LanguageModel}.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { foundryModel, generateText } from "@osdk/aip-core";
|
|
36
|
+
*
|
|
37
|
+
* const model = foundryModel({ client, model: "gpt-4o" });
|
|
38
|
+
* const { text } = await generateText({
|
|
39
|
+
* model,
|
|
40
|
+
* prompt: "Hello, world",
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export function foundryModel(options) {
|
|
45
|
+
const identifier = typeof options.model === "string" ? {
|
|
46
|
+
type: "lmsModel",
|
|
47
|
+
apiName: options.model
|
|
48
|
+
} : options.model;
|
|
49
|
+
const id = identifier.type === "lmsModel" ? identifier.apiName : identifier.registeredModelRid;
|
|
50
|
+
const handle = Object.freeze({
|
|
51
|
+
modelId: `foundry/${id}`,
|
|
52
|
+
provider: "foundry-lms"
|
|
53
|
+
});
|
|
54
|
+
internals.set(handle, {
|
|
55
|
+
client: options.client,
|
|
56
|
+
identifier
|
|
57
|
+
});
|
|
58
|
+
return handle;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Internal accessor for the foundry handle. Not exported from the package
|
|
63
|
+
* index. `runStep` calls this; consumers should never need it.
|
|
64
|
+
*
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
export function _getFoundryInternal(model) {
|
|
68
|
+
const handle = internals.get(model);
|
|
69
|
+
if (handle == null) {
|
|
70
|
+
throw new Error(`LanguageModel(modelId=${model.modelId}, provider=${model.provider}) ` + `was not constructed via foundryModel(). Only foundry-lms models are supported in v0.`);
|
|
71
|
+
}
|
|
72
|
+
return handle;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","names":["internals","WeakMap","foundryModel","options","identifier","model","type","apiName","id","registeredModelRid","handle","Object","freeze","modelId","provider","set","client","_getFoundryInternal","get","Error"],"sources":["model.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PlatformClient } from \"@osdk/client\";\n\n/**\n * Identifies a model in the Foundry Language Model Service.\n *\n * - `lmsModel`: a built-in LMS model addressed by `apiName` (e.g. \"gpt-4o\")\n * - `registeredModel`: a customer-registered model addressed by RID\n */\nexport type ModelIdentifier =\n | { type: \"lmsModel\"; apiName: string }\n | { type: \"registeredModel\"; registeredModelRid: string };\n\n/** Opaque language model handle accepted by `generateText` / `streamText`. */\nexport interface LanguageModel {\n /** Stable identifier for logging / telemetry, e.g. \"foundry/gpt-4o\". */\n readonly modelId: string;\n /** Provider tag — `\"foundry-lms\"` for the built-in LMS adapter. */\n readonly provider: string;\n}\n\nexport interface FoundryModelOptions {\n /** Foundry PlatformClient providing the auth token + base URL. */\n client: PlatformClient;\n /** LMS model API name or registered model RID. */\n model: string | ModelIdentifier;\n}\n\n/** @internal */\nexport interface FoundryInternalHandle {\n client: PlatformClient;\n identifier: ModelIdentifier;\n}\n\nconst internals: WeakMap<LanguageModel, FoundryInternalHandle> = new WeakMap();\n\n/**\n * Construct a Foundry-LMS-backed {@link LanguageModel}.\n *\n * @example\n * ```ts\n * import { foundryModel, generateText } from \"@osdk/aip-core\";\n *\n * const model = foundryModel({ client, model: \"gpt-4o\" });\n * const { text } = await generateText({\n * model,\n * prompt: \"Hello, world\",\n * });\n * ```\n */\nexport function foundryModel(options: FoundryModelOptions): LanguageModel {\n const identifier: ModelIdentifier = typeof options.model === \"string\"\n ? { type: \"lmsModel\", apiName: options.model }\n : options.model;\n\n const id = identifier.type === \"lmsModel\"\n ? identifier.apiName\n : identifier.registeredModelRid;\n\n const handle: LanguageModel = Object.freeze({\n modelId: `foundry/${id}`,\n provider: \"foundry-lms\",\n });\n\n internals.set(handle, {\n client: options.client,\n identifier,\n });\n\n return handle;\n}\n\n/**\n * Internal accessor for the foundry handle. Not exported from the package\n * index. `runStep` calls this; consumers should never need it.\n *\n * @internal\n */\nexport function _getFoundryInternal(\n model: LanguageModel,\n): FoundryInternalHandle {\n const handle = internals.get(model);\n if (handle == null) {\n throw new Error(\n `LanguageModel(modelId=${model.modelId}, provider=${model.provider}) `\n + `was not constructed via foundryModel(). Only foundry-lms models are supported in v0.`,\n );\n }\n return handle;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;;AAKA;;AAeA;;AAMA,MAAMA,SAAwD,GAAG,IAAIC,OAAO,CAAC,CAAC;;AAE9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAACC,OAA4B,EAAiB;EACxE,MAAMC,UAA2B,GAAG,OAAOD,OAAO,CAACE,KAAK,KAAK,QAAQ,GACjE;IAAEC,IAAI,EAAE,UAAU;IAAEC,OAAO,EAAEJ,OAAO,CAACE;EAAM,CAAC,GAC5CF,OAAO,CAACE,KAAK;EAEjB,MAAMG,EAAE,GAAGJ,UAAU,CAACE,IAAI,KAAK,UAAU,GACrCF,UAAU,CAACG,OAAO,GAClBH,UAAU,CAACK,kBAAkB;EAEjC,MAAMC,MAAqB,GAAGC,MAAM,CAACC,MAAM,CAAC;IAC1CC,OAAO,EAAE,WAAWL,EAAE,EAAE;IACxBM,QAAQ,EAAE;EACZ,CAAC,CAAC;EAEFd,SAAS,CAACe,GAAG,CAACL,MAAM,EAAE;IACpBM,MAAM,EAAEb,OAAO,CAACa,MAAM;IACtBZ;EACF,CAAC,CAAC;EAEF,OAAOM,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASO,mBAAmBA,CACjCZ,KAAoB,EACG;EACvB,MAAMK,MAAM,GAAGV,SAAS,CAACkB,GAAG,CAACb,KAAK,CAAC;EACnC,IAAIK,MAAM,IAAI,IAAI,EAAE;IAClB,MAAM,IAAIS,KAAK,CACb,yBAAyBd,KAAK,CAACQ,OAAO,cAAcR,KAAK,CAACS,QAAQ,IAAI,GAClE,sFACN,CAAC;EACH;EACA,OAAOJ,MAAM;AACf","ignoreList":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Palantir Technologies, Inc. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export { createFoundryAI } from "../ai-sdk/provider.js";
|
|
18
|
+
//# sourceMappingURL=ai-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk.js","names":["createFoundryAI"],"sources":["ai-sdk.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport { createFoundryAI } from \"../ai-sdk/provider.js\";\nexport type {\n FoundryAIProvider,\n FoundryAIProviderOptions,\n} from \"../ai-sdk/provider.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,eAAe,QAAQ,uBAAuB","ignoreList":[]}
|