@gammatech/aijsx 0.1.2 → 0.2.0-vision.2
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/{createElement-Q_LxUYf8.d.mts → createElement-y5NHsp6D.d.mts} +3 -3
- package/dist/{createElement-Q_LxUYf8.d.ts → createElement-y5NHsp6D.d.ts} +3 -3
- package/dist/index.d.mts +15 -5
- package/dist/index.d.ts +15 -5
- package/dist/index.js +93 -23
- package/dist/index.mjs +91 -22
- package/dist/jsx-dev-runtime.d.mts +1 -1
- package/dist/jsx-dev-runtime.d.ts +1 -1
- package/dist/jsx-runtime.d.mts +1 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/package.json +1 -2
|
@@ -112,8 +112,8 @@ declare class CombinedLogger extends LogImplementation {
|
|
|
112
112
|
private readonly loggers;
|
|
113
113
|
constructor(loggers: LogImplementation[]);
|
|
114
114
|
log(...args: Parameters<LogImplementation['log']>): void;
|
|
115
|
-
chatCompletionRequest<
|
|
116
|
-
chatCompletionResponse<
|
|
115
|
+
chatCompletionRequest<_K extends keyof ChatCompletionRequestPayloads>(...args: Parameters<LogImplementation['chatCompletionRequest']>): void;
|
|
116
|
+
chatCompletionResponse<_K extends keyof ChatCompletionRequestPayloads>(...args: Parameters<LogImplementation['chatCompletionResponse']>): void;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
type ChatCompletionRole = 'user' | 'system' | 'assistant';
|
|
@@ -156,4 +156,4 @@ declare function AIFragment({ children }: {
|
|
|
156
156
|
children: AINode;
|
|
157
157
|
}): Renderable;
|
|
158
158
|
|
|
159
|
-
export { type
|
|
159
|
+
export { type AIComponent as A, BoundLogger as B, type Context as C, LogImplementation as L, NoopLogImplementation as N, type PropsOfAIComponent as P, type RenderContext as R, SystemMessage as S, UserMessage as U, type AINode as a, type AIElement as b, createAIElement as c, AIFragment as d, LoggerContext as e, createContext as f, AssistantMessage as g, type ConversationMessage as h, type RenderedConversationMessage as i, childrenToConversationMessage as j, computeUsage as k, ChatCompletionError as l, type ChatCompletionRequestPayloads as m, type LogChatCompletionRequest as n, type LogChatCompletionResponse as o, type LogLevel as p, type Logger as q, ConsoleLogger as r, CombinedLogger as s, type Literal as t, type RenderableStream as u, type RenderResult as v, attachedContextSymbol as w, type Renderable as x };
|
|
@@ -112,8 +112,8 @@ declare class CombinedLogger extends LogImplementation {
|
|
|
112
112
|
private readonly loggers;
|
|
113
113
|
constructor(loggers: LogImplementation[]);
|
|
114
114
|
log(...args: Parameters<LogImplementation['log']>): void;
|
|
115
|
-
chatCompletionRequest<
|
|
116
|
-
chatCompletionResponse<
|
|
115
|
+
chatCompletionRequest<_K extends keyof ChatCompletionRequestPayloads>(...args: Parameters<LogImplementation['chatCompletionRequest']>): void;
|
|
116
|
+
chatCompletionResponse<_K extends keyof ChatCompletionRequestPayloads>(...args: Parameters<LogImplementation['chatCompletionResponse']>): void;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
type ChatCompletionRole = 'user' | 'system' | 'assistant';
|
|
@@ -156,4 +156,4 @@ declare function AIFragment({ children }: {
|
|
|
156
156
|
children: AINode;
|
|
157
157
|
}): Renderable;
|
|
158
158
|
|
|
159
|
-
export { type
|
|
159
|
+
export { type AIComponent as A, BoundLogger as B, type Context as C, LogImplementation as L, NoopLogImplementation as N, type PropsOfAIComponent as P, type RenderContext as R, SystemMessage as S, UserMessage as U, type AINode as a, type AIElement as b, createAIElement as c, AIFragment as d, LoggerContext as e, createContext as f, AssistantMessage as g, type ConversationMessage as h, type RenderedConversationMessage as i, childrenToConversationMessage as j, computeUsage as k, ChatCompletionError as l, type ChatCompletionRequestPayloads as m, type LogChatCompletionRequest as n, type LogChatCompletionResponse as o, type LogLevel as p, type Logger as q, ConsoleLogger as r, CombinedLogger as s, type Literal as t, type RenderableStream as u, type RenderResult as v, attachedContextSymbol as w, type Renderable as x };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { L as LogImplementation, R as RenderContext, C as Context,
|
|
2
|
-
export {
|
|
1
|
+
import { L as LogImplementation, R as RenderContext, A as AIComponent, C as Context, a as AINode, b as AIElement } from './createElement-y5NHsp6D.mjs';
|
|
2
|
+
export { d as AIFragment, g as AssistantMessage, B as BoundLogger, l as ChatCompletionError, m as ChatCompletionRequestPayloads, s as CombinedLogger, r as ConsoleLogger, h as ConversationMessage, t as Literal, n as LogChatCompletionRequest, o as LogChatCompletionResponse, p as LogLevel, q as Logger, e as LoggerContext, N as NoopLogImplementation, P as PropsOfAIComponent, v as RenderResult, x as Renderable, u as RenderableStream, i as RenderedConversationMessage, S as SystemMessage, U as UserMessage, w as attachedContextSymbol, j as childrenToConversationMessage, k as computeUsage, c as createAIElement, f as createContext } from './createElement-y5NHsp6D.mjs';
|
|
3
3
|
import { OpenAI } from 'openai';
|
|
4
4
|
export { OpenAI as OpenAIClient } from 'openai';
|
|
5
|
+
import { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam, ChatCompletionAssistantMessageParam } from 'openai/resources';
|
|
5
6
|
import AnthropicClient from '@anthropic-ai/sdk';
|
|
6
7
|
export { default as AnthropicClient } from '@anthropic-ai/sdk';
|
|
7
8
|
export { countTokens as countAnthropicTokens } from '@anthropic-ai/tokenizer';
|
|
@@ -12,12 +13,21 @@ declare function createRenderContext({ logger, rootRenderId, }?: {
|
|
|
12
13
|
}): RenderContext;
|
|
13
14
|
|
|
14
15
|
type OpenAIChatCompletionRequest = OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming;
|
|
16
|
+
type OpenAIChatMessage = ChatCompletionSystemMessageParam | ChatCompletionUserMessageParam | ChatCompletionAssistantMessageParam;
|
|
15
17
|
declare module '@gammatech/aijsx' {
|
|
16
18
|
interface ChatCompletionRequestPayloads {
|
|
17
19
|
openai: OpenAIChatCompletionRequest;
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
|
-
type
|
|
22
|
+
type UserMessageWithImagesProps = {
|
|
23
|
+
children: AINode;
|
|
24
|
+
images: {
|
|
25
|
+
url: string;
|
|
26
|
+
detail?: 'low' | 'high' | 'auto';
|
|
27
|
+
}[];
|
|
28
|
+
};
|
|
29
|
+
declare const UserMessageWithImages: AIComponent<UserMessageWithImagesProps>;
|
|
30
|
+
type ValidOpenAIChatModel = 'gpt-4' | 'gpt-4-0314' | 'gpt-4-0613' | 'gpt-4-32k' | 'gpt-4-32k-0314' | 'gpt-4-32k-0613' | 'gpt-4-1106-preview' | 'gpt-3.5-turbo' | 'gpt-3.5-turbo-0301' | 'gpt-3.5-turbo-0613' | 'gpt-3.5-turbo-16k' | 'gpt-3.5-turbo-16k-0613' | 'gpt-3.5-turbo-1106' | 'gpt-4-vision-preview';
|
|
21
31
|
declare const OpenAIClientContext: Context<() => OpenAI>;
|
|
22
32
|
type OpenAIChatCompletionProps = {
|
|
23
33
|
model: ValidOpenAIChatModel;
|
|
@@ -34,7 +44,7 @@ declare const tokenizer: {
|
|
|
34
44
|
decode: (tokens: number[]) => string;
|
|
35
45
|
};
|
|
36
46
|
declare function tokenLimitForChatModel(model: ValidOpenAIChatModel): number | undefined;
|
|
37
|
-
declare function
|
|
47
|
+
declare function tokenCountForChatMessage(message: OpenAIChatMessage): number;
|
|
38
48
|
|
|
39
49
|
type AnthropicChatCompletionRequest = AnthropicClient.CompletionCreateParams;
|
|
40
50
|
declare module '@gammatech/aijsx' {
|
|
@@ -69,4 +79,4 @@ type AnthropicChatCompletionProps = {
|
|
|
69
79
|
*/
|
|
70
80
|
declare function AnthropicChatCompletion(props: AnthropicChatCompletionProps, { render, logger, getContext }: RenderContext): AsyncGenerator<string, void, unknown>;
|
|
71
81
|
|
|
72
|
-
export { AIElement, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, Context, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, OpenAIClientContext, RenderContext,
|
|
82
|
+
export { AIComponent, AIElement, AINode, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, Context, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, RenderContext, UserMessageWithImages, type ValidAnthropicChatModel, type ValidOpenAIChatModel, createRenderContext, defaultMaxTokens, tokenCountForChatMessage, tokenLimitForChatModel, tokenizer };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { L as LogImplementation, R as RenderContext, C as Context,
|
|
2
|
-
export {
|
|
1
|
+
import { L as LogImplementation, R as RenderContext, A as AIComponent, C as Context, a as AINode, b as AIElement } from './createElement-y5NHsp6D.js';
|
|
2
|
+
export { d as AIFragment, g as AssistantMessage, B as BoundLogger, l as ChatCompletionError, m as ChatCompletionRequestPayloads, s as CombinedLogger, r as ConsoleLogger, h as ConversationMessage, t as Literal, n as LogChatCompletionRequest, o as LogChatCompletionResponse, p as LogLevel, q as Logger, e as LoggerContext, N as NoopLogImplementation, P as PropsOfAIComponent, v as RenderResult, x as Renderable, u as RenderableStream, i as RenderedConversationMessage, S as SystemMessage, U as UserMessage, w as attachedContextSymbol, j as childrenToConversationMessage, k as computeUsage, c as createAIElement, f as createContext } from './createElement-y5NHsp6D.js';
|
|
3
3
|
import { OpenAI } from 'openai';
|
|
4
4
|
export { OpenAI as OpenAIClient } from 'openai';
|
|
5
|
+
import { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam, ChatCompletionAssistantMessageParam } from 'openai/resources';
|
|
5
6
|
import AnthropicClient from '@anthropic-ai/sdk';
|
|
6
7
|
export { default as AnthropicClient } from '@anthropic-ai/sdk';
|
|
7
8
|
export { countTokens as countAnthropicTokens } from '@anthropic-ai/tokenizer';
|
|
@@ -12,12 +13,21 @@ declare function createRenderContext({ logger, rootRenderId, }?: {
|
|
|
12
13
|
}): RenderContext;
|
|
13
14
|
|
|
14
15
|
type OpenAIChatCompletionRequest = OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming;
|
|
16
|
+
type OpenAIChatMessage = ChatCompletionSystemMessageParam | ChatCompletionUserMessageParam | ChatCompletionAssistantMessageParam;
|
|
15
17
|
declare module '@gammatech/aijsx' {
|
|
16
18
|
interface ChatCompletionRequestPayloads {
|
|
17
19
|
openai: OpenAIChatCompletionRequest;
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
|
-
type
|
|
22
|
+
type UserMessageWithImagesProps = {
|
|
23
|
+
children: AINode;
|
|
24
|
+
images: {
|
|
25
|
+
url: string;
|
|
26
|
+
detail?: 'low' | 'high' | 'auto';
|
|
27
|
+
}[];
|
|
28
|
+
};
|
|
29
|
+
declare const UserMessageWithImages: AIComponent<UserMessageWithImagesProps>;
|
|
30
|
+
type ValidOpenAIChatModel = 'gpt-4' | 'gpt-4-0314' | 'gpt-4-0613' | 'gpt-4-32k' | 'gpt-4-32k-0314' | 'gpt-4-32k-0613' | 'gpt-4-1106-preview' | 'gpt-3.5-turbo' | 'gpt-3.5-turbo-0301' | 'gpt-3.5-turbo-0613' | 'gpt-3.5-turbo-16k' | 'gpt-3.5-turbo-16k-0613' | 'gpt-3.5-turbo-1106' | 'gpt-4-vision-preview';
|
|
21
31
|
declare const OpenAIClientContext: Context<() => OpenAI>;
|
|
22
32
|
type OpenAIChatCompletionProps = {
|
|
23
33
|
model: ValidOpenAIChatModel;
|
|
@@ -34,7 +44,7 @@ declare const tokenizer: {
|
|
|
34
44
|
decode: (tokens: number[]) => string;
|
|
35
45
|
};
|
|
36
46
|
declare function tokenLimitForChatModel(model: ValidOpenAIChatModel): number | undefined;
|
|
37
|
-
declare function
|
|
47
|
+
declare function tokenCountForChatMessage(message: OpenAIChatMessage): number;
|
|
38
48
|
|
|
39
49
|
type AnthropicChatCompletionRequest = AnthropicClient.CompletionCreateParams;
|
|
40
50
|
declare module '@gammatech/aijsx' {
|
|
@@ -69,4 +79,4 @@ type AnthropicChatCompletionProps = {
|
|
|
69
79
|
*/
|
|
70
80
|
declare function AnthropicChatCompletion(props: AnthropicChatCompletionProps, { render, logger, getContext }: RenderContext): AsyncGenerator<string, void, unknown>;
|
|
71
81
|
|
|
72
|
-
export { AIElement, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, Context, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, OpenAIClientContext, RenderContext,
|
|
82
|
+
export { AIComponent, AIElement, AINode, AnthropicChatCompletion, type AnthropicChatCompletionRequest, AnthropicClientContext, Context, LogImplementation, OpenAIChatCompletion, type OpenAIChatCompletionRequest, type OpenAIChatMessage, OpenAIClientContext, RenderContext, UserMessageWithImages, type ValidAnthropicChatModel, type ValidOpenAIChatModel, createRenderContext, defaultMaxTokens, tokenCountForChatMessage, tokenLimitForChatModel, tokenizer };
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,7 @@ __export(src_exports, {
|
|
|
46
46
|
OpenAIClientContext: () => OpenAIClientContext,
|
|
47
47
|
SystemMessage: () => SystemMessage,
|
|
48
48
|
UserMessage: () => UserMessage,
|
|
49
|
+
UserMessageWithImages: () => UserMessageWithImages,
|
|
49
50
|
attachedContextSymbol: () => attachedContextSymbol,
|
|
50
51
|
childrenToConversationMessage: () => childrenToConversationMessage,
|
|
51
52
|
computeUsage: () => computeUsage,
|
|
@@ -54,7 +55,7 @@ __export(src_exports, {
|
|
|
54
55
|
createContext: () => createContext,
|
|
55
56
|
createRenderContext: () => createRenderContext,
|
|
56
57
|
defaultMaxTokens: () => defaultMaxTokens,
|
|
57
|
-
|
|
58
|
+
tokenCountForChatMessage: () => tokenCountForChatMessage,
|
|
58
59
|
tokenLimitForChatModel: () => tokenLimitForChatModel,
|
|
59
60
|
tokenizer: () => tokenizer
|
|
60
61
|
});
|
|
@@ -73,7 +74,7 @@ var AssistantMessage = (props) => {
|
|
|
73
74
|
var childrenToConversationMessage = (c) => {
|
|
74
75
|
const children = Array.isArray(c) ? c : [c];
|
|
75
76
|
return children.map((child) => {
|
|
76
|
-
if (child.tag.name
|
|
77
|
+
if (child.tag.name.startsWith("UserMessage")) {
|
|
77
78
|
return {
|
|
78
79
|
type: "user",
|
|
79
80
|
element: child
|
|
@@ -568,6 +569,7 @@ function tokenLimitForChatModel(model) {
|
|
|
568
569
|
case "gpt-4-0314":
|
|
569
570
|
case "gpt-4-0613":
|
|
570
571
|
return 8192 - TOKENS_CONSUMED_BY_REPLY_PREFIX;
|
|
572
|
+
case "gpt-4-vision-preview":
|
|
571
573
|
case "gpt-4-32k":
|
|
572
574
|
case "gpt-4-32k-0314":
|
|
573
575
|
case "gpt-4-32k-0613":
|
|
@@ -588,14 +590,23 @@ function tokenLimitForChatModel(model) {
|
|
|
588
590
|
}
|
|
589
591
|
}
|
|
590
592
|
}
|
|
591
|
-
|
|
593
|
+
var DETAIL_COST_PLACEHOLDERS = {
|
|
594
|
+
// auto and high are based on 1024x1024
|
|
595
|
+
auto: 765,
|
|
596
|
+
high: 765,
|
|
597
|
+
low: 85
|
|
598
|
+
};
|
|
599
|
+
function tokenCountForChatMessage(message) {
|
|
592
600
|
const TOKENS_PER_MESSAGE = 3;
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
601
|
+
const contentTokens = Array.isArray(message.content) ? message.content.reduce((acc, cur) => {
|
|
602
|
+
if ("text" in cur) {
|
|
603
|
+
return acc + tokenizer.encode(cur.text).length;
|
|
604
|
+
}
|
|
605
|
+
const detail = cur.image_url.detail || "auto";
|
|
606
|
+
const detailCost = DETAIL_COST_PLACEHOLDERS[detail];
|
|
607
|
+
return acc + detailCost;
|
|
608
|
+
}, 0) : tokenizer.encode(message.content || "").length;
|
|
609
|
+
return TOKENS_PER_MESSAGE + contentTokens;
|
|
599
610
|
}
|
|
600
611
|
|
|
601
612
|
// src/jsx-runtime.ts
|
|
@@ -607,6 +618,10 @@ function jsx(type, config, maybeKey) {
|
|
|
607
618
|
var jsxs = jsx;
|
|
608
619
|
|
|
609
620
|
// src/lib/openai/OpenAI.tsx
|
|
621
|
+
var VISION_MODELS = ["gpt-4-vision-preview"];
|
|
622
|
+
var UserMessageWithImages = (props) => {
|
|
623
|
+
return /* @__PURE__ */ jsx(UserMessage, { children: props.children });
|
|
624
|
+
};
|
|
610
625
|
var defaultClient = null;
|
|
611
626
|
var OpenAIClientContext = createContext(() => {
|
|
612
627
|
if (defaultClient) {
|
|
@@ -622,24 +637,78 @@ async function* OpenAIChatCompletion(props, { logger, render, getContext }) {
|
|
|
622
637
|
if (!client) {
|
|
623
638
|
throw new Error("[OpenAI] must supply OpenAI model via context");
|
|
624
639
|
}
|
|
625
|
-
const
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
640
|
+
const conversationMessages = childrenToConversationMessage(props.children);
|
|
641
|
+
const chatMessagesWithElement = await Promise.all(
|
|
642
|
+
conversationMessages.map(async (m) => {
|
|
643
|
+
const content2 = await render(m.element);
|
|
644
|
+
if (VISION_MODELS.includes(props.model) && m.element.tag.name === "UserMessageWithImages") {
|
|
645
|
+
const element = m.element;
|
|
646
|
+
return {
|
|
647
|
+
content: [
|
|
648
|
+
{
|
|
649
|
+
type: "text",
|
|
650
|
+
text: content2
|
|
651
|
+
},
|
|
652
|
+
...element.props.images.map((image) => ({
|
|
653
|
+
type: "image_url",
|
|
654
|
+
image_url: {
|
|
655
|
+
url: image.url,
|
|
656
|
+
detail: image.detail || "auto"
|
|
657
|
+
}
|
|
658
|
+
}))
|
|
659
|
+
],
|
|
660
|
+
role: "user",
|
|
661
|
+
element
|
|
662
|
+
};
|
|
663
|
+
}
|
|
631
664
|
return {
|
|
632
|
-
|
|
633
|
-
|
|
665
|
+
content: content2,
|
|
666
|
+
role: m.type,
|
|
667
|
+
element: m.element
|
|
634
668
|
};
|
|
635
669
|
})
|
|
636
670
|
);
|
|
637
|
-
const
|
|
671
|
+
const renderedMessages = chatMessagesWithElement.map((chatMessage) => {
|
|
672
|
+
const stringContent = typeof chatMessage.content === "string" ? chatMessage.content : (chatMessage.content || []).map((c) => {
|
|
673
|
+
if (c.type === "text") {
|
|
674
|
+
return c.text;
|
|
675
|
+
}
|
|
676
|
+
if (c.type === "image_url") {
|
|
677
|
+
return `<ContentTypeImage url="${c.image_url.url.slice(
|
|
678
|
+
0,
|
|
679
|
+
256
|
|
680
|
+
// in case of base64
|
|
681
|
+
)}" detail="${c.image_url.detail}" />`;
|
|
682
|
+
}
|
|
683
|
+
return "";
|
|
684
|
+
}).join("\n");
|
|
638
685
|
return {
|
|
639
|
-
|
|
640
|
-
|
|
686
|
+
type: chatMessage.role,
|
|
687
|
+
element: chatMessage.element,
|
|
688
|
+
content: stringContent,
|
|
689
|
+
tokens: tokenCountForChatMessage(chatMessage)
|
|
641
690
|
};
|
|
642
691
|
});
|
|
692
|
+
const chatMessages = chatMessagesWithElement.map(
|
|
693
|
+
({ content: content2, role }) => {
|
|
694
|
+
if (role === "user") {
|
|
695
|
+
return {
|
|
696
|
+
content: content2,
|
|
697
|
+
role
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
if (role === "system") {
|
|
701
|
+
return {
|
|
702
|
+
content: content2,
|
|
703
|
+
role
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
return {
|
|
707
|
+
content: content2,
|
|
708
|
+
role
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
);
|
|
643
712
|
const chatCompletionRequest = {
|
|
644
713
|
model: props.model,
|
|
645
714
|
max_tokens: props.maxTokens,
|
|
@@ -689,8 +758,8 @@ async function* OpenAIChatCompletion(props, { logger, render, getContext }) {
|
|
|
689
758
|
type: "assistant",
|
|
690
759
|
element: /* @__PURE__ */ jsx(AssistantMessage, { children: content }),
|
|
691
760
|
content,
|
|
692
|
-
tokens:
|
|
693
|
-
|
|
761
|
+
tokens: tokenCountForChatMessage({
|
|
762
|
+
role: "assistant",
|
|
694
763
|
content
|
|
695
764
|
})
|
|
696
765
|
};
|
|
@@ -845,6 +914,7 @@ var import_tokenizer3 = require("@anthropic-ai/tokenizer");
|
|
|
845
914
|
OpenAIClientContext,
|
|
846
915
|
SystemMessage,
|
|
847
916
|
UserMessage,
|
|
917
|
+
UserMessageWithImages,
|
|
848
918
|
attachedContextSymbol,
|
|
849
919
|
childrenToConversationMessage,
|
|
850
920
|
computeUsage,
|
|
@@ -853,7 +923,7 @@ var import_tokenizer3 = require("@anthropic-ai/tokenizer");
|
|
|
853
923
|
createContext,
|
|
854
924
|
createRenderContext,
|
|
855
925
|
defaultMaxTokens,
|
|
856
|
-
|
|
926
|
+
tokenCountForChatMessage,
|
|
857
927
|
tokenLimitForChatModel,
|
|
858
928
|
tokenizer
|
|
859
929
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ var AssistantMessage = (props) => {
|
|
|
20
20
|
var childrenToConversationMessage = (c) => {
|
|
21
21
|
const children = Array.isArray(c) ? c : [c];
|
|
22
22
|
return children.map((child) => {
|
|
23
|
-
if (child.tag.name
|
|
23
|
+
if (child.tag.name.startsWith("UserMessage")) {
|
|
24
24
|
return {
|
|
25
25
|
type: "user",
|
|
26
26
|
element: child
|
|
@@ -489,6 +489,7 @@ function tokenLimitForChatModel(model) {
|
|
|
489
489
|
case "gpt-4-0314":
|
|
490
490
|
case "gpt-4-0613":
|
|
491
491
|
return 8192 - TOKENS_CONSUMED_BY_REPLY_PREFIX;
|
|
492
|
+
case "gpt-4-vision-preview":
|
|
492
493
|
case "gpt-4-32k":
|
|
493
494
|
case "gpt-4-32k-0314":
|
|
494
495
|
case "gpt-4-32k-0613":
|
|
@@ -509,17 +510,30 @@ function tokenLimitForChatModel(model) {
|
|
|
509
510
|
}
|
|
510
511
|
}
|
|
511
512
|
}
|
|
512
|
-
|
|
513
|
+
var DETAIL_COST_PLACEHOLDERS = {
|
|
514
|
+
// auto and high are based on 1024x1024
|
|
515
|
+
auto: 765,
|
|
516
|
+
high: 765,
|
|
517
|
+
low: 85
|
|
518
|
+
};
|
|
519
|
+
function tokenCountForChatMessage(message) {
|
|
513
520
|
const TOKENS_PER_MESSAGE = 3;
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
521
|
+
const contentTokens = Array.isArray(message.content) ? message.content.reduce((acc, cur) => {
|
|
522
|
+
if ("text" in cur) {
|
|
523
|
+
return acc + tokenizer.encode(cur.text).length;
|
|
524
|
+
}
|
|
525
|
+
const detail = cur.image_url.detail || "auto";
|
|
526
|
+
const detailCost = DETAIL_COST_PLACEHOLDERS[detail];
|
|
527
|
+
return acc + detailCost;
|
|
528
|
+
}, 0) : tokenizer.encode(message.content || "").length;
|
|
529
|
+
return TOKENS_PER_MESSAGE + contentTokens;
|
|
520
530
|
}
|
|
521
531
|
|
|
522
532
|
// src/lib/openai/OpenAI.tsx
|
|
533
|
+
var VISION_MODELS = ["gpt-4-vision-preview"];
|
|
534
|
+
var UserMessageWithImages = (props) => {
|
|
535
|
+
return /* @__PURE__ */ jsx(UserMessage, { children: props.children });
|
|
536
|
+
};
|
|
523
537
|
var defaultClient = null;
|
|
524
538
|
var OpenAIClientContext = createContext(() => {
|
|
525
539
|
if (defaultClient) {
|
|
@@ -535,24 +549,78 @@ async function* OpenAIChatCompletion(props, { logger, render, getContext }) {
|
|
|
535
549
|
if (!client) {
|
|
536
550
|
throw new Error("[OpenAI] must supply OpenAI model via context");
|
|
537
551
|
}
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
552
|
+
const conversationMessages = childrenToConversationMessage(props.children);
|
|
553
|
+
const chatMessagesWithElement = await Promise.all(
|
|
554
|
+
conversationMessages.map(async (m) => {
|
|
555
|
+
const content2 = await render(m.element);
|
|
556
|
+
if (VISION_MODELS.includes(props.model) && m.element.tag.name === "UserMessageWithImages") {
|
|
557
|
+
const element = m.element;
|
|
558
|
+
return {
|
|
559
|
+
content: [
|
|
560
|
+
{
|
|
561
|
+
type: "text",
|
|
562
|
+
text: content2
|
|
563
|
+
},
|
|
564
|
+
...element.props.images.map((image) => ({
|
|
565
|
+
type: "image_url",
|
|
566
|
+
image_url: {
|
|
567
|
+
url: image.url,
|
|
568
|
+
detail: image.detail || "auto"
|
|
569
|
+
}
|
|
570
|
+
}))
|
|
571
|
+
],
|
|
572
|
+
role: "user",
|
|
573
|
+
element
|
|
574
|
+
};
|
|
575
|
+
}
|
|
544
576
|
return {
|
|
545
|
-
|
|
546
|
-
|
|
577
|
+
content: content2,
|
|
578
|
+
role: m.type,
|
|
579
|
+
element: m.element
|
|
547
580
|
};
|
|
548
581
|
})
|
|
549
582
|
);
|
|
550
|
-
const
|
|
583
|
+
const renderedMessages = chatMessagesWithElement.map((chatMessage) => {
|
|
584
|
+
const stringContent = typeof chatMessage.content === "string" ? chatMessage.content : (chatMessage.content || []).map((c) => {
|
|
585
|
+
if (c.type === "text") {
|
|
586
|
+
return c.text;
|
|
587
|
+
}
|
|
588
|
+
if (c.type === "image_url") {
|
|
589
|
+
return `<ContentTypeImage url="${c.image_url.url.slice(
|
|
590
|
+
0,
|
|
591
|
+
256
|
|
592
|
+
// in case of base64
|
|
593
|
+
)}" detail="${c.image_url.detail}" />`;
|
|
594
|
+
}
|
|
595
|
+
return "";
|
|
596
|
+
}).join("\n");
|
|
551
597
|
return {
|
|
552
|
-
|
|
553
|
-
|
|
598
|
+
type: chatMessage.role,
|
|
599
|
+
element: chatMessage.element,
|
|
600
|
+
content: stringContent,
|
|
601
|
+
tokens: tokenCountForChatMessage(chatMessage)
|
|
554
602
|
};
|
|
555
603
|
});
|
|
604
|
+
const chatMessages = chatMessagesWithElement.map(
|
|
605
|
+
({ content: content2, role }) => {
|
|
606
|
+
if (role === "user") {
|
|
607
|
+
return {
|
|
608
|
+
content: content2,
|
|
609
|
+
role
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
if (role === "system") {
|
|
613
|
+
return {
|
|
614
|
+
content: content2,
|
|
615
|
+
role
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
return {
|
|
619
|
+
content: content2,
|
|
620
|
+
role
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
);
|
|
556
624
|
const chatCompletionRequest = {
|
|
557
625
|
model: props.model,
|
|
558
626
|
max_tokens: props.maxTokens,
|
|
@@ -602,8 +670,8 @@ async function* OpenAIChatCompletion(props, { logger, render, getContext }) {
|
|
|
602
670
|
type: "assistant",
|
|
603
671
|
element: /* @__PURE__ */ jsx(AssistantMessage, { children: content }),
|
|
604
672
|
content,
|
|
605
|
-
tokens:
|
|
606
|
-
|
|
673
|
+
tokens: tokenCountForChatMessage({
|
|
674
|
+
role: "assistant",
|
|
607
675
|
content
|
|
608
676
|
})
|
|
609
677
|
};
|
|
@@ -757,6 +825,7 @@ export {
|
|
|
757
825
|
OpenAIClientContext,
|
|
758
826
|
SystemMessage,
|
|
759
827
|
UserMessage,
|
|
828
|
+
UserMessageWithImages,
|
|
760
829
|
attachedContextSymbol,
|
|
761
830
|
childrenToConversationMessage,
|
|
762
831
|
computeUsage,
|
|
@@ -765,7 +834,7 @@ export {
|
|
|
765
834
|
createContext,
|
|
766
835
|
createRenderContext,
|
|
767
836
|
defaultMaxTokens,
|
|
768
|
-
|
|
837
|
+
tokenCountForChatMessage,
|
|
769
838
|
tokenLimitForChatModel,
|
|
770
839
|
tokenizer
|
|
771
840
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Fragment, JSX, jsx, jsxDEV, jsxs } from './jsx-runtime.mjs';
|
|
2
|
-
import './createElement-
|
|
2
|
+
import './createElement-y5NHsp6D.mjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Fragment, JSX, jsx, jsxDEV, jsxs } from './jsx-runtime.js';
|
|
2
|
-
import './createElement-
|
|
2
|
+
import './createElement-y5NHsp6D.js';
|
package/dist/jsx-runtime.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as AIComponent, b as AIElement, d as AIFragment } from './createElement-y5NHsp6D.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The is used as an import source for ts/js files as the JSX transpile functinos
|
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as AIComponent, b as AIElement, d as AIFragment } from './createElement-y5NHsp6D.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The is used as an import source for ts/js files as the JSX transpile functinos
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gammatech/aijsx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-vision.2",
|
|
4
4
|
"description": "Rewrite of aijsx",
|
|
5
5
|
"author": "Jordan Garcia",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
"test:watch": "jest --watch --verbose",
|
|
14
14
|
"build": "yarn check-types && yarn clean-symlinks && tsup",
|
|
15
15
|
"clean-symlinks": "rm ./jsx-* || true",
|
|
16
|
-
"symlink": "ln -s ./dist/jsx-runtime.js . && ln -s ./dist/jsx-runtime.d.ts && ln -s ./dist/jsx-runtime.js ./jsx-dev-runtime.js && ln -s ./dist/jsx-runtime.d.ts ./jsx-dev-runtime.d.ts",
|
|
17
16
|
"prepublishOnly": "yarn build",
|
|
18
17
|
"lint": "eslint \"{src,test}/**/*.ts\" && yarn check-types",
|
|
19
18
|
"check-types": "tsc --skipLibCheck --noEmit"
|