2
0

🐛 Fix ky not working due to fetch rewriting by mistral package

Closes #1396
This commit is contained in:
Baptiste Arnaud
2024-04-03 14:35:18 +02:00
parent 6a4a43efb4
commit ef10f69f92
15 changed files with 28 additions and 14 deletions

View File

@@ -56,14 +56,12 @@ const nextConfig = {
if (nextRuntime === 'edge') { if (nextRuntime === 'edge') {
config.resolve.alias['minio'] = false config.resolve.alias['minio'] = false
config.resolve.alias['got'] = false config.resolve.alias['got'] = false
config.resolve.alias['qrcode'] = false
return config return config
} }
// These packages are imports from the integrations definition files that can be ignored for the client. // These packages are imports from the integrations definition files that can be ignored for the client.
config.resolve.alias['minio'] = false config.resolve.alias['minio'] = false
config.resolve.alias['got'] = false config.resolve.alias['got'] = false
config.resolve.alias['openai'] = false config.resolve.alias['openai'] = false
config.resolve.alias['qrcode'] = false
return config return config
}, },
headers: async () => { headers: async () => {

View File

@@ -26,7 +26,7 @@ After using the [CLI](./cli) to create your new block. The `index.ts` file conta
name="LightLogo" name="LightLogo"
type="(props: React.SVGProps<SVGSVGElement>) => React.JSX.Element" type="(props: React.SVGProps<SVGSVGElement>) => React.JSX.Element"
required required
></ResponseField> />
<ResponseField <ResponseField
name="DarkLogo" name="DarkLogo"

View File

@@ -13,6 +13,8 @@ An action can do one of the following things:
The most common action is to execute a function on the server. This is done by simply declaring that function in the action block. The most common action is to execute a function on the server. This is done by simply declaring that function in the action block.
If you need to use an external package that is not compatible with web browser environment, you will have to dynamically import it in the server function. You can find an example of this in the [Anthropic's Create Chat Message action](https://github.com/baptisteArno/typebot.io/blob/main/packages/forge/blocks/anthropic/actions/createChatMessage.tsx)
Example: Example:
```ts ```ts

View File

@@ -19902,6 +19902,8 @@
"type": "string", "type": "string",
"enum": [ "enum": [
"claude-3-opus-20240229", "claude-3-opus-20240229",
"claude-3-sonnet-20240229",
"claude-3-haiku-20240307",
"claude-2.1", "claude-2.1",
"claude-2.0", "claude-2.0",
"claude-instant-1.2" "claude-instant-1.2"

View File

@@ -10477,6 +10477,8 @@
"type": "string", "type": "string",
"enum": [ "enum": [
"claude-3-opus-20240229", "claude-3-opus-20240229",
"claude-3-sonnet-20240229",
"claude-3-haiku-20240307",
"claude-2.1", "claude-2.1",
"claude-2.0", "claude-2.0",
"claude-instant-1.2" "claude-instant-1.2"

View File

@@ -56,14 +56,12 @@ const nextConfig = {
if (nextRuntime === 'edge') { if (nextRuntime === 'edge') {
config.resolve.alias['minio'] = false config.resolve.alias['minio'] = false
config.resolve.alias['got'] = false config.resolve.alias['got'] = false
config.resolve.alias['qrcode'] = false
return config return config
} }
// These packages are imports from the integrations definition files that can be ignored for the client. // These packages are imports from the integrations definition files that can be ignored for the client.
config.resolve.alias['minio'] = false config.resolve.alias['minio'] = false
config.resolve.alias['got'] = false config.resolve.alias['got'] = false
config.resolve.alias['openai'] = false config.resolve.alias['openai'] = false
config.resolve.alias['qrcode'] = false
return config return config
}, },
async redirects() { async redirects() {

View File

@@ -13,6 +13,7 @@ type Props = {
sessionId: string sessionId: string
} }
export const continueChat = async ({ origin, sessionId, message }: Props) => { export const continueChat = async ({ origin, sessionId, message }: Props) => {
console.log('test')
const session = await getSession(sessionId) const session = await getSession(sessionId)
if (!session) { if (!session) {

View File

@@ -111,6 +111,7 @@ export const executeGroup = async (
logs, logs,
visitedEdges, visitedEdges,
} }
console.log('yes')
const executionResponse = ( const executionResponse = (
isLogicBlock(block) isLogicBlock(block)
? await executeLogic(newSessionState)(block) ? await executeLogic(newSessionState)(block)

View File

@@ -16,6 +16,7 @@ import { env } from '@typebot.io/env'
export const executeIntegration = export const executeIntegration =
(state: SessionState) => (state: SessionState) =>
async (block: IntegrationBlock): Promise<ExecuteIntegrationResponse> => { async (block: IntegrationBlock): Promise<ExecuteIntegrationResponse> => {
console.log('HI')
switch (block.type) { switch (block.type) {
case IntegrationBlockType.GOOGLE_SHEETS: case IntegrationBlockType.GOOGLE_SHEETS:
return { return {

View File

@@ -27,6 +27,7 @@ export const executeForgedBlock = async (
const blockDef = forgedBlocks[block.type] const blockDef = forgedBlocks[block.type]
if (!blockDef) return { outgoingEdgeId: block.outgoingEdgeId } if (!blockDef) return { outgoingEdgeId: block.outgoingEdgeId }
const action = blockDef.actions.find((a) => a.name === block.options.action) const action = blockDef.actions.find((a) => a.name === block.options.action)
console.log('test', action)
const noCredentialsError = { const noCredentialsError = {
status: 'error', status: 'error',
description: 'Credentials not provided for integration', description: 'Credentials not provided for integration',
@@ -60,7 +61,9 @@ export const executeForgedBlock = async (
state.isStreamEnabled && state.isStreamEnabled &&
!state.whatsApp && !state.whatsApp &&
// TODO: Enable once chat api is rolling // TODO: Enable once chat api is rolling
isPlaneteScale() isPlaneteScale() &&
credentials &&
isCredentialsV2(credentials)
// !process.env.VERCEL_ENV // !process.env.VERCEL_ENV
) { ) {
return { return {

View File

@@ -1,6 +1,5 @@
import { createAction, option } from '@typebot.io/forge' import { createAction, option } from '@typebot.io/forge'
import { auth } from '../auth' import { auth } from '../auth'
import { Anthropic } from '@anthropic-ai/sdk'
import { AnthropicStream } from 'ai' import { AnthropicStream } from 'ai'
import { anthropicModels, defaultAnthropicOptions } from '../constants' import { anthropicModels, defaultAnthropicOptions } from '../constants'
import { parseChatMessages } from '../helpers/parseChatMessages' import { parseChatMessages } from '../helpers/parseChatMessages'
@@ -104,6 +103,8 @@ export const createChatMessage = createAction({
responseMapping?.map((res) => res.variableId).filter(isDefined) ?? [], responseMapping?.map((res) => res.variableId).filter(isDefined) ?? [],
run: { run: {
server: async ({ credentials: { apiKey }, options, variables, logs }) => { server: async ({ credentials: { apiKey }, options, variables, logs }) => {
const { Anthropic } = await import('@anthropic-ai/sdk')
const client = new Anthropic({ const client = new Anthropic({
apiKey: apiKey, apiKey: apiKey,
}) })
@@ -149,6 +150,8 @@ export const createChatMessage = createAction({
(res) => res.item === 'Message Content' || !res.item (res) => res.item === 'Message Content' || !res.item
)?.variableId, )?.variableId,
run: async ({ credentials: { apiKey }, options, variables }) => { run: async ({ credentials: { apiKey }, options, variables }) => {
const { Anthropic } = await import('@anthropic-ai/sdk')
const client = new Anthropic({ const client = new Anthropic({
apiKey: apiKey, apiKey: apiKey,
}) })

View File

@@ -1,7 +1,6 @@
import { option, createAction } from '@typebot.io/forge' import { option, createAction } from '@typebot.io/forge'
import { isDefined } from '@typebot.io/lib' import { isDefined } from '@typebot.io/lib'
import { auth } from '../auth' import { auth } from '../auth'
import MistralClient from '@mistralai/mistralai'
import { parseMessages } from '../helpers/parseMessages' import { parseMessages } from '../helpers/parseMessages'
import { OpenAIStream } from 'ai' import { OpenAIStream } from 'ai'
@@ -96,6 +95,7 @@ export const createChatCompletion = createAction({
id: 'fetchModels', id: 'fetchModels',
dependencies: [], dependencies: [],
fetch: async ({ credentials }) => { fetch: async ({ credentials }) => {
const MistralClient = (await import('@mistralai/mistralai')).default
const client = new MistralClient(credentials.apiKey) const client = new MistralClient(credentials.apiKey)
const listModelsResponse = await client.listModels() const listModelsResponse = await client.listModels()
@@ -111,6 +111,7 @@ export const createChatCompletion = createAction({
run: { run: {
server: async ({ credentials: { apiKey }, options, variables, logs }) => { server: async ({ credentials: { apiKey }, options, variables, logs }) => {
if (!options.model) return logs.add('No model selected') if (!options.model) return logs.add('No model selected')
const MistralClient = (await import('@mistralai/mistralai')).default
const client = new MistralClient(apiKey) const client = new MistralClient(apiKey)
const response = await client.chat({ const response = await client.chat({
@@ -131,6 +132,7 @@ export const createChatCompletion = createAction({
)?.variableId, )?.variableId,
run: async ({ credentials: { apiKey }, options, variables }) => { run: async ({ credentials: { apiKey }, options, variables }) => {
if (!options.model) return if (!options.model) return
const MistralClient = (await import('@mistralai/mistralai')).default
const client = new MistralClient(apiKey) const client = new MistralClient(apiKey)
const response = client.chatStream({ const response = client.chatStream({

View File

@@ -13,7 +13,7 @@
"typescript": "5.3.2" "typescript": "5.3.2"
}, },
"dependencies": { "dependencies": {
"@mistralai/mistralai": "0.0.10", "@mistralai/mistralai": "0.1.3",
"ai": "3.0.12" "ai": "3.0.12"
} }
} }

View File

@@ -1,5 +1,4 @@
import { createAction, option } from '@typebot.io/forge' import { createAction, option } from '@typebot.io/forge'
import { toBuffer as generateQrCodeBuffer } from 'qrcode'
import { uploadFileToBucket } from '@typebot.io/lib/s3/uploadFileToBucket' import { uploadFileToBucket } from '@typebot.io/lib/s3/uploadFileToBucket'
import { createId } from '@typebot.io/lib/createId' import { createId } from '@typebot.io/lib/createId'
@@ -29,6 +28,8 @@ export const generateQrCode = createAction({
'QR code image URL is not specified. Please select a variable to save the generated QR code image.' 'QR code image URL is not specified. Please select a variable to save the generated QR code image.'
) )
const generateQrCodeBuffer = (await import('qrcode')).toBuffer
const url = await uploadFileToBucket({ const url = await uploadFileToBucket({
file: await generateQrCodeBuffer(options.data), file: await generateQrCodeBuffer(options.data),
key: `tmp/qrcodes/${createId() + createId()}.png`, key: `tmp/qrcodes/${createId() + createId()}.png`,

8
pnpm-lock.yaml generated
View File

@@ -1387,8 +1387,8 @@ importers:
packages/forge/blocks/mistral: packages/forge/blocks/mistral:
dependencies: dependencies:
'@mistralai/mistralai': '@mistralai/mistralai':
specifier: 0.0.10 specifier: 0.1.3
version: 0.0.10 version: 0.1.3
ai: ai:
specifier: 3.0.12 specifier: 3.0.12
version: 3.0.12(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4) version: 3.0.12(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4)
@@ -7461,8 +7461,8 @@ packages:
zod-to-json-schema: 3.22.4(zod@3.22.4) zod-to-json-schema: 3.22.4(zod@3.22.4)
dev: true dev: true
/@mistralai/mistralai@0.0.10: /@mistralai/mistralai@0.1.3:
resolution: {integrity: sha512-fZOt7A32DcPSff58wTa44pKUBoJBH5toAuzNI9yoM7s5NjTupa1IYcSqqk2LigO8M5EtOEkFsD/XzdyWPnhaRA==} resolution: {integrity: sha512-WUHxC2xdeqX9PTXJEqdiNY54vT2ir72WSJrZTTBKRnkfhX6zIfCYA24faRlWjUB5WTpn+wfdGsTMl3ArijlXFA==}
dependencies: dependencies:
node-fetch: 2.7.0 node-fetch: 2.7.0
transitivePeerDependencies: transitivePeerDependencies: