Skip to content

Commit

Permalink
Dify.AI | Create Chat Message Full Implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
abdullahbaa5 committed Jan 23, 2024
1 parent 392ec68 commit 1c7b2d4
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 8 deletions.
79 changes: 79 additions & 0 deletions packages/forge/blocks/difyAi/actions/createChatMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { createAction, option } from '@typebot.io/forge'
import { isDefined, isEmpty } from '@typebot.io/lib'
import { got } from 'got'
import { auth } from '../auth'
import { DifyResponse } from '../types'

export const createChatMessage = createAction({
auth,
name: 'Create Chat Message',
options: option.object({
inputs: option.string.layout({
label: 'Inputs',
helperText:
'Variable values to be replaced in the prompt. The code must be a JSON object containing the variable key/value pairs.',
inputType: 'code',
defaultValue: '{}',
}),
query: option.string.layout({
label: 'Query',
placeholder: 'User input/question content',
inputType: 'textarea',
isRequired: true,
}),
conversation_id: option.string.layout({
label: 'Conversation ID',
moreInfoTooltip:
'Used to remember the conversation with the user. If empty, a new conversation id is created.',
}),
user: option.string.layout({
label: 'User',
moreInfoTooltip:
'The user identifier, defined by the developer, must ensure uniqueness within the app.',
}),
responseMapping: option
.saveResponseArray(['Answer', 'Conversation ID', 'Total Tokens'])
.layout({
accordion: 'Save response',
}),
}),
getSetVariableIds: ({ responseMapping }) =>
responseMapping?.map((r) => r.variableId).filter(isDefined) ?? [],
run: {
server: async ({
credentials: { apiEndpoint, apiKey },
options: { conversation_id, query, user, inputs, responseMapping },
variables,
}) => {
if (isEmpty(inputs)) inputs = '{}'

const res: DifyResponse = await got
.post(apiEndpoint + '/chat-messages', {
headers: {
Authorization: `Bearer ${apiKey}`,
},
json: {
inputs: JSON.parse(inputs),
query,
response_mode: 'blocking',
conversation_id,
user,
},
})
.json()

responseMapping?.forEach((mapping) => {
if (!mapping.variableId) return

const item = mapping.item ?? 'Answer'
if (item === 'Answer') variables.set(mapping.variableId, res.answer)

if (item === 'Conversation ID')
variables.set(mapping.variableId, res.conversation_id)

if (item === 'Total Tokens')
variables.set(mapping.variableId, res.metadata.usage.total_tokens)
})
},
},
})
13 changes: 10 additions & 3 deletions packages/forge/blocks/difyAi/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ export const auth = {
type: 'encryptedCredentials',
name: 'Dify.AI account',
schema: option.object({
apiEndpoint: option.string.layout({
label: 'API Endpoint',
isRequired: true,
helperText: 'URI where the Service API is hosted.',
withVariableButton: true,
}),
apiKey: option.string.layout({
label: 'API key',
label: 'App API key',
isRequired: true,
input: 'password',
helperText: 'You can generate an API key [here](<INSERT_URL>).',
helperText: 'API Secret Key for your Dify App.',
inputType: 'password',
withVariableButton: true,
}),
}),
} satisfies AuthDefinition
3 changes: 2 additions & 1 deletion packages/forge/blocks/difyAi/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { createBlock } from '@typebot.io/forge'
import { DifyAiLogo } from './logo'
import { auth } from './auth'
import { createChatMessage } from './actions/createChatMessage'

export const difyAi = createBlock({
id: 'dify-ai',
name: 'Dify.AI',
tags: ['dify', 'ai', 'documents', 'files', 'knowledge base'],
LightLogo: DifyAiLogo,
auth,
actions: [],
actions: [createChatMessage],
})
16 changes: 15 additions & 1 deletion packages/forge/blocks/difyAi/logo.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
import React from 'react'

export const DifyAiLogo = (props: React.SVGProps<SVGSVGElement>) => <svg></svg>
export const DifyAiLogo = (props: React.SVGProps<SVGSVGElement>) => (
<svg
viewBox="0 0 25 25"
width="25"
height="25"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<image
href="https://framerusercontent.com/images/xRJ6vNo9mUYeVNxt0KITXCXEuSk.png"
height="25"
width="25"
/>
</svg>
)
5 changes: 3 additions & 2 deletions packages/forge/blocks/difyAi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
"license": "ISC",
"devDependencies": {
"@typebot.io/forge": "workspace:*",
"@typebot.io/lib": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2",
"@typebot.io/lib": "workspace:*"
"got": "12.6.0",
"typescript": "5.3.2"
}
}
9 changes: 9 additions & 0 deletions packages/forge/blocks/difyAi/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type DifyResponse = {
answer: string
metadata: {
usage: {
total_tokens: number
}
}
conversation_id: string
}
2 changes: 1 addition & 1 deletion packages/forge/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ const createAuthFile = async (
apiKey: option.string.layout({
label: 'API key',
isRequired: true,
input: 'password',
inputType: 'password',
helperText:
'You can generate an API key [here](<INSERT_URL>).',
}),
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1c7b2d4

Please sign in to comment.