feat: allow passing array of sections instead of entire message

Philipp Burckhardt 2023-06-16 20:03:02 -04:00
rodzic 3cce379a2d
commit f887ea239e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: A2C3BCA4F31D1DDD
3 zmienionych plików z 46 dodań i 24 usunięć

Wyświetl plik

@ -57,17 +57,18 @@ export class HumanFeedbackMechanismTwilio<
message: string,
choices: HumanFeedbackUserActions[]
): Promise<HumanFeedbackUserActions> {
message += '\n\n'
message += choices
.map(
(choice, idx) => `${idx} - ${HumanFeedbackUserActionMessages[choice]}`
)
.join('\n')
message += '\n\n'
message += 'Reply with the number of your choice.'
const response = await this._twilioClient.sendAndWaitForReply({
name: 'human-feedback-ask',
text: message,
text: [
message,
choices
.map(
(choice, idx) =>
`${idx} - ${HumanFeedbackUserActionMessages[choice]}`
)
.join('\n'),
'Reply with the number of your choice.'
],
timeoutMs: this._options.timeoutMs,
validate: (message) => {
const choice = parseInt(message.body)
@ -87,10 +88,11 @@ export class HumanFeedbackMechanismTwilio<
const { body: selectedOutput } =
await this._twilioClient.sendAndWaitForReply({
name: 'human-feedback-select',
text:
'Pick one output:' +
response.map((r, idx) => `\n${idx} - ${JSON.stringify(r)}`).join('') +
'\n\nReply with the number of your choice.',
text: [
'Pick one output:',
response.map((r, idx) => `\n${idx} - ${JSON.stringify(r)}`).join(''),
'Reply with the number of your choice.'
],
timeoutMs: this._options.timeoutMs,
validate: (message) => {
const choice = parseInt(message.body)
@ -110,10 +112,11 @@ export class HumanFeedbackMechanismTwilio<
const { body: selectedOutput } =
await this._twilioClient.sendAndWaitForReply({
name: 'human-feedback-select',
text:
'Select outputs:' +
response.map((r, idx) => `\n${idx} - ${JSON.stringify(r)}`).join('') +
'\n\nReply with a comma-separated list of the output numbers of your choice.',
text: [
'Select outputs:',
response.map((r, idx) => `\n${idx} - ${JSON.stringify(r)}`).join(''),
'Reply with a comma-separated list of the output numbers of your choice.'
],
timeoutMs: this._options.timeoutMs,
validate: (message) => {
const choices = message.body.split(',')

Wyświetl plik

@ -1,7 +1,7 @@
import defaultKy from 'ky'
import { DEFAULT_BOT_NAME } from '@/constants'
import { chunkString, sleep } from '@/utils'
import { chunkMultipleStrings, chunkString, sleep } from '@/utils'
export const TWILIO_CONVERSATION_API_BASE_URL =
'https://conversations.twilio.com/v1'
@ -101,9 +101,9 @@ export type TwilioSendAndWaitOptions = {
recipientPhoneNumber?: string
/**
* The text of the message to send.
* The text of the message to send (or an array of strings to send as separate messages).
*/
text: string
text: string | string[]
/**
* Friendly name of the conversation.
@ -245,10 +245,16 @@ export class TwilioConversationClient {
text
}: {
conversationSid: string
text: string
text: string | string[]
maxChunkLength?: number
}) {
const chunks = chunkString(text, TWILIO_SMS_LENGTH_SOFT_LIMIT)
let chunks
if (Array.isArray(text)) {
chunks = chunkMultipleStrings(text, TWILIO_SMS_LENGTH_SOFT_LIMIT)
} else {
chunks = chunkString(text, TWILIO_SMS_LENGTH_SOFT_LIMIT)
}
const out: TwilioConversationMessage[] = []
for (const chunk of chunks) {
const sent = await this.sendMessage({

Wyświetl plik

@ -84,8 +84,7 @@ export function chunkString(text: string, maxLength: number): string[] {
if (word.length > maxLength) {
// Truncate the word if it's too long and indicate that it was truncated:
chunks.push(word.substring(0, maxLength - 3) + '...')
} else if ((chunk + word + 1).length > maxLength) {
// +1 accounts for the space between words
} else if ((chunk + ' ' + word).length > maxLength) {
chunks.push(chunk.trim())
chunk = word
} else {
@ -100,6 +99,20 @@ export function chunkString(text: string, maxLength: number): string[] {
return chunks
}
/**
* Chunks an array of strings into an array of chunks while preserving existing sections.
*
* @param textSections - array of strings to chunk
* @param maxLength - maximum length of each chunk
* @returns array of chunks
*/
export function chunkMultipleStrings(
textSections: string[],
maxLength: number
): string[] {
return textSections.map((section) => chunkString(section, maxLength)).flat()
}
/**
* Stringifies a JSON value for use in an LLM prompt.
*