Skip to content

Commit

Permalink
refactor: correct model used in chat, code style refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
dnovacik committed Feb 17, 2024
1 parent 56f6a09 commit 17c8a3c
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 167 deletions.
54 changes: 15 additions & 39 deletions src/backend/services/ollama.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { app, ipcMain } from 'electron';
import { Ollama, ProgressResponse } from 'ollama';
import { Ollama } from 'ollama';
import { execFile, ChildProcess } from 'child_process';
import fs from 'fs';
import { isDev, sendOllamaStatusToRenderer } from '..';
import { sendOllamaStatusToRenderer } from '..';
import { MOR_PROMPT } from './prompts';

// events
import { IpcMainChannel, OllamaChannel } from '../../events';
import { IpcMainChannel } from '../../events';
import {
createDirectoryElevated,
executeCommandElevated,
getDefaultAppDataPathByPlatform,
getExecutablePathByPlatform,
killProcess,
runDelayed,
Expand All @@ -22,7 +21,6 @@ import { logger } from './logger';

// constants
const DEFAULT_OLLAMA_URL = 'http://127.0.0.1:11434/';
const DEFAULT_OLLAMA_MODEL = 'mistral';

// commands
export const SERVE_OLLAMA_CMD = 'ollama serve';
Expand All @@ -42,7 +40,7 @@ export const loadOllama = async () => {
});

await sendOllamaStatusToRenderer(
`Local instance of ollama is running and connected at ${DEFAULT_OLLAMA_URL}`,
`local instance of ollama is running and connected at ${DEFAULT_OLLAMA_URL}`,
);

return true;
Expand All @@ -58,7 +56,7 @@ export const loadOllama = async () => {
});

await sendOllamaStatusToRenderer(
`Local instance of ollama is running and connected at ${DEFAULT_OLLAMA_URL}`,
`local instance of ollama is running and connected at ${DEFAULT_OLLAMA_URL}`,
);

return true;
Expand All @@ -73,7 +71,7 @@ export const isOllamaInstanceRunning = async (url?: string): Promise<boolean> =>
try {
const usedUrl = url ?? DEFAULT_OLLAMA_URL;

await sendOllamaStatusToRenderer(`Checking if ollama instance is running at ${usedUrl}`);
await sendOllamaStatusToRenderer(`checking if ollama instance is running at ${usedUrl}`);

const ping = await fetch(usedUrl);

Expand All @@ -84,7 +82,7 @@ export const isOllamaInstanceRunning = async (url?: string): Promise<boolean> =>
};

export const packedExecutableOllamaSpawn = async (customDataPath?: string) => {
await sendOllamaStatusToRenderer(`Trying to spawn locally installed ollama`);
await sendOllamaStatusToRenderer(`trying to spawn locally installed ollama`);

try {
spawnLocalExecutable(customDataPath);
Expand Down Expand Up @@ -145,25 +143,19 @@ export const getOllamaExecutableAndAppDataPath = (
};

export const askOllama = async (model: string, message: string) => {
//const engineeredPrompt = `${MOR_PROMPT}\n\nUser: ${message}\n\nResponse:`
return await ollama.chat({
model,
messages: [
{
role: 'system',
content: MOR_PROMPT
{
role: 'system',
content: MOR_PROMPT,
},
{
role: 'user',
content: ` Now answer the following question: ${message}. Response:`
}
]

{
role: 'user',
content: ` Now answer the following question: ${message}. Response:`,
},
],
});
/*return await ollama.generate({
model: model,
prompt: engineeredPrompt
})*/
};

export const getOrPullModel = async (model: string) => {
Expand Down Expand Up @@ -203,22 +195,6 @@ export const getAllLocalModels = async () => {
return await ollama.list();
};

export const consumeStream = async (stream: AsyncGenerator<ProgressResponse, any, unknown>) => {
for await (const part of stream) {
if (part.digest) {
let percent = 0;

if (part.completed && part.total) {
percent = Math.round((part.completed / part.total) * 100);

return `${part.status} ${percent}%`;
}
} else {
return part.status;
}
}
};

export const stopOllama = async () => {
if (!ollamaProcess) {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/backend/services/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Response: "{
}"
`;

const errorHandling = `If a question is initiating a buy or transfer transaction and the user doesn't specify an amount in ETH. Gently decline to send the transaction
export const errorHandling = `If a question is initiating a buy or transfer transaction and the user doesn't specify an amount in ETH. Gently decline to send the transaction
and request the amount to buy or transfer (depending on their transaction type) in ethereum.
If a question is initiating a sell transaction and the user doesn't specify an amount in tokens. Gently decline to send the transaction
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const AppRoot = () => {

return;
} else {
console.error(`Something went wrong with pulling model ${'mistral'}`);
console.error(`Something went wrong with pulling model ${'orca-mini'}`);
}
}

Expand Down
191 changes: 107 additions & 84 deletions src/frontend/utils/transaction.ts
Original file line number Diff line number Diff line change
@@ -1,99 +1,122 @@
import { ethers } from "ethers";
import { SDKProvider } from "@metamask/sdk";
import { transactionParams } from "./types";
import { ethers } from 'ethers';
import { SDKProvider } from '@metamask/sdk';
import { Transaction, TransactionParams } from './types';

export const isTransactionIntiated = (transaction: transactionParams) => {
return !(Object.keys(transaction).length === 0);
}
export const isTransactionInitiated = (transaction: TransactionParams) => {
return !(Object.keys(transaction).length === 0);
};

export const buildTransaction = (transaction: transactionParams, account: string | undefined, gasPrice: string, provider: SDKProvider | undefined) => {
const transactionType = transaction.type.toLowerCase();

let tx: any
switch (transactionType) {
case "transfer":
tx = buildTransferTransaction(transaction, account, gasPrice);
break;
default:
throw Error(`Transaction of type ${transactionType} is not yet supported`);
}
//returned wrapped call with method for metamask with transaction params
return {
"method": "eth_sendTransaction",
"params": [tx]
}
export const buildTransaction = (
transaction: TransactionParams,
account: string,
gasPrice: string,
) => {
const transactionType = transaction.type.toLowerCase();

let tx: Transaction;

switch (transactionType) {
case 'transfer':
tx = buildTransferTransaction(transaction, account, gasPrice);
break;
default:
throw Error(`Transaction of type ${transactionType} is not yet supported`);
}

const buildTransferTransaction = (transaction: transactionParams, account: string | undefined, gasPrice: any) => {
return {
from: account,
to: transaction.targetAddress,
gas: "0x76c0", //for more complex tasks estimate this from metamast
gasPrice: gasPrice,
value: '0x' + ethers.parseEther(transaction.ethAmount).toString(16),
data: "0x000000"
}
}
// returned wrapped call with method for metamask with transaction params
return {
method: 'eth_sendTransaction',
params: [tx],
};
};

const buildTransferTransaction = (
transaction: TransactionParams,
account: string,
gasPrice: any,
): Transaction => {
return {
from: account,
to: transaction.targetAddress,
gas: '0x76c0', //for more complex tasks estimate this from metamast
gasPrice: gasPrice,
value: '0x' + ethers.parseEther(transaction.ethAmount).toString(16),
data: '0x000000',
};
};

//TODO: take chain ID to get arb balance or w/e chain
const formatWalletBalance = (balanceWeiHex: string) => {
const balanceBigInt = BigInt(balanceWeiHex)
const balance = ethers.formatUnits(balanceBigInt, "ether");
return parseFloat(balance).toFixed(2) + " " + "ETH";
}

export const handleBalanceRequest = async (provider: SDKProvider | undefined, account: string | undefined, response: string) => {
const blockNumber = await provider?.request({
"method": "eth_blockNumber",
"params": []
});

const balanceWeiHex = await provider?.request({
"method": "eth_getBalance",
"params": [
account,
blockNumber
]
});
if(typeof balanceWeiHex === 'string'){
return response + " " + formatWalletBalance(balanceWeiHex);
} else {
console.error('Failed to retrieve a valid balance.');
throw Error('Invalid Balance Recieved from MetaMask.')
}
}
const balanceBigInt = BigInt(balanceWeiHex);
const balance = ethers.formatUnits(balanceBigInt, 'ether');

return `${parseFloat(balance).toFixed(2)} ETH`;
};

export const handleBalanceRequest = async (
provider: SDKProvider | undefined,
account: string | undefined,
response: string,
) => {
const blockNumber = await provider?.request({
method: 'eth_blockNumber',
params: [],
});

const balanceWeiHex = await provider?.request({
method: 'eth_getBalance',
params: [account, blockNumber],
});

if (typeof balanceWeiHex === 'string') {
return `${response} ${formatWalletBalance(balanceWeiHex)}`;
} else {
console.error('Failed to retrieve a valid balance.');

throw Error('Invalid Balance Received from MetaMask.');
}
};

const estimateGasWithOverHead = (estimatedGasMaybe: string) => {
const estimatedGas = parseInt(estimatedGasMaybe, 16);
//console.log("Gas Limit: " + estimatedGas)
const gasLimitWithOverhead = Math.ceil(estimatedGas * 5);
return "0x" + gasLimitWithOverhead.toString(16);
}

export const handleTransactionRequest = async (provider: SDKProvider | undefined, transaction: transactionParams, account: string | undefined) => {
const gasPrice = await provider?.request({
"method": "eth_gasPrice",
"params": []
});
//Sanity Check
if(typeof gasPrice !== 'string'){
const estimatedGas = parseInt(estimatedGasMaybe, 16);
const gasLimitWithOverhead = Math.ceil(estimatedGas * 5);

return `0x${gasLimitWithOverhead.toString(16)}`;
};

export const handleTransactionRequest = async (
provider: SDKProvider | undefined,
transaction: TransactionParams,
account: string,
) => {
const gasPrice = await provider?.request({
method: 'eth_gasPrice',
params: [],
});

// Sanity Check
if (typeof gasPrice !== 'string') {
console.error('Failed to retrieve a valid gasPrice');
throw new Error('Invalid gasPrice received');
}
let builtTx = buildTransaction(transaction, account, gasPrice, provider);

let estimatedGas = await provider?.request({
"method": "eth_estimateGas",
"params": [builtTx]
});
//Sanity Check
if(typeof estimatedGas !== 'string'){
throw new Error('Invalid gasPrice received');
}

const builtTx = buildTransaction(transaction, account, gasPrice);

const estimatedGas = await provider?.request({
method: 'eth_estimateGas',
params: [builtTx],
});

//Sanity Check
if (typeof estimatedGas !== 'string') {
console.error('Failed to estimate Gas with metamask');

throw new Error('Invalid gasPrice received');
}
}

const gasLimitWithOverhead = estimateGasWithOverHead(estimatedGas)
builtTx.params[0].gas = gasLimitWithOverhead; // Update the transaction with the new gas limit in hex
return builtTx
}
const gasLimitWithOverhead = estimateGasWithOverHead(estimatedGas);
builtTx.params[0].gas = gasLimitWithOverhead; // Update the transaction with the new gas limit in hex

return builtTx;
};
19 changes: 14 additions & 5 deletions src/frontend/utils/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
export type ModelResponse = {
response: string;
transaction: transactionParams
response: string;
transaction: TransactionParams;
};

export type transactionParams = {
[key: string]: string
}
export type TransactionParams = {
[key: string]: string;
};

export type Transaction = {
from: string;
to: string;
gas: string;
gasPrice: any;
value: string;
data: string;
};
Loading

0 comments on commit 17c8a3c

Please sign in to comment.