Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New chat history format #116

Merged
merged 5 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 25 additions & 42 deletions contracts/contracts/Agent.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,9 @@ contract Agent {

string public prompt;

struct Message {
string role;
string content;
}

struct AgentRun {
address owner;
Message[] messages;
IOracle.Message[] messages;
uint responsesCount;
uint8 max_iterations;
bool is_finished;
Expand Down Expand Up @@ -102,14 +97,10 @@ contract Agent {
run.responsesCount = 0;
run.max_iterations = max_iterations;

Message memory systemMessage;
systemMessage.content = prompt;
systemMessage.role = "system";
IOracle.Message memory systemMessage = createTextMessage("system", prompt);
run.messages.push(systemMessage);

Message memory newMessage;
newMessage.content = query;
newMessage.role = "user";
IOracle.Message memory newMessage = createTextMessage("user", query);
run.messages.push(newMessage);

uint currentId = agentRunCount;
Expand All @@ -134,9 +125,7 @@ contract Agent {
AgentRun storage run = agentRuns[runId];

if (!compareStrings(errorMessage, "")) {
Message memory newMessage;
newMessage.role = "assistant";
newMessage.content = errorMessage;
IOracle.Message memory newMessage = createTextMessage("assistant", errorMessage);
run.messages.push(newMessage);
run.responsesCount++;
run.is_finished = true;
Expand All @@ -147,10 +136,8 @@ contract Agent {
return;
}
if (!compareStrings(response.content, "")) {
Message memory assistantMessage;
assistantMessage.content = response.content;
assistantMessage.role = "assistant";
run.messages.push(assistantMessage);
IOracle.Message memory newMessage = createTextMessage("assistant", response.content);
run.messages.push(newMessage);
run.responsesCount++;
}
if (!compareStrings(response.functionName, "")) {
Expand Down Expand Up @@ -178,36 +165,18 @@ contract Agent {
result = errorMessage;
}

Message memory newMessage;
newMessage.role = "user";
newMessage.content = result;
IOracle.Message memory newMessage = createTextMessage("user", result);
run.messages.push(newMessage);
run.responsesCount++;
IOracle(oracleAddress).createOpenAiLlmCall(runId, config);
}

// @notice Retrieves the message history contents for a given agent run
// @param agentId The ID of the agent run
// @return An array of message contents
// @dev Called by teeML oracle
function getMessageHistoryContents(uint agentId) public view returns (string[] memory) {
string[] memory messages = new string[](agentRuns[agentId].messages.length);
for (uint i = 0; i < agentRuns[agentId].messages.length; i++) {
messages[i] = agentRuns[agentId].messages[i].content;
}
return messages;
}

// @notice Retrieves the roles of the messages in a given agent run
// @notice Retrieves the message history for a given agent run
// @param agentId The ID of the agent run
// @return An array of message roles
// @return An array of messages
// @dev Called by teeML oracle
function getMessageHistoryRoles(uint agentId) public view returns (string[] memory) {
string[] memory roles = new string[](agentRuns[agentId].messages.length);
for (uint i = 0; i < agentRuns[agentId].messages.length; i++) {
roles[i] = agentRuns[agentId].messages[i].role;
}
return roles;
function getMessageHistory(uint agentId) public view returns (IOracle.Message[] memory) {
return agentRuns[agentId].messages;
}

// @notice Checks if a given agent run is finished
Expand All @@ -217,6 +186,20 @@ contract Agent {
return agentRuns[runId].is_finished;
}

// @notice Creates a text message with the given role and content
// @param role The role of the message
// @param content The content of the message
// @return The created message
function createTextMessage(string memory role, string memory content) private pure returns (IOracle.Message memory) {
IOracle.Message memory newMessage = IOracle.Message({
role: role,
content: new IOracle.Content[](1)
});
newMessage.content[0].contentType = "text";
newMessage.content[0].value = content;
return newMessage;
}

// @notice Compares two strings for equality
// @param a The first string
// @param b The second string
Expand Down
49 changes: 19 additions & 30 deletions contracts/contracts/AnthropicChatGpt.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,7 @@ contract AnthropicChatGpt {
ChatRun storage run = chatRuns[chatRunsCount];

run.owner = msg.sender;
IOracle.Message memory newMessage = IOracle.Message({
role: "user",
content: new IOracle.Content[](1)
});
newMessage.content[0].contentType = "text";
newMessage.content[0].value = message;
IOracle.Message memory newMessage = createTextMessage("user", message);
run.messages.push(newMessage);
run.messagesCount++;

Expand Down Expand Up @@ -122,12 +117,7 @@ contract AnthropicChatGpt {
);

if (!compareStrings(errorMessage, "")) {
IOracle.Message memory newMessage = IOracle.Message({
role: "assistant",
content: new IOracle.Content[](1)
});
newMessage.content[0].contentType = "text";
newMessage.content[0].value = errorMessage;
IOracle.Message memory newMessage = createTextMessage("assistant", errorMessage);
run.messages.push(newMessage);
run.messagesCount++;
} else {
Expand All @@ -137,12 +127,7 @@ contract AnthropicChatGpt {
} else {
toolRunning[runId] = "";
}
IOracle.Message memory newMessage = IOracle.Message({
role: "assistant",
content: new IOracle.Content[](1)
});
newMessage.content[0].contentType = "text";
newMessage.content[0].value = response.content;
IOracle.Message memory newMessage = createTextMessage("assistant", response.content);
run.messages.push(newMessage);
run.messagesCount++;
}
Expand All @@ -164,12 +149,7 @@ contract AnthropicChatGpt {
);
ChatRun storage run = chatRuns[runId];
if (compareStrings(errorMessage, "")) {
IOracle.Message memory newMessage = IOracle.Message({
role: "user",
content: new IOracle.Content[](1)
});
newMessage.content[0].contentType = "text";
newMessage.content[0].value = response;
IOracle.Message memory newMessage = createTextMessage("user", response);
run.messages.push(newMessage);
run.messagesCount++;
IOracle(oracleAddress).createLlmCall(runId, config);
Expand Down Expand Up @@ -226,12 +206,7 @@ contract AnthropicChatGpt {
run.owner == msg.sender, "Only chat owner can add messages"
);

IOracle.Message memory newMessage = IOracle.Message({
role: "user",
content: new IOracle.Content[](1)
});
newMessage.content[0].contentType = "text";
newMessage.content[0].value = message;
IOracle.Message memory newMessage = createTextMessage("user", message);
run.messages.push(newMessage);
run.messagesCount++;
// If there is a knowledge base, create a knowledge base query
Expand All @@ -256,6 +231,20 @@ contract AnthropicChatGpt {
return chatRuns[chatId].messages;
}

// @notice Creates a text message with the given role and content
// @param role The role of the message
// @param content The content of the message
// @return The created message
function createTextMessage(string memory role, string memory content) private pure returns (IOracle.Message memory) {
IOracle.Message memory newMessage = IOracle.Message({
role: role,
content: new IOracle.Content[](1)
});
newMessage.content[0].contentType = "text";
newMessage.content[0].value = content;
return newMessage;
}

// @notice Compares two strings for equality
// @param a The first string
// @param b The second string
Expand Down
48 changes: 22 additions & 26 deletions contracts/contracts/AnthropicSimpleLLM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ pragma solidity ^0.8.13;
import "./interfaces/IOracle.sol";

contract SimpleLLM {
address private oracleAddress = 0x68EC9556830AD097D661Df2557FBCeC166a0A075; // use latest: https://docs.galadriel.com/oracle-address
uint private runId = 0;
string public message;
address private oracleAddress; // use latest: https://docs.galadriel.com/oracle-address
IOracle.Message public message;
string public response;
IOracle.LlmRequest private config;

constructor() {
constructor(address initialOracleAddress) {
oracleAddress = initialOracleAddress;

config = IOracle.LlmRequest({
model: "claude-3-5-sonnet-20240620", // "claude-3-5-sonnet-20240620", "claude-3-opus-20240229", "claude-3-sonnet-20240229", "claude-3-haiku-20240307", "claude-2.1", "claude-2.0", "claude-instant-1.2"
frequencyPenalty: 21, // > 20 for null
Expand All @@ -30,16 +31,8 @@ contract SimpleLLM {
}

function sendMessage(string memory _message) public {
IOracle.Message memory newMessage = IOracle.Message({
role: "user",
content: new IOracle.Content[](1)
});
newMessage.content[0] = IOracle.Content({
contentType: "text",
value: _message
});
message = _message;
IOracle(oracleAddress).createLlmCall(runId, config);
message = createTextMessage("user", _message);
IOracle(oracleAddress).createLlmCall(0, config);
}

// required for Oracle
Expand All @@ -49,10 +42,7 @@ contract SimpleLLM {
string memory _errorMessage
) public {
require(msg.sender == oracleAddress, "Caller is not oracle");
if (
keccak256(abi.encodePacked(_errorMessage)) !=
keccak256(abi.encodePacked(""))
) {
if (bytes(_errorMessage).length > 0) {
response = _errorMessage;
} else {
response = _response.content;
Expand All @@ -63,16 +53,22 @@ contract SimpleLLM {
function getMessageHistory(
uint /*_runId*/
) public view returns (IOracle.Message[] memory) {
IOracle.Message[] memory messages = new IOracle.Message[](1);
messages[0] = message;
return messages;
}

// @notice Creates a text message with the given role and content
// @param role The role of the message
// @param content The content of the message
// @return The created message
function createTextMessage(string memory role, string memory content) private pure returns (IOracle.Message memory) {
IOracle.Message memory newMessage = IOracle.Message({
role: "user",
role: role,
content: new IOracle.Content[](1)
});
newMessage.content[0] = IOracle.Content({
contentType: "text",
value: message
});
IOracle.Message[] memory newMessages = new IOracle.Message[](1);
newMessages[0] = newMessage;
return newMessages;
newMessage.content[0].contentType = "text";
newMessage.content[0].value = content;
return newMessage;
}
}
Loading