chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import JSON5 from 'json5'
|
||||
import { jsonrepair } from 'jsonrepair'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
export type LLMInput = bp.interfaces.llm.actions.generateContent.input.Input
|
||||
export type LLMOutput = bp.interfaces.llm.actions.generateContent.output.Output
|
||||
|
||||
type LLMChoice = LLMOutput['choices'][number]
|
||||
type PredictResponse = {
|
||||
success: boolean
|
||||
json: object
|
||||
}
|
||||
|
||||
const tryParseJson = (str: string) => {
|
||||
try {
|
||||
return JSON5.parse(jsonrepair(str))
|
||||
} catch {
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
export const parseLLMOutput = (output: LLMOutput): PredictResponse => {
|
||||
const mappedChoices: LLMChoice['content'][] = output.choices.map((choice) => choice.content)
|
||||
const firstChoice = mappedChoices[0]!
|
||||
return {
|
||||
success: true,
|
||||
json: tryParseJson(firstChoice as string),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import * as gen from './generate-content'
|
||||
import * as rewrite from './rewrite-prompt'
|
||||
import * as bp from '.botpress'
|
||||
|
||||
const plugin = new bp.Plugin({
|
||||
actions: {},
|
||||
})
|
||||
|
||||
plugin.on.beforeOutgoingMessage('*', async ({ data: message, configuration, actions }) => {
|
||||
if (message.type !== 'text') {
|
||||
console.debug('Ignoring non-text message')
|
||||
return
|
||||
}
|
||||
|
||||
console.debug('Rewriting message:', message.payload.text)
|
||||
|
||||
const text = message.payload.text as string
|
||||
|
||||
const { model, personality } = configuration
|
||||
|
||||
const input = rewrite.prompt({
|
||||
model,
|
||||
personality,
|
||||
payload: text,
|
||||
})
|
||||
const output = await actions.llm.generateContent(input)
|
||||
|
||||
const { success, json } = gen.parseLLMOutput(output)
|
||||
|
||||
const parseResult = rewrite.responseSchema.safeParse(json)
|
||||
if (!success || !parseResult.success) {
|
||||
console.debug('Failed to rewrite message')
|
||||
return { data: message }
|
||||
}
|
||||
|
||||
message.payload.text = parseResult.data.payload
|
||||
return { data: message }
|
||||
})
|
||||
|
||||
export default plugin
|
||||
@@ -0,0 +1,48 @@
|
||||
import { z } from '@botpress/sdk'
|
||||
import dedent from 'dedent'
|
||||
import { LLMInput } from './generate-content'
|
||||
|
||||
export const responseSchema = z.object({
|
||||
payload: z.string(),
|
||||
})
|
||||
|
||||
type PromptArgs = {
|
||||
model: string
|
||||
personality: string
|
||||
payload: string
|
||||
}
|
||||
|
||||
const systemPrompt = (args: PromptArgs): string => dedent`
|
||||
Please rewrite the below JSON messages in your own voice and personality.
|
||||
Do NOT CHANGE the nature and meaning of any of the messages.
|
||||
Do not add additional greetings, introduction or personality traits in the below messages.
|
||||
Just change the writing style.
|
||||
Preserve the numbering, ordering, meaning, casing and spacing.
|
||||
Only rewrite the main message text, keep buttons and choices as-is.
|
||||
|
||||
Your personality is as follows:
|
||||
---
|
||||
${args.personality}
|
||||
---
|
||||
`
|
||||
|
||||
const userPrompt = (args: PromptArgs): string => dedent`
|
||||
\`\`\`json
|
||||
{ "payload": ${args.payload} }
|
||||
\`\`\`
|
||||
|
||||
type OutputFormat = ${responseSchema.toTypescriptType({ treatDefaultAsOptional: true })}
|
||||
`
|
||||
|
||||
export const prompt = (args: PromptArgs): LLMInput => ({
|
||||
model: { id: args.model },
|
||||
responseFormat: 'json_object',
|
||||
temperature: 0,
|
||||
systemPrompt: systemPrompt(args),
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: userPrompt(args),
|
||||
},
|
||||
],
|
||||
})
|
||||
Reference in New Issue
Block a user