@gammatech/aijsx 0.4.1-beta.4 → 0.5.0-dev.2024-03-11
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/dist/index.d.mts +24 -5
- package/dist/index.d.ts +24 -5
- package/dist/index.js +182 -52
- package/dist/index.mjs +181 -52
- package/dist/{createElement-x4FT7ZgG.d.mts → jsx-dev-runtime-zWb34twz.d.mts} +28 -2
- package/dist/{createElement-x4FT7ZgG.d.ts → jsx-dev-runtime-zWb34twz.d.ts} +28 -2
- package/dist/jsx-dev-runtime.d.mts +1 -2
- package/dist/jsx-dev-runtime.d.ts +1 -2
- package/dist/jsx-runtime.d.mts +1 -29
- package/dist/jsx-runtime.d.ts +1 -29
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { R as RenderContext, L as LogImplementation, S as SpanProcessor, C as ContextValues, T as Tracer, a as ReadableSpan, b as SpanExporter, A as AIComponent, c as AINode, d as SpanAttributes, E as EvaluatorFn, P as PromptParsed, e as Prompt, N as NotAsyncGenerator, F as FunctionChain, f as StreamChain, g as EvaluatorResult, h as Context } from './
|
|
2
|
-
export { H as AIElement, j as AIFragment, n as AssistantMessage, B as BoundLogger, q as ChatCompletionError, r as ChatCompletionRequestPayloads, l as ChatCompletionRole, y as CombinedLogger, x as ConsoleLogger, z as Literal, s as LogChatCompletionRequest, t as LogChatCompletionResponse, u as LogLevel, v as Logger, w as NoopLogImplementation,
|
|
1
|
+
import { R as RenderContext, L as LogImplementation, S as SpanProcessor, C as ContextValues, T as Tracer, a as ReadableSpan, b as SpanExporter, A as AIComponent, c as AINode, d as SpanAttributes, E as EvaluatorFn, P as PromptParsed, e as Prompt, N as NotAsyncGenerator, F as FunctionChain, f as StreamChain, g as EvaluatorResult, h as Context, J as JSX } from './jsx-dev-runtime-zWb34twz.mjs';
|
|
2
|
+
export { H as AIElement, j as AIFragment, n as AssistantMessage, B as BoundLogger, q as ChatCompletionError, r as ChatCompletionRequestPayloads, l as ChatCompletionRole, y as CombinedLogger, x as ConsoleLogger, z as Literal, s as LogChatCompletionRequest, t as LogChatCompletionResponse, u as LogLevel, v as Logger, w as NoopLogImplementation, Z as OutputParser, K as PropsOfAIComponent, D as RenderResult, I as Renderable, o as RenderedConversationMessage, Q as Span, M as SpanContext, V as SpanEvent, O as SpanStatus, m as SystemMessage, X as TracingContext, W as TracingContextKey, Y as TracingContextManager, U as UserMessage, G as attachedContextSymbol, p as computeUsage, i as createAIElement, k as createContext } from './jsx-dev-runtime-zWb34twz.mjs';
|
|
3
3
|
import { ZodObject, ZodRawShape, ZodTypeAny, ZodString, z } from 'zod';
|
|
4
4
|
import { OpenAI } from 'openai';
|
|
5
5
|
export { OpenAI as OpenAIClient } from 'openai';
|
|
6
6
|
import { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam, ChatCompletionAssistantMessageParam, ChatCompletionCreateParams } from 'openai/resources';
|
|
7
7
|
import AnthropicClient from '@anthropic-ai/sdk';
|
|
8
8
|
export { default as AnthropicClient } from '@anthropic-ai/sdk';
|
|
9
|
+
import { ImageBlockParam } from '@anthropic-ai/sdk/resources';
|
|
9
10
|
export { countTokens as countAnthropicTokens } from '@anthropic-ai/tokenizer';
|
|
10
11
|
|
|
11
12
|
type CreateRenderContextOptions = {
|
|
@@ -178,7 +179,7 @@ declare function tokenLimitForChatModel(model: ValidOpenAIChatModel): number | u
|
|
|
178
179
|
declare function tokenCountForOpenAIMessage(message: OpenAIChatMessage): number;
|
|
179
180
|
declare function tokenCountForOpenAIVisionMessage(message: OpenAIChatMessage): number;
|
|
180
181
|
|
|
181
|
-
type AnthropicChatCompletionRequest = AnthropicClient.
|
|
182
|
+
type AnthropicChatCompletionRequest = AnthropicClient.Messages.MessageStreamParams;
|
|
182
183
|
declare module '@gammatech/aijsx' {
|
|
183
184
|
interface ChatCompletionRequestPayloads {
|
|
184
185
|
anthropic: AnthropicChatCompletionRequest;
|
|
@@ -188,7 +189,7 @@ declare module '@gammatech/aijsx' {
|
|
|
188
189
|
* The set of valid Claude models.
|
|
189
190
|
* @see https://docs.anthropic.com/claude/reference/selecting-a-model
|
|
190
191
|
*/
|
|
191
|
-
type ValidAnthropicChatModel = 'claude-instant-1.2' | 'claude-2.1';
|
|
192
|
+
type ValidAnthropicChatModel = 'claude-instant-1.2' | 'claude-2.1' | 'claude-3-opus-20240229' | 'claude-3-sonnet-20240229';
|
|
192
193
|
declare const AnthropicClientContext: Context<() => AnthropicClient>;
|
|
193
194
|
type AnthropicChatCompletionProps = {
|
|
194
195
|
model: ValidAnthropicChatModel;
|
|
@@ -207,4 +208,22 @@ type AnthropicChatCompletionProps = {
|
|
|
207
208
|
*/
|
|
208
209
|
declare function AnthropicChatCompletion(props: AnthropicChatCompletionProps, { render, logger, tracer, getContext }: RenderContext): AsyncGenerator<string, void, unknown>;
|
|
209
210
|
|
|
210
|
-
|
|
211
|
+
type ClaudeImageBlockBase64 = {
|
|
212
|
+
data: string;
|
|
213
|
+
dimensions?: {
|
|
214
|
+
width: number;
|
|
215
|
+
height: number;
|
|
216
|
+
};
|
|
217
|
+
mediaType: ImageBlockParam.Source['media_type'];
|
|
218
|
+
};
|
|
219
|
+
type ClaudeImageBlockUrl = {
|
|
220
|
+
url: string;
|
|
221
|
+
dimensions?: {
|
|
222
|
+
width: number;
|
|
223
|
+
height: number;
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
type ClaudeImageBlockProps = ClaudeImageBlockBase64 | ClaudeImageBlockUrl;
|
|
227
|
+
declare const ClaudeImageBlock: (props: ClaudeImageBlockProps) => Promise<JSX.Element>;
|
|
228
|
+
|
|
229
|
+
export { AIComponent, AINode, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, ClaudeImageBlock, ContentTypeImage, Context, type CostFn, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, FunctionChain, LogImplementation, NotAsyncGenerator, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, OpenAIVisionChatCompletion, ParseVariablesError, Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, SpanAttributes, SpanExporter, SpanProcessor, StreamChain, Trace, Tracer, type ValidAnthropicChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, createFunctionChain, createPrompt, createRenderContext, createStreamChain, evaluatePrompt, tokenCountForOpenAIMessage, tokenCountForOpenAIVisionMessage, tokenLimitForChatModel, tokenizer, tracing };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { R as RenderContext, L as LogImplementation, S as SpanProcessor, C as ContextValues, T as Tracer, a as ReadableSpan, b as SpanExporter, A as AIComponent, c as AINode, d as SpanAttributes, E as EvaluatorFn, P as PromptParsed, e as Prompt, N as NotAsyncGenerator, F as FunctionChain, f as StreamChain, g as EvaluatorResult, h as Context } from './
|
|
2
|
-
export { H as AIElement, j as AIFragment, n as AssistantMessage, B as BoundLogger, q as ChatCompletionError, r as ChatCompletionRequestPayloads, l as ChatCompletionRole, y as CombinedLogger, x as ConsoleLogger, z as Literal, s as LogChatCompletionRequest, t as LogChatCompletionResponse, u as LogLevel, v as Logger, w as NoopLogImplementation,
|
|
1
|
+
import { R as RenderContext, L as LogImplementation, S as SpanProcessor, C as ContextValues, T as Tracer, a as ReadableSpan, b as SpanExporter, A as AIComponent, c as AINode, d as SpanAttributes, E as EvaluatorFn, P as PromptParsed, e as Prompt, N as NotAsyncGenerator, F as FunctionChain, f as StreamChain, g as EvaluatorResult, h as Context, J as JSX } from './jsx-dev-runtime-zWb34twz.js';
|
|
2
|
+
export { H as AIElement, j as AIFragment, n as AssistantMessage, B as BoundLogger, q as ChatCompletionError, r as ChatCompletionRequestPayloads, l as ChatCompletionRole, y as CombinedLogger, x as ConsoleLogger, z as Literal, s as LogChatCompletionRequest, t as LogChatCompletionResponse, u as LogLevel, v as Logger, w as NoopLogImplementation, Z as OutputParser, K as PropsOfAIComponent, D as RenderResult, I as Renderable, o as RenderedConversationMessage, Q as Span, M as SpanContext, V as SpanEvent, O as SpanStatus, m as SystemMessage, X as TracingContext, W as TracingContextKey, Y as TracingContextManager, U as UserMessage, G as attachedContextSymbol, p as computeUsage, i as createAIElement, k as createContext } from './jsx-dev-runtime-zWb34twz.js';
|
|
3
3
|
import { ZodObject, ZodRawShape, ZodTypeAny, ZodString, z } from 'zod';
|
|
4
4
|
import { OpenAI } from 'openai';
|
|
5
5
|
export { OpenAI as OpenAIClient } from 'openai';
|
|
6
6
|
import { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam, ChatCompletionAssistantMessageParam, ChatCompletionCreateParams } from 'openai/resources';
|
|
7
7
|
import AnthropicClient from '@anthropic-ai/sdk';
|
|
8
8
|
export { default as AnthropicClient } from '@anthropic-ai/sdk';
|
|
9
|
+
import { ImageBlockParam } from '@anthropic-ai/sdk/resources';
|
|
9
10
|
export { countTokens as countAnthropicTokens } from '@anthropic-ai/tokenizer';
|
|
10
11
|
|
|
11
12
|
type CreateRenderContextOptions = {
|
|
@@ -178,7 +179,7 @@ declare function tokenLimitForChatModel(model: ValidOpenAIChatModel): number | u
|
|
|
178
179
|
declare function tokenCountForOpenAIMessage(message: OpenAIChatMessage): number;
|
|
179
180
|
declare function tokenCountForOpenAIVisionMessage(message: OpenAIChatMessage): number;
|
|
180
181
|
|
|
181
|
-
type AnthropicChatCompletionRequest = AnthropicClient.
|
|
182
|
+
type AnthropicChatCompletionRequest = AnthropicClient.Messages.MessageStreamParams;
|
|
182
183
|
declare module '@gammatech/aijsx' {
|
|
183
184
|
interface ChatCompletionRequestPayloads {
|
|
184
185
|
anthropic: AnthropicChatCompletionRequest;
|
|
@@ -188,7 +189,7 @@ declare module '@gammatech/aijsx' {
|
|
|
188
189
|
* The set of valid Claude models.
|
|
189
190
|
* @see https://docs.anthropic.com/claude/reference/selecting-a-model
|
|
190
191
|
*/
|
|
191
|
-
type ValidAnthropicChatModel = 'claude-instant-1.2' | 'claude-2.1';
|
|
192
|
+
type ValidAnthropicChatModel = 'claude-instant-1.2' | 'claude-2.1' | 'claude-3-opus-20240229' | 'claude-3-sonnet-20240229';
|
|
192
193
|
declare const AnthropicClientContext: Context<() => AnthropicClient>;
|
|
193
194
|
type AnthropicChatCompletionProps = {
|
|
194
195
|
model: ValidAnthropicChatModel;
|
|
@@ -207,4 +208,22 @@ type AnthropicChatCompletionProps = {
|
|
|
207
208
|
*/
|
|
208
209
|
declare function AnthropicChatCompletion(props: AnthropicChatCompletionProps, { render, logger, tracer, getContext }: RenderContext): AsyncGenerator<string, void, unknown>;
|
|
209
210
|
|
|
210
|
-
|
|
211
|
+
type ClaudeImageBlockBase64 = {
|
|
212
|
+
data: string;
|
|
213
|
+
dimensions?: {
|
|
214
|
+
width: number;
|
|
215
|
+
height: number;
|
|
216
|
+
};
|
|
217
|
+
mediaType: ImageBlockParam.Source['media_type'];
|
|
218
|
+
};
|
|
219
|
+
type ClaudeImageBlockUrl = {
|
|
220
|
+
url: string;
|
|
221
|
+
dimensions?: {
|
|
222
|
+
width: number;
|
|
223
|
+
height: number;
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
type ClaudeImageBlockProps = ClaudeImageBlockBase64 | ClaudeImageBlockUrl;
|
|
227
|
+
declare const ClaudeImageBlock: (props: ClaudeImageBlockProps) => Promise<JSX.Element>;
|
|
228
|
+
|
|
229
|
+
export { AIComponent, AINode, AISpanProcessor, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, ClaudeImageBlock, ContentTypeImage, Context, type CostFn, EnrichingSpanProcessor, EvaluatorFn, EvaluatorResult, FunctionChain, LogImplementation, NotAsyncGenerator, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, OpenAIVisionChatCompletion, ParseVariablesError, Prompt, PromptInvalidOutputError, PromptParsed, ReadableSpan, RenderContext, SpanAttributes, SpanExporter, SpanProcessor, StreamChain, Trace, Tracer, type ValidAnthropicChatModel, type ValidOpenAIChatModel, type ValidOpenAIVisionModel, createFunctionChain, createPrompt, createRenderContext, createStreamChain, evaluatePrompt, tokenCountForOpenAIMessage, tokenCountForOpenAIVisionMessage, tokenLimitForChatModel, tokenizer, tracing };
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,7 @@ __export(src_exports, {
|
|
|
37
37
|
AssistantMessage: () => AssistantMessage,
|
|
38
38
|
BoundLogger: () => BoundLogger,
|
|
39
39
|
ChatCompletionError: () => ChatCompletionError,
|
|
40
|
+
ClaudeImageBlock: () => ClaudeImageBlock,
|
|
40
41
|
CombinedLogger: () => CombinedLogger,
|
|
41
42
|
ConsoleLogger: () => ConsoleLogger,
|
|
42
43
|
ContentTypeImage: () => ContentTypeImage,
|
|
@@ -1097,6 +1098,9 @@ function parseXml(input) {
|
|
|
1097
1098
|
const attributeName = Object.keys(nodeObject)[1];
|
|
1098
1099
|
const childObjects = nodeObject[nodeName];
|
|
1099
1100
|
const attributes = Object.entries(nodeObject[attributeName] || {}).reduce((acc, [key, value]) => {
|
|
1101
|
+
if (!value) {
|
|
1102
|
+
return acc;
|
|
1103
|
+
}
|
|
1100
1104
|
try {
|
|
1101
1105
|
acc[key] = JSON.parse(value);
|
|
1102
1106
|
} catch (e) {
|
|
@@ -1114,6 +1118,9 @@ function parseXml(input) {
|
|
|
1114
1118
|
return constructNode(null, parsed[0]);
|
|
1115
1119
|
}
|
|
1116
1120
|
function escape(html) {
|
|
1121
|
+
if (!html) {
|
|
1122
|
+
return "";
|
|
1123
|
+
}
|
|
1117
1124
|
return html.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1118
1125
|
}
|
|
1119
1126
|
|
|
@@ -1760,10 +1767,10 @@ var OpenAIClientContext = createContext(() => {
|
|
|
1760
1767
|
});
|
|
1761
1768
|
function buildOpenAIMessages(childrenXml) {
|
|
1762
1769
|
const messages = [];
|
|
1763
|
-
const
|
|
1764
|
-
const parsed = parseXml(childrenXml).collapse(
|
|
1770
|
+
const chatMessageTags = ["UserMessage", "AssistantMessage", "SystemMessage"];
|
|
1771
|
+
const parsed = parseXml(childrenXml).collapse(chatMessageTags);
|
|
1765
1772
|
const topLevelValid = parsed.childNodes.every(
|
|
1766
|
-
(node) =>
|
|
1773
|
+
(node) => chatMessageTags.includes(node.nodeName)
|
|
1767
1774
|
);
|
|
1768
1775
|
if (!topLevelValid) {
|
|
1769
1776
|
throw new Error("Invalid top level chat message tags");
|
|
@@ -1901,15 +1908,15 @@ var ContentTypeImage = (_props) => {
|
|
|
1901
1908
|
};
|
|
1902
1909
|
function buildOpenAIVisionChatMessages(childrenXml) {
|
|
1903
1910
|
const messages = [];
|
|
1904
|
-
const
|
|
1911
|
+
const chatMessageTags = [
|
|
1905
1912
|
"UserMessage",
|
|
1906
1913
|
"AssistantMessage",
|
|
1907
1914
|
"SystemMessage",
|
|
1908
1915
|
"ContentTypeImage"
|
|
1909
1916
|
];
|
|
1910
|
-
const parsed = parseXml(childrenXml).collapse(
|
|
1917
|
+
const parsed = parseXml(childrenXml).collapse(chatMessageTags);
|
|
1911
1918
|
const topLevelValid = parsed.childNodes.every(
|
|
1912
|
-
(node) =>
|
|
1919
|
+
(node) => chatMessageTags.includes(node.nodeName)
|
|
1913
1920
|
);
|
|
1914
1921
|
if (!topLevelValid) {
|
|
1915
1922
|
throw new Error("Invalid top level chat message tags");
|
|
@@ -2123,9 +2130,15 @@ var AnthropicClientContext = createContext(
|
|
|
2123
2130
|
}
|
|
2124
2131
|
);
|
|
2125
2132
|
var defaultMaxTokens = 4096;
|
|
2126
|
-
|
|
2127
|
-
|
|
2133
|
+
function buildAnthropicMessages(childrenXml) {
|
|
2134
|
+
let system = "";
|
|
2128
2135
|
const messages = [];
|
|
2136
|
+
const chatMessageTags = [
|
|
2137
|
+
"UserMessage",
|
|
2138
|
+
"AssistantMessage",
|
|
2139
|
+
"SystemMessage",
|
|
2140
|
+
"ClaudeImageBlockParam"
|
|
2141
|
+
];
|
|
2129
2142
|
const parsed = parseXml(childrenXml).collapse(chatMessageTags);
|
|
2130
2143
|
const topLevelValid = parsed.childNodes.every(
|
|
2131
2144
|
(node) => chatMessageTags.includes(node.nodeName)
|
|
@@ -2133,37 +2146,52 @@ function buildChatMessages(childrenXml) {
|
|
|
2133
2146
|
if (!topLevelValid) {
|
|
2134
2147
|
throw new Error("Invalid top level chat message tags");
|
|
2135
2148
|
}
|
|
2149
|
+
const dimensions = /* @__PURE__ */ new WeakMap();
|
|
2136
2150
|
for (const node of parsed.childNodes) {
|
|
2137
2151
|
if (node.nodeName === "UserMessage") {
|
|
2138
|
-
|
|
2152
|
+
if (node.childNodes?.length === 1 && node.childNodes[0].nodeName === "#text") {
|
|
2153
|
+
messages.push({
|
|
2154
|
+
content: node.childNodes[0].value,
|
|
2155
|
+
role: "user"
|
|
2156
|
+
});
|
|
2157
|
+
continue;
|
|
2158
|
+
}
|
|
2159
|
+
const parts = node.childNodes.map((n) => {
|
|
2160
|
+
if (n.nodeName === "#text") {
|
|
2161
|
+
return {
|
|
2162
|
+
type: "text",
|
|
2163
|
+
text: n.value
|
|
2164
|
+
};
|
|
2165
|
+
} else if (n.nodeName === "ClaudeImageBlockParam") {
|
|
2166
|
+
const imagePart = {
|
|
2167
|
+
type: "image",
|
|
2168
|
+
source: {
|
|
2169
|
+
type: "base64",
|
|
2170
|
+
media_type: n.attributes.mediaType,
|
|
2171
|
+
data: n.attributes.data
|
|
2172
|
+
}
|
|
2173
|
+
};
|
|
2174
|
+
dimensions.set(imagePart, n.attributes.dimensions);
|
|
2175
|
+
return imagePart;
|
|
2176
|
+
}
|
|
2177
|
+
throw new Error(
|
|
2178
|
+
"Invalid ChatCompletionContentPart, expecting text or ContentTypeImage"
|
|
2179
|
+
);
|
|
2180
|
+
});
|
|
2139
2181
|
messages.push({
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
tokens: (0, import_tokenizer3.countTokens)(content)
|
|
2182
|
+
content: parts,
|
|
2183
|
+
role: "user"
|
|
2143
2184
|
});
|
|
2144
2185
|
} else if (node.nodeName === "AssistantMessage") {
|
|
2145
|
-
const content = `${import_sdk.default.AI_PROMPT} ${node.textContent}`;
|
|
2146
2186
|
messages.push({
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
tokens: (0, import_tokenizer3.countTokens)(content)
|
|
2187
|
+
content: node.textContent,
|
|
2188
|
+
role: "assistant"
|
|
2150
2189
|
});
|
|
2151
2190
|
} else if (node.nodeName === "SystemMessage") {
|
|
2152
|
-
|
|
2153
|
-
messages.push({
|
|
2154
|
-
role: "user",
|
|
2155
|
-
content: userContent,
|
|
2156
|
-
tokens: (0, import_tokenizer3.countTokens)(userContent)
|
|
2157
|
-
});
|
|
2158
|
-
const assistantContent = `${import_sdk.default.AI_PROMPT} Okay, I will do that.`;
|
|
2159
|
-
messages.push({
|
|
2160
|
-
role: "assistant",
|
|
2161
|
-
content: assistantContent,
|
|
2162
|
-
tokens: (0, import_tokenizer3.countTokens)(assistantContent)
|
|
2163
|
-
});
|
|
2191
|
+
system = node.textContent;
|
|
2164
2192
|
}
|
|
2165
2193
|
}
|
|
2166
|
-
return messages;
|
|
2194
|
+
return { messages, system, dimensions };
|
|
2167
2195
|
}
|
|
2168
2196
|
function AnthropicChatCompletion(props, { render, logger, tracer, getContext }) {
|
|
2169
2197
|
const startTime = performance.now();
|
|
@@ -2177,21 +2205,25 @@ function AnthropicChatCompletion(props, { render, logger, tracer, getContext })
|
|
|
2177
2205
|
"[AnthropicChatCompletion] must supply AnthropicClient via context"
|
|
2178
2206
|
);
|
|
2179
2207
|
}
|
|
2180
|
-
const
|
|
2208
|
+
const { system, messages } = buildAnthropicMessages(
|
|
2181
2209
|
await render(props.children, {
|
|
2182
|
-
preserveTags: true
|
|
2210
|
+
preserveTags: true,
|
|
2211
|
+
renderedProps: {
|
|
2212
|
+
ClaudeImageBlockParam: {
|
|
2213
|
+
data: true,
|
|
2214
|
+
dimensions: true,
|
|
2215
|
+
mediaType: true
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2183
2218
|
})
|
|
2184
2219
|
);
|
|
2185
|
-
const
|
|
2186
|
-
...inputMessages.map((message) => message.content),
|
|
2187
|
-
import_sdk.default.AI_PROMPT
|
|
2188
|
-
].join("");
|
|
2220
|
+
const inputMessages = getRenderedMessages(system, messages);
|
|
2189
2221
|
const anthropicCompletionRequest = {
|
|
2190
|
-
|
|
2191
|
-
|
|
2222
|
+
system,
|
|
2223
|
+
messages,
|
|
2224
|
+
max_tokens: props.maxTokens ?? defaultMaxTokens,
|
|
2192
2225
|
temperature: props.temperature,
|
|
2193
|
-
model: props.model
|
|
2194
|
-
stream: true
|
|
2226
|
+
model: props.model
|
|
2195
2227
|
};
|
|
2196
2228
|
const logRequestData = {
|
|
2197
2229
|
startTime,
|
|
@@ -2211,7 +2243,7 @@ function AnthropicChatCompletion(props, { render, logger, tracer, getContext })
|
|
|
2211
2243
|
});
|
|
2212
2244
|
let response;
|
|
2213
2245
|
try {
|
|
2214
|
-
response =
|
|
2246
|
+
response = client.messages.stream(anthropicCompletionRequest);
|
|
2215
2247
|
} catch (err) {
|
|
2216
2248
|
if (err instanceof import_sdk.default.APIError) {
|
|
2217
2249
|
throw new ChatCompletionError(
|
|
@@ -2224,29 +2256,50 @@ function AnthropicChatCompletion(props, { render, logger, tracer, getContext })
|
|
|
2224
2256
|
throw err;
|
|
2225
2257
|
}
|
|
2226
2258
|
let content = "";
|
|
2227
|
-
let
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2259
|
+
let outputUsage = 0;
|
|
2260
|
+
let inputUsage = 0;
|
|
2261
|
+
let finishReason = null;
|
|
2262
|
+
for await (const event of response) {
|
|
2263
|
+
if (event.type === "message_start") {
|
|
2264
|
+
inputUsage = event.message.usage?.input_tokens || 0;
|
|
2265
|
+
}
|
|
2266
|
+
if (event.type === "content_block_delta") {
|
|
2267
|
+
const chunk = event.delta.text;
|
|
2268
|
+
content += chunk;
|
|
2269
|
+
yield chunk;
|
|
2270
|
+
}
|
|
2271
|
+
if (event.type === "message_delta") {
|
|
2272
|
+
finishReason = event.delta.stop_reason;
|
|
2273
|
+
outputUsage = event.usage?.output_tokens;
|
|
2235
2274
|
}
|
|
2236
|
-
content += text;
|
|
2237
|
-
yield text;
|
|
2238
2275
|
}
|
|
2239
2276
|
const outputMessage = {
|
|
2240
2277
|
role: "assistant",
|
|
2241
2278
|
content,
|
|
2242
|
-
tokens:
|
|
2279
|
+
tokens: outputUsage
|
|
2243
2280
|
};
|
|
2244
|
-
const
|
|
2281
|
+
const userMessage = inputMessages.find(
|
|
2282
|
+
(m) => m.role === "user" && m.tokens === 0
|
|
2283
|
+
);
|
|
2284
|
+
const restMessages = inputMessages.filter(
|
|
2285
|
+
(m) => m.role !== "assistant" && m.tokens > 0
|
|
2286
|
+
);
|
|
2287
|
+
const restMessagesTokens = restMessages.reduce(
|
|
2288
|
+
(acc, m) => acc + m.tokens,
|
|
2289
|
+
0
|
|
2290
|
+
);
|
|
2291
|
+
if (userMessage && inputUsage) {
|
|
2292
|
+
userMessage.tokens = inputUsage - restMessagesTokens;
|
|
2293
|
+
}
|
|
2245
2294
|
const tokensUsed = computeUsage([...inputMessages, outputMessage]);
|
|
2246
2295
|
const responseData = {
|
|
2247
2296
|
...logRequestData,
|
|
2248
2297
|
finishReason,
|
|
2249
2298
|
latency: performance.now() - startTime,
|
|
2299
|
+
// NOTE(jordan) we dont REALLY need inputMessages, they are this kind of intermediary that we use
|
|
2300
|
+
// to store the token values for the messages, but we could easily just compute the tokensUsed and call
|
|
2301
|
+
// it a day
|
|
2302
|
+
inputMessages,
|
|
2250
2303
|
outputMessage,
|
|
2251
2304
|
tokensUsed
|
|
2252
2305
|
};
|
|
@@ -2259,6 +2312,82 @@ function AnthropicChatCompletion(props, { render, logger, tracer, getContext })
|
|
|
2259
2312
|
}
|
|
2260
2313
|
);
|
|
2261
2314
|
}
|
|
2315
|
+
function getRenderedMessages(system, messages) {
|
|
2316
|
+
const systemMessage = {
|
|
2317
|
+
role: "system",
|
|
2318
|
+
content: system,
|
|
2319
|
+
tokens: (0, import_tokenizer3.countTokens)(system)
|
|
2320
|
+
};
|
|
2321
|
+
const renderedMessages = messages.map((message) => {
|
|
2322
|
+
if (message.role === "user") {
|
|
2323
|
+
return {
|
|
2324
|
+
role: message.role,
|
|
2325
|
+
content: renderChatMessageContent2(message.content),
|
|
2326
|
+
// we keep user message tokens 0 and just let anthropic tell us
|
|
2327
|
+
tokens: 0
|
|
2328
|
+
};
|
|
2329
|
+
}
|
|
2330
|
+
return {
|
|
2331
|
+
role: message.role,
|
|
2332
|
+
content: renderChatMessageContent2(message.content),
|
|
2333
|
+
tokens: (0, import_tokenizer3.countTokens)(message.content)
|
|
2334
|
+
};
|
|
2335
|
+
});
|
|
2336
|
+
return [systemMessage, ...renderedMessages];
|
|
2337
|
+
}
|
|
2338
|
+
var renderChatMessageContent2 = (content) => {
|
|
2339
|
+
if (content == null) {
|
|
2340
|
+
return "";
|
|
2341
|
+
}
|
|
2342
|
+
if (typeof content === "string") {
|
|
2343
|
+
return content;
|
|
2344
|
+
}
|
|
2345
|
+
return content.map((part) => {
|
|
2346
|
+
if (typeof part === "string") {
|
|
2347
|
+
return part;
|
|
2348
|
+
} else if ("text" in part) {
|
|
2349
|
+
return part.text;
|
|
2350
|
+
} else if ("source" in part && typeof part.source === "object") {
|
|
2351
|
+
return `<ImageBlockParam data="base64..." />`;
|
|
2352
|
+
}
|
|
2353
|
+
throw new Error("Invalid ImageBlockParam type");
|
|
2354
|
+
}).join("\n\n");
|
|
2355
|
+
};
|
|
2356
|
+
|
|
2357
|
+
// src/lib/anthropic/ClaudeImageBlock.tsx
|
|
2358
|
+
var ClaudeImageBlockParam = (_props) => {
|
|
2359
|
+
return null;
|
|
2360
|
+
};
|
|
2361
|
+
async function fetchImageAndConvertToBase64(url) {
|
|
2362
|
+
const response = await fetch(url);
|
|
2363
|
+
const contentType = response.headers.get("content-type");
|
|
2364
|
+
const allowedTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"];
|
|
2365
|
+
if (!contentType || !allowedTypes.includes(contentType)) {
|
|
2366
|
+
throw new Error(`Unsupported media type: ${contentType}`);
|
|
2367
|
+
}
|
|
2368
|
+
const blob = await response.blob();
|
|
2369
|
+
const buffer = Buffer.from(await blob.arrayBuffer());
|
|
2370
|
+
const base64 = buffer.toString("base64");
|
|
2371
|
+
return {
|
|
2372
|
+
base64,
|
|
2373
|
+
mediaType: contentType
|
|
2374
|
+
};
|
|
2375
|
+
}
|
|
2376
|
+
var ClaudeImageBlock = async (props) => {
|
|
2377
|
+
if ("data" in props) {
|
|
2378
|
+
return /* @__PURE__ */ jsx(ClaudeImageBlockParam, { ...props });
|
|
2379
|
+
}
|
|
2380
|
+
const { dimensions, url } = props;
|
|
2381
|
+
const { base64, mediaType } = await fetchImageAndConvertToBase64(url);
|
|
2382
|
+
return /* @__PURE__ */ jsx(
|
|
2383
|
+
ClaudeImageBlockParam,
|
|
2384
|
+
{
|
|
2385
|
+
dimensions,
|
|
2386
|
+
mediaType,
|
|
2387
|
+
data: base64
|
|
2388
|
+
}
|
|
2389
|
+
);
|
|
2390
|
+
};
|
|
2262
2391
|
|
|
2263
2392
|
// src/lib/anthropic/index.ts
|
|
2264
2393
|
var import_sdk2 = __toESM(require("@anthropic-ai/sdk"));
|
|
@@ -2273,6 +2402,7 @@ var import_tokenizer4 = require("@anthropic-ai/tokenizer");
|
|
|
2273
2402
|
AssistantMessage,
|
|
2274
2403
|
BoundLogger,
|
|
2275
2404
|
ChatCompletionError,
|
|
2405
|
+
ClaudeImageBlock,
|
|
2276
2406
|
CombinedLogger,
|
|
2277
2407
|
ConsoleLogger,
|
|
2278
2408
|
ContentTypeImage,
|
package/dist/index.mjs
CHANGED
|
@@ -1007,6 +1007,9 @@ function parseXml(input) {
|
|
|
1007
1007
|
const attributeName = Object.keys(nodeObject)[1];
|
|
1008
1008
|
const childObjects = nodeObject[nodeName];
|
|
1009
1009
|
const attributes = Object.entries(nodeObject[attributeName] || {}).reduce((acc, [key, value]) => {
|
|
1010
|
+
if (!value) {
|
|
1011
|
+
return acc;
|
|
1012
|
+
}
|
|
1010
1013
|
try {
|
|
1011
1014
|
acc[key] = JSON.parse(value);
|
|
1012
1015
|
} catch (e) {
|
|
@@ -1024,6 +1027,9 @@ function parseXml(input) {
|
|
|
1024
1027
|
return constructNode(null, parsed[0]);
|
|
1025
1028
|
}
|
|
1026
1029
|
function escape(html) {
|
|
1030
|
+
if (!html) {
|
|
1031
|
+
return "";
|
|
1032
|
+
}
|
|
1027
1033
|
return html.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1028
1034
|
}
|
|
1029
1035
|
|
|
@@ -1663,10 +1669,10 @@ var OpenAIClientContext = createContext(() => {
|
|
|
1663
1669
|
});
|
|
1664
1670
|
function buildOpenAIMessages(childrenXml) {
|
|
1665
1671
|
const messages = [];
|
|
1666
|
-
const
|
|
1667
|
-
const parsed = parseXml(childrenXml).collapse(
|
|
1672
|
+
const chatMessageTags = ["UserMessage", "AssistantMessage", "SystemMessage"];
|
|
1673
|
+
const parsed = parseXml(childrenXml).collapse(chatMessageTags);
|
|
1668
1674
|
const topLevelValid = parsed.childNodes.every(
|
|
1669
|
-
(node) =>
|
|
1675
|
+
(node) => chatMessageTags.includes(node.nodeName)
|
|
1670
1676
|
);
|
|
1671
1677
|
if (!topLevelValid) {
|
|
1672
1678
|
throw new Error("Invalid top level chat message tags");
|
|
@@ -1804,15 +1810,15 @@ var ContentTypeImage = (_props) => {
|
|
|
1804
1810
|
};
|
|
1805
1811
|
function buildOpenAIVisionChatMessages(childrenXml) {
|
|
1806
1812
|
const messages = [];
|
|
1807
|
-
const
|
|
1813
|
+
const chatMessageTags = [
|
|
1808
1814
|
"UserMessage",
|
|
1809
1815
|
"AssistantMessage",
|
|
1810
1816
|
"SystemMessage",
|
|
1811
1817
|
"ContentTypeImage"
|
|
1812
1818
|
];
|
|
1813
|
-
const parsed = parseXml(childrenXml).collapse(
|
|
1819
|
+
const parsed = parseXml(childrenXml).collapse(chatMessageTags);
|
|
1814
1820
|
const topLevelValid = parsed.childNodes.every(
|
|
1815
|
-
(node) =>
|
|
1821
|
+
(node) => chatMessageTags.includes(node.nodeName)
|
|
1816
1822
|
);
|
|
1817
1823
|
if (!topLevelValid) {
|
|
1818
1824
|
throw new Error("Invalid top level chat message tags");
|
|
@@ -2026,9 +2032,15 @@ var AnthropicClientContext = createContext(
|
|
|
2026
2032
|
}
|
|
2027
2033
|
);
|
|
2028
2034
|
var defaultMaxTokens = 4096;
|
|
2029
|
-
|
|
2030
|
-
|
|
2035
|
+
function buildAnthropicMessages(childrenXml) {
|
|
2036
|
+
let system = "";
|
|
2031
2037
|
const messages = [];
|
|
2038
|
+
const chatMessageTags = [
|
|
2039
|
+
"UserMessage",
|
|
2040
|
+
"AssistantMessage",
|
|
2041
|
+
"SystemMessage",
|
|
2042
|
+
"ClaudeImageBlockParam"
|
|
2043
|
+
];
|
|
2032
2044
|
const parsed = parseXml(childrenXml).collapse(chatMessageTags);
|
|
2033
2045
|
const topLevelValid = parsed.childNodes.every(
|
|
2034
2046
|
(node) => chatMessageTags.includes(node.nodeName)
|
|
@@ -2036,37 +2048,52 @@ function buildChatMessages(childrenXml) {
|
|
|
2036
2048
|
if (!topLevelValid) {
|
|
2037
2049
|
throw new Error("Invalid top level chat message tags");
|
|
2038
2050
|
}
|
|
2051
|
+
const dimensions = /* @__PURE__ */ new WeakMap();
|
|
2039
2052
|
for (const node of parsed.childNodes) {
|
|
2040
2053
|
if (node.nodeName === "UserMessage") {
|
|
2041
|
-
|
|
2054
|
+
if (node.childNodes?.length === 1 && node.childNodes[0].nodeName === "#text") {
|
|
2055
|
+
messages.push({
|
|
2056
|
+
content: node.childNodes[0].value,
|
|
2057
|
+
role: "user"
|
|
2058
|
+
});
|
|
2059
|
+
continue;
|
|
2060
|
+
}
|
|
2061
|
+
const parts = node.childNodes.map((n) => {
|
|
2062
|
+
if (n.nodeName === "#text") {
|
|
2063
|
+
return {
|
|
2064
|
+
type: "text",
|
|
2065
|
+
text: n.value
|
|
2066
|
+
};
|
|
2067
|
+
} else if (n.nodeName === "ClaudeImageBlockParam") {
|
|
2068
|
+
const imagePart = {
|
|
2069
|
+
type: "image",
|
|
2070
|
+
source: {
|
|
2071
|
+
type: "base64",
|
|
2072
|
+
media_type: n.attributes.mediaType,
|
|
2073
|
+
data: n.attributes.data
|
|
2074
|
+
}
|
|
2075
|
+
};
|
|
2076
|
+
dimensions.set(imagePart, n.attributes.dimensions);
|
|
2077
|
+
return imagePart;
|
|
2078
|
+
}
|
|
2079
|
+
throw new Error(
|
|
2080
|
+
"Invalid ChatCompletionContentPart, expecting text or ContentTypeImage"
|
|
2081
|
+
);
|
|
2082
|
+
});
|
|
2042
2083
|
messages.push({
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
tokens: countTokens(content)
|
|
2084
|
+
content: parts,
|
|
2085
|
+
role: "user"
|
|
2046
2086
|
});
|
|
2047
2087
|
} else if (node.nodeName === "AssistantMessage") {
|
|
2048
|
-
const content = `${AnthropicClient.AI_PROMPT} ${node.textContent}`;
|
|
2049
2088
|
messages.push({
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
tokens: countTokens(content)
|
|
2089
|
+
content: node.textContent,
|
|
2090
|
+
role: "assistant"
|
|
2053
2091
|
});
|
|
2054
2092
|
} else if (node.nodeName === "SystemMessage") {
|
|
2055
|
-
|
|
2056
|
-
messages.push({
|
|
2057
|
-
role: "user",
|
|
2058
|
-
content: userContent,
|
|
2059
|
-
tokens: countTokens(userContent)
|
|
2060
|
-
});
|
|
2061
|
-
const assistantContent = `${AnthropicClient.AI_PROMPT} Okay, I will do that.`;
|
|
2062
|
-
messages.push({
|
|
2063
|
-
role: "assistant",
|
|
2064
|
-
content: assistantContent,
|
|
2065
|
-
tokens: countTokens(assistantContent)
|
|
2066
|
-
});
|
|
2093
|
+
system = node.textContent;
|
|
2067
2094
|
}
|
|
2068
2095
|
}
|
|
2069
|
-
return messages;
|
|
2096
|
+
return { messages, system, dimensions };
|
|
2070
2097
|
}
|
|
2071
2098
|
function AnthropicChatCompletion(props, { render, logger, tracer, getContext }) {
|
|
2072
2099
|
const startTime = performance.now();
|
|
@@ -2080,21 +2107,25 @@ function AnthropicChatCompletion(props, { render, logger, tracer, getContext })
|
|
|
2080
2107
|
"[AnthropicChatCompletion] must supply AnthropicClient via context"
|
|
2081
2108
|
);
|
|
2082
2109
|
}
|
|
2083
|
-
const
|
|
2110
|
+
const { system, messages } = buildAnthropicMessages(
|
|
2084
2111
|
await render(props.children, {
|
|
2085
|
-
preserveTags: true
|
|
2112
|
+
preserveTags: true,
|
|
2113
|
+
renderedProps: {
|
|
2114
|
+
ClaudeImageBlockParam: {
|
|
2115
|
+
data: true,
|
|
2116
|
+
dimensions: true,
|
|
2117
|
+
mediaType: true
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2086
2120
|
})
|
|
2087
2121
|
);
|
|
2088
|
-
const
|
|
2089
|
-
...inputMessages.map((message) => message.content),
|
|
2090
|
-
AnthropicClient.AI_PROMPT
|
|
2091
|
-
].join("");
|
|
2122
|
+
const inputMessages = getRenderedMessages(system, messages);
|
|
2092
2123
|
const anthropicCompletionRequest = {
|
|
2093
|
-
|
|
2094
|
-
|
|
2124
|
+
system,
|
|
2125
|
+
messages,
|
|
2126
|
+
max_tokens: props.maxTokens ?? defaultMaxTokens,
|
|
2095
2127
|
temperature: props.temperature,
|
|
2096
|
-
model: props.model
|
|
2097
|
-
stream: true
|
|
2128
|
+
model: props.model
|
|
2098
2129
|
};
|
|
2099
2130
|
const logRequestData = {
|
|
2100
2131
|
startTime,
|
|
@@ -2114,7 +2145,7 @@ function AnthropicChatCompletion(props, { render, logger, tracer, getContext })
|
|
|
2114
2145
|
});
|
|
2115
2146
|
let response;
|
|
2116
2147
|
try {
|
|
2117
|
-
response =
|
|
2148
|
+
response = client.messages.stream(anthropicCompletionRequest);
|
|
2118
2149
|
} catch (err) {
|
|
2119
2150
|
if (err instanceof AnthropicClient.APIError) {
|
|
2120
2151
|
throw new ChatCompletionError(
|
|
@@ -2127,29 +2158,50 @@ function AnthropicChatCompletion(props, { render, logger, tracer, getContext })
|
|
|
2127
2158
|
throw err;
|
|
2128
2159
|
}
|
|
2129
2160
|
let content = "";
|
|
2130
|
-
let
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2161
|
+
let outputUsage = 0;
|
|
2162
|
+
let inputUsage = 0;
|
|
2163
|
+
let finishReason = null;
|
|
2164
|
+
for await (const event of response) {
|
|
2165
|
+
if (event.type === "message_start") {
|
|
2166
|
+
inputUsage = event.message.usage?.input_tokens || 0;
|
|
2167
|
+
}
|
|
2168
|
+
if (event.type === "content_block_delta") {
|
|
2169
|
+
const chunk = event.delta.text;
|
|
2170
|
+
content += chunk;
|
|
2171
|
+
yield chunk;
|
|
2172
|
+
}
|
|
2173
|
+
if (event.type === "message_delta") {
|
|
2174
|
+
finishReason = event.delta.stop_reason;
|
|
2175
|
+
outputUsage = event.usage?.output_tokens;
|
|
2138
2176
|
}
|
|
2139
|
-
content += text;
|
|
2140
|
-
yield text;
|
|
2141
2177
|
}
|
|
2142
2178
|
const outputMessage = {
|
|
2143
2179
|
role: "assistant",
|
|
2144
2180
|
content,
|
|
2145
|
-
tokens:
|
|
2181
|
+
tokens: outputUsage
|
|
2146
2182
|
};
|
|
2147
|
-
const
|
|
2183
|
+
const userMessage = inputMessages.find(
|
|
2184
|
+
(m) => m.role === "user" && m.tokens === 0
|
|
2185
|
+
);
|
|
2186
|
+
const restMessages = inputMessages.filter(
|
|
2187
|
+
(m) => m.role !== "assistant" && m.tokens > 0
|
|
2188
|
+
);
|
|
2189
|
+
const restMessagesTokens = restMessages.reduce(
|
|
2190
|
+
(acc, m) => acc + m.tokens,
|
|
2191
|
+
0
|
|
2192
|
+
);
|
|
2193
|
+
if (userMessage && inputUsage) {
|
|
2194
|
+
userMessage.tokens = inputUsage - restMessagesTokens;
|
|
2195
|
+
}
|
|
2148
2196
|
const tokensUsed = computeUsage([...inputMessages, outputMessage]);
|
|
2149
2197
|
const responseData = {
|
|
2150
2198
|
...logRequestData,
|
|
2151
2199
|
finishReason,
|
|
2152
2200
|
latency: performance.now() - startTime,
|
|
2201
|
+
// NOTE(jordan) we dont REALLY need inputMessages, they are this kind of intermediary that we use
|
|
2202
|
+
// to store the token values for the messages, but we could easily just compute the tokensUsed and call
|
|
2203
|
+
// it a day
|
|
2204
|
+
inputMessages,
|
|
2153
2205
|
outputMessage,
|
|
2154
2206
|
tokensUsed
|
|
2155
2207
|
};
|
|
@@ -2162,6 +2214,82 @@ function AnthropicChatCompletion(props, { render, logger, tracer, getContext })
|
|
|
2162
2214
|
}
|
|
2163
2215
|
);
|
|
2164
2216
|
}
|
|
2217
|
+
function getRenderedMessages(system, messages) {
|
|
2218
|
+
const systemMessage = {
|
|
2219
|
+
role: "system",
|
|
2220
|
+
content: system,
|
|
2221
|
+
tokens: countTokens(system)
|
|
2222
|
+
};
|
|
2223
|
+
const renderedMessages = messages.map((message) => {
|
|
2224
|
+
if (message.role === "user") {
|
|
2225
|
+
return {
|
|
2226
|
+
role: message.role,
|
|
2227
|
+
content: renderChatMessageContent2(message.content),
|
|
2228
|
+
// we keep user message tokens 0 and just let anthropic tell us
|
|
2229
|
+
tokens: 0
|
|
2230
|
+
};
|
|
2231
|
+
}
|
|
2232
|
+
return {
|
|
2233
|
+
role: message.role,
|
|
2234
|
+
content: renderChatMessageContent2(message.content),
|
|
2235
|
+
tokens: countTokens(message.content)
|
|
2236
|
+
};
|
|
2237
|
+
});
|
|
2238
|
+
return [systemMessage, ...renderedMessages];
|
|
2239
|
+
}
|
|
2240
|
+
var renderChatMessageContent2 = (content) => {
|
|
2241
|
+
if (content == null) {
|
|
2242
|
+
return "";
|
|
2243
|
+
}
|
|
2244
|
+
if (typeof content === "string") {
|
|
2245
|
+
return content;
|
|
2246
|
+
}
|
|
2247
|
+
return content.map((part) => {
|
|
2248
|
+
if (typeof part === "string") {
|
|
2249
|
+
return part;
|
|
2250
|
+
} else if ("text" in part) {
|
|
2251
|
+
return part.text;
|
|
2252
|
+
} else if ("source" in part && typeof part.source === "object") {
|
|
2253
|
+
return `<ImageBlockParam data="base64..." />`;
|
|
2254
|
+
}
|
|
2255
|
+
throw new Error("Invalid ImageBlockParam type");
|
|
2256
|
+
}).join("\n\n");
|
|
2257
|
+
};
|
|
2258
|
+
|
|
2259
|
+
// src/lib/anthropic/ClaudeImageBlock.tsx
|
|
2260
|
+
var ClaudeImageBlockParam = (_props) => {
|
|
2261
|
+
return null;
|
|
2262
|
+
};
|
|
2263
|
+
async function fetchImageAndConvertToBase64(url) {
|
|
2264
|
+
const response = await fetch(url);
|
|
2265
|
+
const contentType = response.headers.get("content-type");
|
|
2266
|
+
const allowedTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"];
|
|
2267
|
+
if (!contentType || !allowedTypes.includes(contentType)) {
|
|
2268
|
+
throw new Error(`Unsupported media type: ${contentType}`);
|
|
2269
|
+
}
|
|
2270
|
+
const blob = await response.blob();
|
|
2271
|
+
const buffer = Buffer.from(await blob.arrayBuffer());
|
|
2272
|
+
const base64 = buffer.toString("base64");
|
|
2273
|
+
return {
|
|
2274
|
+
base64,
|
|
2275
|
+
mediaType: contentType
|
|
2276
|
+
};
|
|
2277
|
+
}
|
|
2278
|
+
var ClaudeImageBlock = async (props) => {
|
|
2279
|
+
if ("data" in props) {
|
|
2280
|
+
return /* @__PURE__ */ jsx(ClaudeImageBlockParam, { ...props });
|
|
2281
|
+
}
|
|
2282
|
+
const { dimensions, url } = props;
|
|
2283
|
+
const { base64, mediaType } = await fetchImageAndConvertToBase64(url);
|
|
2284
|
+
return /* @__PURE__ */ jsx(
|
|
2285
|
+
ClaudeImageBlockParam,
|
|
2286
|
+
{
|
|
2287
|
+
dimensions,
|
|
2288
|
+
mediaType,
|
|
2289
|
+
data: base64
|
|
2290
|
+
}
|
|
2291
|
+
);
|
|
2292
|
+
};
|
|
2165
2293
|
|
|
2166
2294
|
// src/lib/anthropic/index.ts
|
|
2167
2295
|
import AnthropicClient2 from "@anthropic-ai/sdk";
|
|
@@ -2175,6 +2303,7 @@ export {
|
|
|
2175
2303
|
AssistantMessage,
|
|
2176
2304
|
BoundLogger,
|
|
2177
2305
|
ChatCompletionError,
|
|
2306
|
+
ClaudeImageBlock,
|
|
2178
2307
|
CombinedLogger,
|
|
2179
2308
|
ConsoleLogger,
|
|
2180
2309
|
ContentTypeImage,
|
|
@@ -223,7 +223,7 @@ interface LogChatCompletionRequest<R extends Record<string, any> = ChatCompletio
|
|
|
223
223
|
interface LogChatCompletionResponse<R extends Record<string, any> = ChatCompletionRequestPayloads[keyof ChatCompletionRequestPayloads]> extends LogChatCompletionRequest<R> {
|
|
224
224
|
latency: number;
|
|
225
225
|
outputMessage: RenderedConversationMessage;
|
|
226
|
-
finishReason: string;
|
|
226
|
+
finishReason: string | null;
|
|
227
227
|
tokensUsed: {
|
|
228
228
|
prompt: number;
|
|
229
229
|
completion: number;
|
|
@@ -318,4 +318,30 @@ declare function AIFragment({ children }: {
|
|
|
318
318
|
children: AINode;
|
|
319
319
|
}): Renderable;
|
|
320
320
|
|
|
321
|
-
|
|
321
|
+
/**
|
|
322
|
+
* The is used as an import source for ts/js files as the JSX transpile functinos
|
|
323
|
+
*/
|
|
324
|
+
|
|
325
|
+
/** @hidden */
|
|
326
|
+
declare namespace JSX {
|
|
327
|
+
type ElementType = AIComponent<any>;
|
|
328
|
+
interface Element extends AIElement<any> {
|
|
329
|
+
}
|
|
330
|
+
interface IntrinsicElements {
|
|
331
|
+
}
|
|
332
|
+
interface ElementChildrenAttribute {
|
|
333
|
+
children: {};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/** @hidden */
|
|
337
|
+
declare function jsx(type: any, config: any, maybeKey?: any): AIElement<{
|
|
338
|
+
children: any[];
|
|
339
|
+
}>;
|
|
340
|
+
/** @hidden */
|
|
341
|
+
declare const jsxDEV: typeof jsx;
|
|
342
|
+
/** @hidden */
|
|
343
|
+
declare const jsxs: typeof jsx;
|
|
344
|
+
/** @hidden */
|
|
345
|
+
declare const Fragment: typeof AIFragment;
|
|
346
|
+
|
|
347
|
+
export { jsxDEV as $, type AIComponent as A, BoundLogger as B, type ContextValues as C, type RenderResult as D, type EvaluatorFn as E, type FunctionChain as F, attachedContextSymbol as G, type AIElement as H, type Renderable as I, JSX as J, type PropsOfAIComponent as K, LogImplementation as L, type SpanContext as M, type NotAsyncGenerator as N, type SpanStatus as O, type PromptParsed as P, type Span as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, UserMessage as U, type SpanEvent as V, type TracingContextKey as W, type TracingContext as X, type TracingContextManager as Y, type OutputParser as Z, jsx as _, type ReadableSpan as a, jsxs as a0, Fragment as a1, type SpanExporter as b, type AINode as c, type SpanAttributes as d, type Prompt as e, type StreamChain as f, type EvaluatorResult as g, type Context as h, createAIElement as i, AIFragment as j, createContext as k, type ChatCompletionRole as l, SystemMessage as m, AssistantMessage as n, type RenderedConversationMessage as o, computeUsage as p, ChatCompletionError as q, type ChatCompletionRequestPayloads as r, type LogChatCompletionRequest as s, type LogChatCompletionResponse as t, type LogLevel as u, type Logger as v, NoopLogImplementation as w, ConsoleLogger as x, CombinedLogger as y, type Literal as z };
|
|
@@ -223,7 +223,7 @@ interface LogChatCompletionRequest<R extends Record<string, any> = ChatCompletio
|
|
|
223
223
|
interface LogChatCompletionResponse<R extends Record<string, any> = ChatCompletionRequestPayloads[keyof ChatCompletionRequestPayloads]> extends LogChatCompletionRequest<R> {
|
|
224
224
|
latency: number;
|
|
225
225
|
outputMessage: RenderedConversationMessage;
|
|
226
|
-
finishReason: string;
|
|
226
|
+
finishReason: string | null;
|
|
227
227
|
tokensUsed: {
|
|
228
228
|
prompt: number;
|
|
229
229
|
completion: number;
|
|
@@ -318,4 +318,30 @@ declare function AIFragment({ children }: {
|
|
|
318
318
|
children: AINode;
|
|
319
319
|
}): Renderable;
|
|
320
320
|
|
|
321
|
-
|
|
321
|
+
/**
|
|
322
|
+
* The is used as an import source for ts/js files as the JSX transpile functinos
|
|
323
|
+
*/
|
|
324
|
+
|
|
325
|
+
/** @hidden */
|
|
326
|
+
declare namespace JSX {
|
|
327
|
+
type ElementType = AIComponent<any>;
|
|
328
|
+
interface Element extends AIElement<any> {
|
|
329
|
+
}
|
|
330
|
+
interface IntrinsicElements {
|
|
331
|
+
}
|
|
332
|
+
interface ElementChildrenAttribute {
|
|
333
|
+
children: {};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/** @hidden */
|
|
337
|
+
declare function jsx(type: any, config: any, maybeKey?: any): AIElement<{
|
|
338
|
+
children: any[];
|
|
339
|
+
}>;
|
|
340
|
+
/** @hidden */
|
|
341
|
+
declare const jsxDEV: typeof jsx;
|
|
342
|
+
/** @hidden */
|
|
343
|
+
declare const jsxs: typeof jsx;
|
|
344
|
+
/** @hidden */
|
|
345
|
+
declare const Fragment: typeof AIFragment;
|
|
346
|
+
|
|
347
|
+
export { jsxDEV as $, type AIComponent as A, BoundLogger as B, type ContextValues as C, type RenderResult as D, type EvaluatorFn as E, type FunctionChain as F, attachedContextSymbol as G, type AIElement as H, type Renderable as I, JSX as J, type PropsOfAIComponent as K, LogImplementation as L, type SpanContext as M, type NotAsyncGenerator as N, type SpanStatus as O, type PromptParsed as P, type Span as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, UserMessage as U, type SpanEvent as V, type TracingContextKey as W, type TracingContext as X, type TracingContextManager as Y, type OutputParser as Z, jsx as _, type ReadableSpan as a, jsxs as a0, Fragment as a1, type SpanExporter as b, type AINode as c, type SpanAttributes as d, type Prompt as e, type StreamChain as f, type EvaluatorResult as g, type Context as h, createAIElement as i, AIFragment as j, createContext as k, type ChatCompletionRole as l, SystemMessage as m, AssistantMessage as n, type RenderedConversationMessage as o, computeUsage as p, ChatCompletionError as q, type ChatCompletionRequestPayloads as r, type LogChatCompletionRequest as s, type LogChatCompletionResponse as t, type LogLevel as u, type Logger as v, NoopLogImplementation as w, ConsoleLogger as x, CombinedLogger as y, type Literal as z };
|
package/dist/jsx-runtime.d.mts
CHANGED
|
@@ -1,30 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
export { a1 as Fragment, J as JSX, _ as jsx, $ as jsxDEV, a0 as jsxs } from './jsx-dev-runtime-zWb34twz.mjs';
|
|
2
2
|
import 'zod';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The is used as an import source for ts/js files as the JSX transpile functinos
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/** @hidden */
|
|
9
|
-
declare namespace JSX {
|
|
10
|
-
type ElementType = AIComponent<any>;
|
|
11
|
-
interface Element extends AIElement<any> {
|
|
12
|
-
}
|
|
13
|
-
interface IntrinsicElements {
|
|
14
|
-
}
|
|
15
|
-
interface ElementChildrenAttribute {
|
|
16
|
-
children: {};
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
/** @hidden */
|
|
20
|
-
declare function jsx(type: any, config: any, maybeKey?: any): AIElement<{
|
|
21
|
-
children: any[];
|
|
22
|
-
}>;
|
|
23
|
-
/** @hidden */
|
|
24
|
-
declare const jsxDEV: typeof jsx;
|
|
25
|
-
/** @hidden */
|
|
26
|
-
declare const jsxs: typeof jsx;
|
|
27
|
-
/** @hidden */
|
|
28
|
-
declare const Fragment: typeof AIFragment;
|
|
29
|
-
|
|
30
|
-
export { Fragment, JSX, jsx, jsxDEV, jsxs };
|
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -1,30 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
export { a1 as Fragment, J as JSX, _ as jsx, $ as jsxDEV, a0 as jsxs } from './jsx-dev-runtime-zWb34twz.js';
|
|
2
2
|
import 'zod';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The is used as an import source for ts/js files as the JSX transpile functinos
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/** @hidden */
|
|
9
|
-
declare namespace JSX {
|
|
10
|
-
type ElementType = AIComponent<any>;
|
|
11
|
-
interface Element extends AIElement<any> {
|
|
12
|
-
}
|
|
13
|
-
interface IntrinsicElements {
|
|
14
|
-
}
|
|
15
|
-
interface ElementChildrenAttribute {
|
|
16
|
-
children: {};
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
/** @hidden */
|
|
20
|
-
declare function jsx(type: any, config: any, maybeKey?: any): AIElement<{
|
|
21
|
-
children: any[];
|
|
22
|
-
}>;
|
|
23
|
-
/** @hidden */
|
|
24
|
-
declare const jsxDEV: typeof jsx;
|
|
25
|
-
/** @hidden */
|
|
26
|
-
declare const jsxs: typeof jsx;
|
|
27
|
-
/** @hidden */
|
|
28
|
-
declare const Fragment: typeof AIFragment;
|
|
29
|
-
|
|
30
|
-
export { Fragment, JSX, jsx, jsxDEV, jsxs };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gammatech/aijsx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-dev.2024-03-11",
|
|
4
4
|
"description": "Rewrite of aijsx",
|
|
5
5
|
"author": "Jordan Garcia",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"check-types": "tsc --skipLibCheck --noEmit"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@anthropic-ai/sdk": "
|
|
21
|
+
"@anthropic-ai/sdk": "0.17.1",
|
|
22
22
|
"@anthropic-ai/tokenizer": "^0.0.4",
|
|
23
23
|
"fast-xml-parser": "^4.3.4",
|
|
24
24
|
"js-tiktoken": "^1.0.8",
|