@absolutejs/absolute 0.19.0-beta.226 → 0.19.0-beta.228
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/.absolutejs/eslint-cache +1 -0
- package/.absolutejs/prettier.cache.json +42 -19
- package/.absolutejs/vue-tsc.tsbuildinfo +1 -1
- package/.claude/settings.local.json +2 -1
- package/ROADMAP.md +0 -25
- package/dist/{Image-y5bdvj57.vue → Image-b3r6hxqk.vue} +6 -1
- package/dist/ai/index.js +529 -0
- package/dist/ai/index.js.map +13 -0
- package/dist/ai/providers/anthropic.js +396 -0
- package/dist/ai/providers/anthropic.js.map +10 -0
- package/dist/ai/providers/ollama.js +233 -0
- package/dist/ai/providers/ollama.js.map +10 -0
- package/dist/ai/providers/openai.js +355 -0
- package/dist/ai/providers/openai.js.map +10 -0
- package/dist/ai-client/angular/ai/index.js +532 -0
- package/dist/ai-client/react/ai/index.js +499 -0
- package/dist/ai-client/vue/ai/index.js +460 -0
- package/dist/angular/ai/index.js +668 -0
- package/dist/angular/ai/index.js.map +15 -0
- package/dist/angular/components/image.component.js +1 -1
- package/dist/angular/index.js +11 -1
- package/dist/angular/index.js.map +3 -3
- package/dist/build.js +48 -2
- package/dist/build.js.map +4 -4
- package/dist/index.js +50 -2
- package/dist/index.js.map +6 -6
- package/dist/react/ai/index.js +635 -0
- package/dist/react/ai/index.js.map +16 -0
- package/dist/react/components/index.js +11 -1
- package/dist/react/components/index.js.map +2 -2
- package/dist/react/hooks/index.js +11 -1
- package/dist/react/hooks/index.js.map +2 -2
- package/dist/react/index.js +11 -1
- package/dist/react/index.js.map +3 -3
- package/dist/src/ai/client/actions.d.ts +46 -0
- package/dist/src/ai/client/connection.d.ts +9 -0
- package/dist/src/ai/client/messageStore.d.ts +12 -0
- package/dist/src/ai/conversationManager.d.ts +11 -0
- package/dist/src/ai/index.d.ts +3 -0
- package/dist/src/ai/protocol.d.ts +4 -0
- package/dist/src/ai/providers/anthropic.d.ts +3 -0
- package/dist/src/ai/providers/ollama.d.ts +6 -0
- package/dist/src/ai/providers/openai.d.ts +7 -0
- package/dist/src/ai/streamAI.d.ts +2 -0
- package/dist/src/angular/ai/ai-stream.service.d.ts +15 -0
- package/dist/src/angular/ai/index.d.ts +1 -0
- package/dist/src/react/ai/AIStreamProvider.d.ts +13 -0
- package/dist/src/react/ai/index.d.ts +2 -0
- package/dist/src/react/ai/useAIStream.d.ts +8 -0
- package/dist/src/svelte/ai/createAIStream.d.ts +10 -0
- package/dist/src/svelte/ai/index.d.ts +1 -0
- package/dist/src/vue/ai/index.d.ts +1 -0
- package/dist/src/vue/ai/useAIStream.d.ts +22 -0
- package/dist/svelte/ai/index.js +590 -0
- package/dist/svelte/ai/index.js.map +15 -0
- package/dist/svelte/components/Image.svelte +6 -1
- package/dist/svelte/index.js +11 -1
- package/dist/svelte/index.js.map +3 -3
- package/dist/types/ai.d.ts +188 -0
- package/dist/types/anthropic.d.ts +18 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/typeGuards.d.ts +3 -0
- package/dist/vue/ai/index.js +596 -0
- package/dist/vue/ai/index.js.map +15 -0
- package/dist/vue/components/Image.vue +6 -1
- package/dist/vue/components/index.js +12 -2
- package/dist/vue/components/index.js.map +1 -1
- package/dist/vue/index.js +11 -1
- package/dist/vue/index.js.map +3 -3
- package/package.json +36 -1
- package/scripts/build.ts +33 -0
- package/types/ai.ts +235 -0
- package/types/anthropic.ts +17 -0
- package/types/index.ts +1 -0
- package/types/typeGuards.ts +72 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/ai/providers/ollama.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type {\n\tAIChunk,\n\tAIDoneChunk,\n\tAIProviderConfig,\n\tAIProviderStreamParams\n} from '../../../types/ai';\n\ntype OllamaConfig = {\n\tbaseUrl?: string;\n};\n\ntype OllamaMessage = {\n\tcontent: string;\n\trole: 'assistant' | 'system' | 'user';\n};\n\nconst DEFAULT_BASE_URL = 'http://localhost:11434';\nconst ZERO_TOKENS = 0;\n\nconst DONE_CHUNK: AIChunk = { type: 'done' };\n\nconst buildRequestBody = (params: AIProviderStreamParams) => {\n\tconst messages: OllamaMessage[] = params.messages.map((msg) => ({\n\t\tcontent: typeof msg.content === 'string' ? msg.content : '',\n\t\trole: msg.role\n\t}));\n\n\tif (params.systemPrompt) {\n\t\tmessages.unshift({ content: params.systemPrompt, role: 'system' });\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tmodel: params.model,\n\t\tstream: true\n\t};\n};\n\nconst isRecord = (val: unknown): val is Record<string, unknown> =>\n\tval !== null && typeof val === 'object' && !Array.isArray(val);\n\nconst tryParseJSON = (text: string) => {\n\ttry {\n\t\tconst result: unknown = JSON.parse(text);\n\t\tif (isRecord(result)) {\n\t\t\treturn result;\n\t\t}\n\n\t\treturn null;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nconst buildDoneChunk = (parsed: Record<string, unknown>): AIDoneChunk => {\n\tconst promptEvalCount =\n\t\ttypeof parsed.prompt_eval_count === 'number'\n\t\t\t? parsed.prompt_eval_count\n\t\t\t: undefined;\n\tconst evalCount =\n\t\ttypeof parsed.eval_count === 'number' ? parsed.eval_count : undefined;\n\tconst totalDuration =\n\t\ttypeof parsed.total_duration === 'number'\n\t\t\t? parsed.total_duration\n\t\t\t: undefined;\n\n\tconst hasTokenCounts =\n\t\tpromptEvalCount !== undefined || evalCount !== undefined;\n\tif (hasTokenCounts) {\n\t\treturn {\n\t\t\ttype: 'done',\n\t\t\tusage: {\n\t\t\t\tinputTokens: promptEvalCount ?? ZERO_TOKENS,\n\t\t\t\toutputTokens: evalCount ?? ZERO_TOKENS\n\t\t\t}\n\t\t};\n\t}\n\n\tif (totalDuration !== undefined) {\n\t\treturn {\n\t\t\ttype: 'done',\n\t\t\tusage: { inputTokens: ZERO_TOKENS, outputTokens: ZERO_TOKENS }\n\t\t};\n\t}\n\n\treturn { type: 'done' };\n};\n\nconst buildTextChunk = (content: string): AIChunk => ({\n\tcontent,\n\ttype: 'text'\n});\n\nconst extractTextChunk = (parsed: Record<string, unknown>) => {\n\tconst { message } = parsed;\n\tif (!isRecord(message)) {\n\t\treturn null;\n\t}\n\n\tconst { content } = message;\n\tif (typeof content !== 'string' || !content) {\n\t\treturn null;\n\t}\n\n\treturn buildTextChunk(content);\n};\n\nconst processLine = (line: string) => {\n\tconst trimmed = line.trim();\n\tif (!trimmed) {\n\t\treturn null;\n\t}\n\n\tconst parsed = tryParseJSON(trimmed);\n\tif (!parsed) {\n\t\treturn null;\n\t}\n\n\tif (parsed.done === true) {\n\t\treturn buildDoneChunk(parsed);\n\t}\n\n\treturn extractTextChunk(parsed);\n};\n\nconst processBufferedLines = (lines: string[]) =>\n\tlines.map(processLine).filter((chunk): chunk is AIChunk => chunk !== null);\n\nconst readStreamChunks = async (\n\treader: ReadableStreamDefaultReader<Uint8Array>,\n\tdecoder: TextDecoder,\n\tbuffer: string,\n\tsignal?: AbortSignal\n) => {\n\tconst emptyChunks: AIChunk[] = [];\n\n\tif (signal?.aborted) {\n\t\treturn {\n\t\t\tallChunks: emptyChunks,\n\t\t\tcurrentBuffer: buffer,\n\t\t\tfinished: true\n\t\t};\n\t}\n\n\tconst result = await reader.read();\n\tconst { done, value } = result;\n\n\tif (done) {\n\t\treturn {\n\t\t\tallChunks: emptyChunks,\n\t\t\tcurrentBuffer: buffer,\n\t\t\tfinished: true\n\t\t};\n\t}\n\n\tconst currentBuffer = buffer + decoder.decode(value, { stream: true });\n\tconst lines = currentBuffer.split('\\n');\n\tconst remainder = lines.pop() ?? '';\n\tconst allChunks = processBufferedLines(lines);\n\tconst finished = allChunks.some((c) => c.type === 'done');\n\n\treturn { allChunks, currentBuffer: remainder, finished };\n};\n\nconst parseNDJSONStream = async function* (\n\tbody: ReadableStream<Uint8Array>,\n\tsignal?: AbortSignal\n) {\n\tconst reader = body.getReader();\n\n\ttry {\n\t\tyield* parseNDJSONStreamInner(reader, signal);\n\t} finally {\n\t\treader.releaseLock();\n\t}\n};\n\nconst parseNDJSONStreamInner = async function* (\n\treader: ReadableStreamDefaultReader<Uint8Array>,\n\tsignal?: AbortSignal\n) {\n\tconst decoder = new TextDecoder();\n\tlet buffer = '';\n\tlet done = false;\n\n\twhile (!done) {\n\t\t// eslint-disable-next-line no-await-in-loop\n\t\tconst result = await readStreamChunks(reader, decoder, buffer, signal);\n\t\tbuffer = result.currentBuffer;\n\t\tdone = result.finished;\n\n\t\tyield* result.allChunks;\n\t}\n\n\tyield DONE_CHUNK;\n};\n\nconst fetchAndStream = async function* (\n\tbaseUrl: string,\n\tparams: AIProviderStreamParams\n) {\n\tconst requestBody = buildRequestBody(params);\n\n\tconst response = await fetch(`${baseUrl}/api/chat`, {\n\t\tbody: JSON.stringify(requestBody),\n\t\theaders: { 'Content-Type': 'application/json' },\n\t\tmethod: 'POST',\n\t\tsignal: params.signal\n\t});\n\n\tif (!response.ok) {\n\t\tconst errorText = await response.text();\n\t\tthrow new Error(`Ollama API error ${response.status}: ${errorText}`);\n\t}\n\n\tif (!response.body) {\n\t\tthrow new Error('Ollama API returned no response body');\n\t}\n\n\tyield* parseNDJSONStream(response.body, params.signal);\n};\n\nexport const ollama = (config: OllamaConfig = {}): AIProviderConfig => {\n\tconst baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;\n\n\treturn {\n\t\tstream: (params: AIProviderStreamParams) =>\n\t\t\tfetchAndStream(baseUrl, params)\n\t};\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "7579757CE08DC46864756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
13
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
21
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
|
+
for (let key of __getOwnPropNames(mod))
|
|
24
|
+
if (!__hasOwnProp.call(to, key))
|
|
25
|
+
__defProp(to, key, {
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
27
|
+
enumerable: true
|
|
28
|
+
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
31
|
+
return to;
|
|
32
|
+
};
|
|
33
|
+
var __toCommonJS = (from) => {
|
|
34
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
35
|
+
if (entry)
|
|
36
|
+
return entry;
|
|
37
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
38
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
39
|
+
for (var key of __getOwnPropNames(from))
|
|
40
|
+
if (!__hasOwnProp.call(entry, key))
|
|
41
|
+
__defProp(entry, key, {
|
|
42
|
+
get: __accessProp.bind(from, key),
|
|
43
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
__moduleCache.set(from, entry);
|
|
47
|
+
return entry;
|
|
48
|
+
};
|
|
49
|
+
var __moduleCache;
|
|
50
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
51
|
+
var __returnValue = (v) => v;
|
|
52
|
+
function __exportSetter(name, newValue) {
|
|
53
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
54
|
+
}
|
|
55
|
+
var __export = (target, all) => {
|
|
56
|
+
for (var name in all)
|
|
57
|
+
__defProp(target, name, {
|
|
58
|
+
get: all[name],
|
|
59
|
+
enumerable: true,
|
|
60
|
+
configurable: true,
|
|
61
|
+
set: __exportSetter.bind(all, name)
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
var __legacyDecorateClassTS = function(decorators, target, key, desc) {
|
|
65
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
66
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
67
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
68
|
+
else
|
|
69
|
+
for (var i = decorators.length - 1;i >= 0; i--)
|
|
70
|
+
if (d = decorators[i])
|
|
71
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
72
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
73
|
+
};
|
|
74
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
75
|
+
var __require = import.meta.require;
|
|
76
|
+
|
|
77
|
+
// src/ai/providers/openai.ts
|
|
78
|
+
var DEFAULT_BASE_URL = "https://api.openai.com";
|
|
79
|
+
var SSE_DATA_PREFIX_LENGTH = 6;
|
|
80
|
+
var DONE_SENTINEL = "[DONE]";
|
|
81
|
+
var NOT_FOUND = -1;
|
|
82
|
+
var isRecord = (value) => typeof value === "object" && value !== null;
|
|
83
|
+
var isRecordArray = (value) => Array.isArray(value) && value.length > 0 && isRecord(value[0]);
|
|
84
|
+
var isToolResultBlock = (block) => block.type === "tool_result";
|
|
85
|
+
var hasArrayContent = (msg) => typeof msg.content !== "string" && Array.isArray(msg.content);
|
|
86
|
+
var spliceToolResult = (result, idx, toolResult) => {
|
|
87
|
+
const contentValue = typeof toolResult.content === "string" ? toolResult.content : "";
|
|
88
|
+
result.splice(idx, 0, {
|
|
89
|
+
content: null,
|
|
90
|
+
role: "assistant",
|
|
91
|
+
tool_calls: []
|
|
92
|
+
});
|
|
93
|
+
result.splice(idx + 1, 0, {
|
|
94
|
+
content: contentValue,
|
|
95
|
+
role: "user"
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
var spliceToolResults = (result, idx, toolResults) => {
|
|
99
|
+
result.splice(idx, 1);
|
|
100
|
+
for (const toolResult of toolResults) {
|
|
101
|
+
spliceToolResult(result, idx, toolResult);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
var processMessageAtIndex = (result, msg, idx) => {
|
|
105
|
+
if (!hasArrayContent(msg)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const toolResults = msg.content.filter(isToolResultBlock);
|
|
109
|
+
if (toolResults.length === 0) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
spliceToolResults(result, idx, toolResults);
|
|
113
|
+
};
|
|
114
|
+
var convertSingleMessage = (result, msg, idx) => {
|
|
115
|
+
if (!msg) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
processMessageAtIndex(result, msg, idx);
|
|
119
|
+
};
|
|
120
|
+
var convertToolResultMessages = (messages, params) => {
|
|
121
|
+
const result = [...messages];
|
|
122
|
+
for (let idx = 0;idx < params.messages.length; idx++) {
|
|
123
|
+
convertSingleMessage(result, params.messages[idx], idx);
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
};
|
|
127
|
+
var mapToolDefinitions = (tools) => tools.map((tool) => ({
|
|
128
|
+
function: {
|
|
129
|
+
description: tool.description,
|
|
130
|
+
name: tool.name,
|
|
131
|
+
parameters: tool.input_schema
|
|
132
|
+
},
|
|
133
|
+
type: "function"
|
|
134
|
+
}));
|
|
135
|
+
var buildRequestBody = (params) => {
|
|
136
|
+
const messages = convertToolResultMessages(params.messages.map((msg) => ({
|
|
137
|
+
content: typeof msg.content === "string" ? msg.content : null,
|
|
138
|
+
role: msg.role
|
|
139
|
+
})), params);
|
|
140
|
+
const body = {
|
|
141
|
+
messages,
|
|
142
|
+
model: params.model,
|
|
143
|
+
stream: true,
|
|
144
|
+
stream_options: { include_usage: true }
|
|
145
|
+
};
|
|
146
|
+
if (params.tools && params.tools.length > 0) {
|
|
147
|
+
body.tools = mapToolDefinitions(params.tools);
|
|
148
|
+
}
|
|
149
|
+
return body;
|
|
150
|
+
};
|
|
151
|
+
var parseToolInput = (rawArguments) => {
|
|
152
|
+
try {
|
|
153
|
+
return JSON.parse(rawArguments);
|
|
154
|
+
} catch {
|
|
155
|
+
return rawArguments;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
var flushPendingToolCalls = function* (pendingToolCalls) {
|
|
159
|
+
for (const [, tool] of pendingToolCalls) {
|
|
160
|
+
const input = parseToolInput(tool.arguments);
|
|
161
|
+
yield {
|
|
162
|
+
id: tool.id,
|
|
163
|
+
input,
|
|
164
|
+
name: tool.name,
|
|
165
|
+
type: "tool_use"
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
pendingToolCalls.clear();
|
|
169
|
+
};
|
|
170
|
+
var extractUsage = (parsedUsage) => ({
|
|
171
|
+
inputTokens: parsedUsage.prompt_tokens ?? 0,
|
|
172
|
+
outputTokens: parsedUsage.completion_tokens ?? 0
|
|
173
|
+
});
|
|
174
|
+
var resolveToolCallIndex = (toolCall) => {
|
|
175
|
+
const raw = typeof toolCall.index === "number" ? toolCall.index : NOT_FOUND;
|
|
176
|
+
return raw < 0 ? undefined : raw;
|
|
177
|
+
};
|
|
178
|
+
var initPendingToolCall = (toolCall, func, index, pendingToolCalls) => {
|
|
179
|
+
if (pendingToolCalls.has(index)) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const toolId = typeof toolCall.id === "string" ? toolCall.id : "";
|
|
183
|
+
const toolName = func && typeof func.name === "string" ? func.name : "";
|
|
184
|
+
pendingToolCalls.set(index, {
|
|
185
|
+
arguments: "",
|
|
186
|
+
id: toolId,
|
|
187
|
+
name: toolName
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
var updatePendingToolCall = (toolCall, func, pending) => {
|
|
191
|
+
if (typeof toolCall.id === "string") {
|
|
192
|
+
pending.id = toolCall.id;
|
|
193
|
+
}
|
|
194
|
+
if (func && typeof func.name === "string") {
|
|
195
|
+
pending.name = func.name;
|
|
196
|
+
}
|
|
197
|
+
if (func && typeof func.arguments === "string") {
|
|
198
|
+
pending.arguments += func.arguments;
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
var processToolCallDelta = (toolCall, pendingToolCalls) => {
|
|
202
|
+
const index = resolveToolCallIndex(toolCall);
|
|
203
|
+
if (index === undefined) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const func = isRecord(toolCall.function) ? toolCall.function : null;
|
|
207
|
+
initPendingToolCall(toolCall, func, index, pendingToolCalls);
|
|
208
|
+
const pending = pendingToolCalls.get(index);
|
|
209
|
+
if (!pending) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
updatePendingToolCall(toolCall, func, pending);
|
|
213
|
+
};
|
|
214
|
+
var processToolCallDeltas = (toolCalls, pendingToolCalls) => {
|
|
215
|
+
for (const toolCall of toolCalls) {
|
|
216
|
+
processToolCallDelta(toolCall, pendingToolCalls);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
var processDelta = function* (delta, pendingToolCalls) {
|
|
220
|
+
if (typeof delta.content === "string") {
|
|
221
|
+
yield { content: delta.content, type: "text" };
|
|
222
|
+
}
|
|
223
|
+
if (isRecordArray(delta.tool_calls)) {
|
|
224
|
+
processToolCallDeltas(delta.tool_calls, pendingToolCalls);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
var processChoice = function* (choice, pendingToolCalls) {
|
|
228
|
+
const delta = isRecord(choice.delta) ? choice.delta : null;
|
|
229
|
+
if (delta) {
|
|
230
|
+
yield* processDelta(delta, pendingToolCalls);
|
|
231
|
+
}
|
|
232
|
+
if (choice.finish_reason === "tool_calls") {
|
|
233
|
+
yield* flushPendingToolCalls(pendingToolCalls);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
var narrowUsageRecord = (parsed) => {
|
|
237
|
+
if (!isRecord(parsed.usage)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const { usage } = parsed;
|
|
241
|
+
const promptTokens = typeof usage.prompt_tokens === "number" ? usage.prompt_tokens : 0;
|
|
242
|
+
const completionTokens = typeof usage.completion_tokens === "number" ? usage.completion_tokens : 0;
|
|
243
|
+
return extractUsage({
|
|
244
|
+
completion_tokens: completionTokens,
|
|
245
|
+
prompt_tokens: promptTokens
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
var processSSELine = function* (line, pendingToolCalls, currentUsage) {
|
|
249
|
+
const trimmed = line.trim();
|
|
250
|
+
if (!trimmed || !trimmed.startsWith("data: ")) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const data = trimmed.slice(SSE_DATA_PREFIX_LENGTH);
|
|
254
|
+
if (data === DONE_SENTINEL) {
|
|
255
|
+
yield* flushPendingToolCalls(pendingToolCalls);
|
|
256
|
+
yield { type: "done", usage: currentUsage };
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
let parsed;
|
|
260
|
+
try {
|
|
261
|
+
parsed = JSON.parse(data);
|
|
262
|
+
} catch {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const usageUpdate = narrowUsageRecord(parsed);
|
|
266
|
+
if (usageUpdate) {
|
|
267
|
+
yield { type: "usage_update", usage: usageUpdate };
|
|
268
|
+
}
|
|
269
|
+
const { choices } = parsed;
|
|
270
|
+
if (!isRecordArray(choices)) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const [firstChoice] = choices;
|
|
274
|
+
if (!firstChoice) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
yield* processChoice(firstChoice, pendingToolCalls);
|
|
278
|
+
};
|
|
279
|
+
var isUsageUpdate = (chunk) => chunk.type === "usage_update";
|
|
280
|
+
var collectYieldableChunks = (line, pendingToolCalls, usageRef) => {
|
|
281
|
+
const allChunks = Array.from(processSSELine(line, pendingToolCalls, usageRef.current));
|
|
282
|
+
const usageChunks = allChunks.filter(isUsageUpdate);
|
|
283
|
+
const lastUsage = usageChunks.at(NOT_FOUND);
|
|
284
|
+
if (lastUsage) {
|
|
285
|
+
usageRef.current = lastUsage.usage;
|
|
286
|
+
}
|
|
287
|
+
return allChunks.filter((chunk) => !isUsageUpdate(chunk));
|
|
288
|
+
};
|
|
289
|
+
var processSSELines = function* (lines, pendingToolCalls, usageRef) {
|
|
290
|
+
for (const line of lines) {
|
|
291
|
+
yield* collectYieldableChunks(line, pendingToolCalls, usageRef);
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
var processStreamValue = (value, decoder, state) => {
|
|
295
|
+
state.buffer += decoder.decode(value, { stream: true });
|
|
296
|
+
const lines = state.buffer.split(`
|
|
297
|
+
`);
|
|
298
|
+
state.buffer = lines.pop() ?? "";
|
|
299
|
+
return lines;
|
|
300
|
+
};
|
|
301
|
+
var drainReader = async function* (reader, decoder, state, signal) {
|
|
302
|
+
for (let result = await reader.read();!result.done && !signal?.aborted; result = await reader.read()) {
|
|
303
|
+
const lines = processStreamValue(result.value, decoder, state);
|
|
304
|
+
yield* processSSELines(lines, state.pendingToolCalls, state.usageRef);
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
var parseSSEStream = async function* (body, signal) {
|
|
308
|
+
const reader = body.getReader();
|
|
309
|
+
const decoder = new TextDecoder;
|
|
310
|
+
const state = {
|
|
311
|
+
buffer: "",
|
|
312
|
+
pendingToolCalls: new Map,
|
|
313
|
+
usageRef: { current: undefined }
|
|
314
|
+
};
|
|
315
|
+
try {
|
|
316
|
+
yield* drainReader(reader, decoder, state, signal);
|
|
317
|
+
yield { type: "done", usage: state.usageRef.current };
|
|
318
|
+
} finally {
|
|
319
|
+
reader.releaseLock();
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
var fetchOpenAIStream = async function* (baseUrl, apiKey, body, signal) {
|
|
323
|
+
const response = await fetch(`${baseUrl}/v1/chat/completions`, {
|
|
324
|
+
body: JSON.stringify(body),
|
|
325
|
+
headers: {
|
|
326
|
+
Authorization: `Bearer ${apiKey}`,
|
|
327
|
+
"Content-Type": "application/json"
|
|
328
|
+
},
|
|
329
|
+
method: "POST",
|
|
330
|
+
signal
|
|
331
|
+
});
|
|
332
|
+
if (!response.ok) {
|
|
333
|
+
const errorText = await response.text();
|
|
334
|
+
throw new Error(`OpenAI API error ${response.status}: ${errorText}`);
|
|
335
|
+
}
|
|
336
|
+
if (!response.body) {
|
|
337
|
+
throw new Error("OpenAI API returned no response body");
|
|
338
|
+
}
|
|
339
|
+
yield* parseSSEStream(response.body, signal);
|
|
340
|
+
};
|
|
341
|
+
var openai = (config) => {
|
|
342
|
+
const baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
343
|
+
return {
|
|
344
|
+
stream: (params) => {
|
|
345
|
+
const body = buildRequestBody(params);
|
|
346
|
+
return fetchOpenAIStream(baseUrl, config.apiKey, body, params.signal);
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
};
|
|
350
|
+
export {
|
|
351
|
+
openai
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
//# debugId=C39A0B1532ABA2F464756E2164756E21
|
|
355
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/ai/providers/openai.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type {\n\tAIProviderConfig,\n\tAIProviderContentBlock,\n\tAIProviderMessage,\n\tAIProviderStreamParams,\n\tAIProviderToolDefinition,\n\tAIUsage\n} from '../../../types/ai';\n\ntype OpenAIConfig = {\n\tapiKey: string;\n\tbaseUrl?: string;\n};\n\ntype OpenAIMessage = {\n\tcontent: string | null;\n\trole: 'user' | 'assistant' | 'system';\n\ttool_calls?: Array<{\n\t\tfunction: { arguments: string; name: string };\n\t\tid: string;\n\t\ttype: 'function';\n\t}>;\n};\n\ntype PendingToolCall = {\n\targuments: string;\n\tid: string;\n\tname: string;\n};\n\ntype UsageRef = {\n\tcurrent: AIUsage | undefined;\n};\n\ntype StreamState = {\n\tbuffer: string;\n\tpendingToolCalls: Map<number, PendingToolCall>;\n\tusageRef: UsageRef;\n};\n\nconst DEFAULT_BASE_URL = 'https://api.openai.com';\nconst SSE_DATA_PREFIX_LENGTH = 6;\nconst DONE_SENTINEL = '[DONE]';\nconst NOT_FOUND = -1;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' && value !== null;\n\nconst isRecordArray = (\n\tvalue: unknown\n): value is Array<Record<string, unknown>> =>\n\tArray.isArray(value) && value.length > 0 && isRecord(value[0]);\n\nconst isToolResultBlock = (\n\tblock: AIProviderContentBlock\n): block is AIProviderContentBlock & {\n\tcontent: string;\n\ttool_use_id: string;\n\ttype: 'tool_result';\n} => block.type === 'tool_result';\n\nconst hasArrayContent = (\n\tmsg: AIProviderMessage\n): msg is AIProviderMessage & { content: AIProviderContentBlock[] } =>\n\ttypeof msg.content !== 'string' && Array.isArray(msg.content);\n\nconst spliceToolResult = (\n\tresult: OpenAIMessage[],\n\tidx: number,\n\ttoolResult: { content: string; tool_use_id: string; type: 'tool_result' }\n) => {\n\tconst contentValue =\n\t\ttypeof toolResult.content === 'string' ? toolResult.content : '';\n\n\tresult.splice(idx, 0, {\n\t\tcontent: null,\n\t\trole: 'assistant',\n\t\ttool_calls: []\n\t});\n\tresult.splice(idx + 1, 0, {\n\t\tcontent: contentValue,\n\t\trole: 'user'\n\t});\n};\n\nconst spliceToolResults = (\n\tresult: OpenAIMessage[],\n\tidx: number,\n\ttoolResults: Array<{\n\t\tcontent: string;\n\t\ttool_use_id: string;\n\t\ttype: 'tool_result';\n\t}>\n) => {\n\tresult.splice(idx, 1);\n\tfor (const toolResult of toolResults) {\n\t\tspliceToolResult(result, idx, toolResult);\n\t}\n};\n\nconst processMessageAtIndex = (\n\tresult: OpenAIMessage[],\n\tmsg: AIProviderMessage,\n\tidx: number\n) => {\n\tif (!hasArrayContent(msg)) {\n\t\treturn;\n\t}\n\n\tconst toolResults = msg.content.filter(isToolResultBlock);\n\tif (toolResults.length === 0) {\n\t\treturn;\n\t}\n\n\tspliceToolResults(result, idx, toolResults);\n};\n\nconst convertSingleMessage = (\n\tresult: OpenAIMessage[],\n\tmsg: AIProviderMessage | undefined,\n\tidx: number\n) => {\n\tif (!msg) {\n\t\treturn;\n\t}\n\n\tprocessMessageAtIndex(result, msg, idx);\n};\n\nconst convertToolResultMessages = (\n\tmessages: OpenAIMessage[],\n\tparams: AIProviderStreamParams\n) => {\n\tconst result = [...messages];\n\n\tfor (let idx = 0; idx < params.messages.length; idx++) {\n\t\tconvertSingleMessage(result, params.messages[idx], idx);\n\t}\n\n\treturn result;\n};\n\nconst mapToolDefinitions = (tools: AIProviderToolDefinition[]) =>\n\ttools.map((tool) => ({\n\t\tfunction: {\n\t\t\tdescription: tool.description,\n\t\t\tname: tool.name,\n\t\t\tparameters: tool.input_schema\n\t\t},\n\t\ttype: 'function'\n\t}));\n\nconst buildRequestBody = (params: AIProviderStreamParams) => {\n\tconst messages = convertToolResultMessages(\n\t\tparams.messages.map((msg) => ({\n\t\t\tcontent: typeof msg.content === 'string' ? msg.content : null,\n\t\t\trole: msg.role\n\t\t})),\n\t\tparams\n\t);\n\n\tconst body: Record<string, unknown> = {\n\t\tmessages,\n\t\tmodel: params.model,\n\t\tstream: true,\n\t\tstream_options: { include_usage: true }\n\t};\n\n\tif (params.tools && params.tools.length > 0) {\n\t\tbody.tools = mapToolDefinitions(params.tools);\n\t}\n\n\treturn body;\n};\n\nconst parseToolInput = (rawArguments: string) => {\n\ttry {\n\t\treturn JSON.parse(rawArguments);\n\t} catch {\n\t\treturn rawArguments;\n\t}\n};\n\nconst flushPendingToolCalls = function* (\n\tpendingToolCalls: Map<number, PendingToolCall>\n) {\n\tfor (const [, tool] of pendingToolCalls) {\n\t\tconst input = parseToolInput(tool.arguments);\n\t\tyield {\n\t\t\tid: tool.id,\n\t\t\tinput,\n\t\t\tname: tool.name,\n\t\t\ttype: 'tool_use' as const\n\t\t};\n\t}\n\n\tpendingToolCalls.clear();\n};\n\nconst extractUsage = (parsedUsage: Record<string, number>) => ({\n\tinputTokens: parsedUsage.prompt_tokens ?? 0,\n\toutputTokens: parsedUsage.completion_tokens ?? 0\n});\n\nconst resolveToolCallIndex = (toolCall: Record<string, unknown>) => {\n\tconst raw = typeof toolCall.index === 'number' ? toolCall.index : NOT_FOUND;\n\n\treturn raw < 0 ? undefined : raw;\n};\n\nconst initPendingToolCall = (\n\ttoolCall: Record<string, unknown>,\n\tfunc: Record<string, unknown> | null,\n\tindex: number,\n\tpendingToolCalls: Map<number, PendingToolCall>\n) => {\n\tif (pendingToolCalls.has(index)) {\n\t\treturn;\n\t}\n\n\tconst toolId = typeof toolCall.id === 'string' ? toolCall.id : '';\n\tconst toolName = func && typeof func.name === 'string' ? func.name : '';\n\n\tpendingToolCalls.set(index, {\n\t\targuments: '',\n\t\tid: toolId,\n\t\tname: toolName\n\t});\n};\n\nconst updatePendingToolCall = (\n\ttoolCall: Record<string, unknown>,\n\tfunc: Record<string, unknown> | null,\n\tpending: PendingToolCall\n) => {\n\tif (typeof toolCall.id === 'string') {\n\t\tpending.id = toolCall.id;\n\t}\n\n\tif (func && typeof func.name === 'string') {\n\t\tpending.name = func.name;\n\t}\n\n\tif (func && typeof func.arguments === 'string') {\n\t\tpending.arguments += func.arguments;\n\t}\n};\n\nconst processToolCallDelta = (\n\ttoolCall: Record<string, unknown>,\n\tpendingToolCalls: Map<number, PendingToolCall>\n) => {\n\tconst index = resolveToolCallIndex(toolCall);\n\tif (index === undefined) {\n\t\treturn;\n\t}\n\n\tconst func = isRecord(toolCall.function) ? toolCall.function : null;\n\tinitPendingToolCall(toolCall, func, index, pendingToolCalls);\n\n\tconst pending = pendingToolCalls.get(index);\n\tif (!pending) {\n\t\treturn;\n\t}\n\n\tupdatePendingToolCall(toolCall, func, pending);\n};\n\nconst processToolCallDeltas = (\n\ttoolCalls: Array<Record<string, unknown>>,\n\tpendingToolCalls: Map<number, PendingToolCall>\n) => {\n\tfor (const toolCall of toolCalls) {\n\t\tprocessToolCallDelta(toolCall, pendingToolCalls);\n\t}\n};\n\nconst processDelta = function* (\n\tdelta: Record<string, unknown>,\n\tpendingToolCalls: Map<number, PendingToolCall>\n) {\n\tif (typeof delta.content === 'string') {\n\t\tyield { content: delta.content, type: 'text' as const };\n\t}\n\n\tif (isRecordArray(delta.tool_calls)) {\n\t\tprocessToolCallDeltas(delta.tool_calls, pendingToolCalls);\n\t}\n};\n\nconst processChoice = function* (\n\tchoice: Record<string, unknown>,\n\tpendingToolCalls: Map<number, PendingToolCall>\n) {\n\tconst delta = isRecord(choice.delta) ? choice.delta : null;\n\tif (delta) {\n\t\tyield* processDelta(delta, pendingToolCalls);\n\t}\n\n\tif (choice.finish_reason === 'tool_calls') {\n\t\tyield* flushPendingToolCalls(pendingToolCalls);\n\t}\n};\n\nconst narrowUsageRecord = (parsed: Record<string, unknown>) => {\n\tif (!isRecord(parsed.usage)) {\n\t\treturn undefined;\n\t}\n\n\tconst { usage } = parsed;\n\tconst promptTokens =\n\t\ttypeof usage.prompt_tokens === 'number' ? usage.prompt_tokens : 0;\n\tconst completionTokens =\n\t\ttypeof usage.completion_tokens === 'number'\n\t\t\t? usage.completion_tokens\n\t\t\t: 0;\n\n\treturn extractUsage({\n\t\tcompletion_tokens: completionTokens,\n\t\tprompt_tokens: promptTokens\n\t});\n};\n\nconst processSSELine = function* (\n\tline: string,\n\tpendingToolCalls: Map<number, PendingToolCall>,\n\tcurrentUsage: AIUsage | undefined\n) {\n\tconst trimmed = line.trim();\n\tif (!trimmed || !trimmed.startsWith('data: ')) {\n\t\treturn;\n\t}\n\n\tconst data = trimmed.slice(SSE_DATA_PREFIX_LENGTH);\n\tif (data === DONE_SENTINEL) {\n\t\tyield* flushPendingToolCalls(pendingToolCalls);\n\t\tyield { type: 'done' as const, usage: currentUsage };\n\n\t\treturn;\n\t}\n\n\tlet parsed: Record<string, unknown>;\n\ttry {\n\t\tparsed = JSON.parse(data);\n\t} catch {\n\t\treturn;\n\t}\n\n\tconst usageUpdate = narrowUsageRecord(parsed);\n\tif (usageUpdate) {\n\t\tyield { type: 'usage_update' as const, usage: usageUpdate };\n\t}\n\n\tconst { choices } = parsed;\n\tif (!isRecordArray(choices)) {\n\t\treturn;\n\t}\n\n\tconst [firstChoice] = choices;\n\tif (!firstChoice) {\n\t\treturn;\n\t}\n\n\tyield* processChoice(firstChoice, pendingToolCalls);\n};\n\nconst isUsageUpdate = (chunk: {\n\ttype: string;\n\tusage?: AIUsage;\n}): chunk is { type: 'usage_update'; usage: AIUsage } =>\n\tchunk.type === 'usage_update';\n\nconst collectYieldableChunks = (\n\tline: string,\n\tpendingToolCalls: Map<number, PendingToolCall>,\n\tusageRef: UsageRef\n) => {\n\tconst allChunks = Array.from(\n\t\tprocessSSELine(line, pendingToolCalls, usageRef.current)\n\t);\n\tconst usageChunks = allChunks.filter(isUsageUpdate);\n\tconst lastUsage = usageChunks.at(NOT_FOUND);\n\n\tif (lastUsage) {\n\t\tusageRef.current = lastUsage.usage;\n\t}\n\n\treturn allChunks.filter((chunk) => !isUsageUpdate(chunk));\n};\n\nconst processSSELines = function* (\n\tlines: string[],\n\tpendingToolCalls: Map<number, PendingToolCall>,\n\tusageRef: UsageRef\n) {\n\tfor (const line of lines) {\n\t\tyield* collectYieldableChunks(line, pendingToolCalls, usageRef);\n\t}\n};\n\nconst processStreamValue = (\n\tvalue: Uint8Array,\n\tdecoder: TextDecoder,\n\tstate: StreamState\n) => {\n\tstate.buffer += decoder.decode(value, { stream: true });\n\tconst lines = state.buffer.split('\\n');\n\tstate.buffer = lines.pop() ?? '';\n\n\treturn lines;\n};\n\nconst drainReader = async function* (\n\treader: ReadableStreamDefaultReader<Uint8Array>,\n\tdecoder: TextDecoder,\n\tstate: StreamState,\n\tsignal?: AbortSignal\n) {\n\t/* eslint-disable no-await-in-loop */\n\tfor (\n\t\tlet result = await reader.read();\n\t\t!result.done && !signal?.aborted;\n\t\tresult = await reader.read()\n\t) {\n\t\t/* eslint-enable no-await-in-loop */\n\t\tconst lines = processStreamValue(result.value, decoder, state);\n\t\tyield* processSSELines(lines, state.pendingToolCalls, state.usageRef);\n\t}\n};\n\nconst parseSSEStream = async function* (\n\tbody: ReadableStream<Uint8Array>,\n\tsignal?: AbortSignal\n) {\n\tconst reader = body.getReader();\n\tconst decoder = new TextDecoder();\n\tconst state: StreamState = {\n\t\tbuffer: '',\n\t\tpendingToolCalls: new Map<number, PendingToolCall>(),\n\t\tusageRef: { current: undefined }\n\t};\n\n\ttry {\n\t\tyield* drainReader(reader, decoder, state, signal);\n\t\tyield { type: 'done' as const, usage: state.usageRef.current };\n\t} finally {\n\t\treader.releaseLock();\n\t}\n};\n\nconst fetchOpenAIStream = async function* (\n\tbaseUrl: string,\n\tapiKey: string,\n\tbody: Record<string, unknown>,\n\tsignal?: AbortSignal\n) {\n\tconst response = await fetch(`${baseUrl}/v1/chat/completions`, {\n\t\tbody: JSON.stringify(body),\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\t'Content-Type': 'application/json'\n\t\t},\n\t\tmethod: 'POST',\n\t\tsignal\n\t});\n\n\tif (!response.ok) {\n\t\tconst errorText = await response.text();\n\t\tthrow new Error(`OpenAI API error ${response.status}: ${errorText}`);\n\t}\n\n\tif (!response.body) {\n\t\tthrow new Error('OpenAI API returned no response body');\n\t}\n\n\tyield* parseSSEStream(response.body, signal);\n};\n\nexport const openai = (config: OpenAIConfig): AIProviderConfig => {\n\tconst baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;\n\n\treturn {\n\t\tstream: (params: AIProviderStreamParams) => {\n\t\t\tconst body = buildRequestBody(params);\n\n\t\t\treturn fetchOpenAIStream(\n\t\t\t\tbaseUrl,\n\t\t\t\tconfig.apiKey,\n\t\t\t\tbody,\n\t\t\t\tparams.signal\n\t\t\t);\n\t\t}\n\t};\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "C39A0B1532ABA2F464756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|