ai-code-writer
Version:
An AI code writer application using OpenAI APIs for audio transcription and chat completion.
232 lines (231 loc) • 10.5 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ChatResultEntity_1 = __importDefault(require("../../../../Core/Conversation/UseCase/ChatResultEntity"));
class OpenAi {
constructor(openai, temperature, logger, model, maxTokens, toolCallConverter, messageEncoder) {
this.openai = openai;
this.temperature = temperature;
this.logger = logger;
this.model = model;
this.maxTokens = maxTokens;
this.toolCallConverter = toolCallConverter;
this.messageEncoder = messageEncoder;
this.fileToolDefinitions = [
{
type: 'function',
function: {
name: 'writeFile',
description: 'Writes content to a specified file path.',
parameters: {
type: 'object',
properties: {
filePath: {
type: 'string',
description: 'The path where the file will be written.'
},
content: {
type: 'string',
description: 'The content to write into the file.'
}
},
required: ['filePath', 'content']
}
}
},
{
type: 'function',
function: {
name: 'deleteFile',
description: 'Deletes a file at the specified path.',
parameters: {
type: 'object',
properties: {
filePath: {
type: 'string',
description: 'The path of the file to delete.'
}
},
required: ['filePath']
}
}
},
{
type: 'function',
function: {
name: 'moveFile',
description: 'Moves a file from a source path to a destination path.',
parameters: {
type: 'object',
properties: {
sourcePath: {
type: 'string',
description: 'The current path of the file.'
},
destinationPath: {
type: 'string',
description: 'The new path for the file.'
}
},
required: ['sourcePath', 'destinationPath']
}
}
},
{
type: 'function',
function: {
name: 'readFile',
description: 'Reads the content of a file at the specified path.',
parameters: {
type: 'object',
properties: {
filePath: {
type: 'string',
description: 'The path of the file to read.'
}
},
required: ['filePath']
}
}
},
{
type: 'function',
function: {
name: 'readAllFiles',
description: 'Reads all project files and adding them as system messages to conversation.'
}
}
];
this.actionToolDefinitions = [
{
type: 'function',
function: {
name: 'pauseCommand',
description: 'Disabled the audio input. NEVER call that on begin of the conversation'
}
},
{
type: 'function',
function: {
name: 'suspendCommand',
description: 'Switch to a suspend mode. That MUST be called after ending a topic. ' +
'You MUST tell that the user before calling this command.'
}
},
{
type: 'function',
function: {
name: 'resumeCommand',
description: 'Resumes from suspend mode to normal operation.'
}
},
{
type: 'function',
function: {
name: 'exitCommand',
description: 'Ending the programm.'
}
}
];
}
runChat(messages) {
return __awaiter(this, void 0, void 0, function* () {
var _a, e_1, _b, _c;
var _d, _e, _f, _g;
const result = new ChatResultEntity_1.default();
let inputTokens = 0;
let outputTokens = 0;
let toolCalls = [];
try {
const formattedMessages = this.messageEncoder.encode(messages);
const body = {
stream: true,
model: this.model,
max_completion_tokens: this.maxTokens,
presence_penalty: 0,
frequency_penalty: 0,
temperature: this.temperature,
top_p: 1,
messages: formattedMessages,
parallel_tool_calls: true,
tools: [
...this.fileToolDefinitions,
...this.actionToolDefinitions
],
stream_options: {
include_usage: true
}
};
const responseStream = yield this.openai.chat.completions.create(body);
let progress = 0;
this.logger.logProgress('Progress: ');
let finishReason = null;
try {
for (var _h = true, responseStream_1 = __asyncValues(responseStream), responseStream_1_1; responseStream_1_1 = yield responseStream_1.next(), _a = responseStream_1_1.done, !_a; _h = true) {
_c = responseStream_1_1.value;
_h = false;
const chunk = _c;
let delta = (_d = chunk.choices[0]) === null || _d === void 0 ? void 0 : _d.delta;
const content = (delta === null || delta === void 0 ? void 0 : delta.content) || '';
result.content += content;
progress += Buffer.byteLength(content);
finishReason = ((_e = chunk.choices[0]) === null || _e === void 0 ? void 0 : _e.finish_reason) || finishReason;
inputTokens += ((_f = chunk.usage) === null || _f === void 0 ? void 0 : _f.prompt_tokens) || 0;
outputTokens += ((_g = chunk.usage) === null || _g === void 0 ? void 0 : _g.completion_tokens) || 0;
if (delta === null || delta === void 0 ? void 0 : delta.tool_calls)
delta.tool_calls.forEach(call => this.mergeToolCalls(toolCalls, call));
if (progress >= 256) {
this.logger.logProgress('.');
progress = 0;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (!_h && !_a && (_b = responseStream_1.return)) yield _b.call(responseStream_1);
}
finally { if (e_1) throw e_1.error; }
}
result.toolCalls = this.toolCallConverter.convert(toolCalls);
result.conversationComplete = finishReason != 'tool_calls';
this.logger.log('Done \n');
this.logger.log('Input Tokens : ' + inputTokens);
this.logger.log('Output Tokens: ' + outputTokens);
return result;
}
catch (error) {
this.logger.logError('Progress: Failed\n');
throw error;
}
});
}
mergeToolCalls(toolCalls, call) {
const foundCall = toolCalls.find(c => c.index == call.index);
if (!foundCall) {
call.function.arguments = call.function.arguments || '';
toolCalls.push(call);
return;
}
foundCall.function.arguments += call.function.arguments || '';
}
}
exports.default = OpenAi;
;