const axios = require('axios');
const http = require('http');

// View our quick start guide to get your API key:
// https://www.voiceflow.com/api/dialog-manager#section/Quick-Start
const apiKeys = ['VF.DM.64ffbfa081aaaf0008374b1a.ukufvrrAYWvsLSCA', 'VF.DM.5f6c3d9c0c8a9f0008f7b1b2.kyjvrrAYWvsLSCB',
'VF.DM.7e8d4e7c0f9baf0009f8b1c3.lzjvrrAYWvsLSCC']; // Array of API keys
const userID = 'user_123'; // Unique ID used to track conversation state

const readBody = (res, json, onData) => new Promise((resolve, reject) => {
let buffer = '';

res.on('data', chunk => {
    onData?.(chunk.toString());
    buffer += chunk;
});

res.on('end', () => {
    try {
        if (json) buffer = JSON.parse(buffer);
        resolve(buffer);
    } catch (e) {
        console.error(buffer);
        reject(e);
    }
});

})

function isObject (value) {
return Object.prototype.toString.call(value) === '[object Object]'
}

async function startInteract(messages) {
return new Promise(async (resolve, reject) => {
const body = {
action: {
type: 'text',
payload: messages,
},
};
try {
// Start a conversation
// Randomly select an API key from the array
const apiKey = apiKeys[Math.floor(Math.random() * apiKeys.length)];
const response = await axios({
method: 'POST',
baseURL: 'https://general-runtime.voiceflow.com',
url: /state/user/${userID}/interact,
headers: {
Authorization: apiKey,
},
data: body,
});
// Log the response
if(!response.data[1]?.payload?.message)
console.log(response.data)
resolve(response.data[1]?.payload?.message)
}
catch(e) {
// If the error message is "token quota exceeded", remove the API key from the array
if (e.message === "[token quota exceeded]") {
const index = apiKeys.indexOf(apiKey);
if (index > -1) {
apiKeys.splice(index, 1);
console.log("Removed expired API key:", apiKey);
}
}
reject(e)
}
})
}

function preparePrompt(messages) {
return messages.filter(m => m.content?.trim()).map(m => {
let author = '';
switch (m.role) {
case 'user': author = 'Human'; break;
case 'assistant': author = 'Assistant'; break;
case 'system': author = 'System Note'; break;
default: author = m.role; break;
}

    return `${author}: ${m.content.trim()}`;
}).join('\n') + `\nAssistant: `;

}

async function main() {
const server = http.createServer(async (req, res) => {
if (req.method.toUpperCase() === 'POST') {
if(!apiKeys.length) { // If the array of API keys is empty, log an error message
console.log("Нет API ключей.")
res.end()
return
}
const body = await readBody(req, true);
const [, modelName] = req.url.split('/');
let {
messages,
} = body;
res.setHeader('Content-Type', 'application/json');
const id = chatcmpl-${(Math.random().toString(36).slice(2))};
const created = Math.floor(Date.now() / 1000);
if(modelName == "anthropic") {

            messages = preparePrompt(messages)
        }
        else messages = JSON.stringify(messages)
        let result = ""
        console.log("Ожидаем ответа...")
        while(!result) {
            try {
                result = await startInteract(messages);
                console.log("Ответ Voiceflow:\n\n", result)
            } catch (error) {
                result = error
            }
        }
        if(isObject(result)) {
            result = JSON.stringify(result)
        }
        else if(result.startsWith("{")) {
            try {
                result = JSON.parse(result)
                if(result.content) result = result.content
                else if(result.assistant) result = result.assistant
            }
            catch(e) {console.log(e)}
        }

        else { result = result.replace(/\\n/g, ' \n').replace(/\"/g, '"') }
        res.write(JSON.stringify({
            id, created,
            object: 'chat.completion',
            model: "GPT-4",
            choices: [{
                message: {
                    role: 'assistant',
                    content: result,
                },
                finish_reason: 'stop',
                index: 0,
            }]
        }))
        res.end();
    } else {
        res.setHeader('Content-Type', 'application/json');
        res.write(JSON.stringify({
            object: 'list',
            data: [
                { id: 'GPT-4', object: 'model', created: Date.now(), owned_by: 'OpenAI', permission: [], root: 'GPT-4', parent: null },
                { id: 'Claude', object: 'model', created: Date.now(), owned_by: 'Anthropic', permission: [], root: 'Claude', parent: null },
            ]
        }));
    }
    res.end();
});

server.listen(5006, '0.0.0.0', () => {
    console.log('Voiceflow с промптами в формате GPT-4: http://127.0.0.1:5006/\n' +
                'Промпты в формате Claude (human/assistant): http://127.0.0.1:5006/anthropic');
});

}

main().catch(console.error);

Edit Report
Pub: 27 Sep 2023 15:04 UTC
Views: 134