mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-03-28 14:56:24 +01:00
Merge remote-tracking branch 'refs/remotes/upstream/main' into Tasks-more-relevant-docs-and-code-exception-fixes
# Conflicts: # src/agent/prompter.js
This commit is contained in:
commit
2127e5b9fb
9 changed files with 118 additions and 33 deletions
|
@ -7,5 +7,6 @@
|
|||
"GROQCLOUD_API_KEY": "",
|
||||
"HUGGINGFACE_API_KEY": "",
|
||||
"QWEN_API_KEY": "",
|
||||
"XAI_API_KEY": ""
|
||||
"XAI_API_KEY": "",
|
||||
"DEEPSEEK_API_KEY": ""
|
||||
}
|
||||
|
|
|
@ -38,10 +38,9 @@
|
|||
],
|
||||
|
||||
[
|
||||
{"role": "system", "content": "work together with the other bot"},
|
||||
{"role": "assistant", "content": "!startConversation(\"terrance\", \"Hey gpt! Let's work together on this.\"))"},
|
||||
{"role": "user", "content": "terrance: (FROM OTHER BOT)Sounds good, what should we do first?"},
|
||||
{"role": "assistant", "content": "I'll start by collecting some resources. !collectBlocks('stone', 10)"}
|
||||
{"role": "system", "content": "work together with the other bot to build a house"},
|
||||
{"role": "assistant", "content": "!startConversation(\"terrance\", \"Hey gpt! Let's work together to build a house. Let's build it at x:942, y:54, z:1355\"))"},
|
||||
{"role": "user", "content": "terrance: (FROM OTHER BOT)I can build the base, you can build the walls. !newAction(\"Build a 10x10 wall of a house at x:942, y:54, z:1355\")"}
|
||||
],
|
||||
|
||||
[
|
||||
|
|
7
profiles/deepseek.json
Normal file
7
profiles/deepseek.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "deepseek",
|
||||
|
||||
"model": "deepseek-chat",
|
||||
|
||||
"embedding": "openai"
|
||||
}
|
|
@ -18,6 +18,7 @@ export default
|
|||
// "./profiles/llama.json",
|
||||
// "./profiles/qwen.json",
|
||||
// "./profiles/grok.json",
|
||||
// "./profiles/deepseek.json",
|
||||
|
||||
// using more than 1 profile requires you to /msg each bot indivually
|
||||
],
|
||||
|
|
|
@ -266,13 +266,12 @@ export const actionsList = [
|
|||
'num': { type: 'int', description: 'The number of times to smelt the item.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
||||
},
|
||||
perform: runAsAction(async (agent, item_name, num) => {
|
||||
let response = await skills.smeltItem(agent.bot, item_name, num);
|
||||
if (response.indexOf('Successfully') !== -1) {
|
||||
// there is a bug where the bot's inventory is not updated after smelting
|
||||
// only updates after a restart
|
||||
agent.cleanKill(response + ' Safely restarting to update inventory.');
|
||||
let success = await skills.smeltItem(agent.bot, item_name, num);
|
||||
if (success) {
|
||||
setTimeout(() => {
|
||||
agent.cleanKill('Safely restarting to update inventory.');
|
||||
}, 500);
|
||||
}
|
||||
return response;
|
||||
})
|
||||
},
|
||||
{
|
||||
|
@ -386,12 +385,12 @@ export const actionsList = [
|
|||
'message': { type: 'string', description: 'The message to send.' },
|
||||
},
|
||||
perform: async function (agent, player_name, message) {
|
||||
if (convoManager.inConversation() && !convoManager.inConversation(player_name))
|
||||
return 'You are already in conversation with other bot.';
|
||||
if (!convoManager.isOtherAgent(player_name))
|
||||
return player_name + ' is not a bot, cannot start conversation.';
|
||||
if (convoManager.inConversation(player_name))
|
||||
agent.history.add('system', 'You are already in conversation with ' + player_name + ' Don\'t use this command to talk to them.');
|
||||
if (convoManager.inConversation() && !convoManager.inConversation(player_name))
|
||||
convoManager.forceEndCurrentConversation();
|
||||
else if (convoManager.inConversation(player_name))
|
||||
agent.history.add('system', 'You are already in conversation with ' + player_name + '. Don\'t use this command to talk to them.');
|
||||
convoManager.startConversation(player_name, message);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -172,9 +172,13 @@ class ConversationManager {
|
|||
async recieveFromBot(sender, recieved) {
|
||||
const convo = this._getConvo(sender);
|
||||
|
||||
if (convo.ignore_until_start && !recieved.start)
|
||||
return;
|
||||
|
||||
// check if any convo is active besides the sender
|
||||
if (Object.values(this.convos).some(c => c.active && c.name !== sender)) {
|
||||
if (this.inConversation() && !this.inConversation(sender)) {
|
||||
this.sendToBot(sender, `I'm talking to someone else, try again later. !endConversation("${sender}")`, false, false);
|
||||
this.endConversation(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -182,8 +186,6 @@ class ConversationManager {
|
|||
convo.reset();
|
||||
this.startConversationFromOtherBot(sender);
|
||||
}
|
||||
if (convo.ignore_until_start)
|
||||
return;
|
||||
|
||||
this._clearMonitorTimeouts();
|
||||
convo.queue(recieved);
|
||||
|
@ -230,6 +232,7 @@ class ConversationManager {
|
|||
endConversation(sender) {
|
||||
if (this.convos[sender]) {
|
||||
this.convos[sender].end();
|
||||
if (this.activeConversation.name === sender) {
|
||||
this._stopMonitor();
|
||||
this.activeConversation = null;
|
||||
if (self_prompter_paused && !this.inConversation()) {
|
||||
|
@ -237,6 +240,7 @@ class ConversationManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endAllConversations() {
|
||||
for (const sender in this.convos) {
|
||||
|
@ -247,6 +251,14 @@ class ConversationManager {
|
|||
}
|
||||
}
|
||||
|
||||
forceEndCurrentConversation() {
|
||||
if (this.activeConversation) {
|
||||
let sender = this.activeConversation.name;
|
||||
this.sendToBot(sender, '!endConversation("' + sender + '")', false, false);
|
||||
this.endConversation(sender);
|
||||
}
|
||||
}
|
||||
|
||||
scheduleSelfPrompter() {
|
||||
self_prompter_paused = true;
|
||||
}
|
||||
|
@ -332,8 +344,8 @@ function _handleFullInMessage(sender, recieved) {
|
|||
let message = _tagMessage(recieved.message);
|
||||
if (recieved.end) {
|
||||
convoManager.endConversation(sender);
|
||||
sender = 'system'; // bot will respond to system instead of the other bot
|
||||
message = `Conversation with ${sender} ended with message: "${message}"`;
|
||||
sender = 'system'; // bot will respond to system instead of the other bot
|
||||
}
|
||||
else if (recieved.start)
|
||||
agent.shut_up = false;
|
||||
|
@ -348,6 +360,8 @@ function _tagMessage(message) {
|
|||
|
||||
async function _resumeSelfPrompter() {
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
if (self_prompter_paused && !convoManager.inConversation()) {
|
||||
self_prompter_paused = false;
|
||||
agent.self_prompter.start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import { Qwen } from "../models/qwen.js";
|
|||
import { Grok } from "../models/grok.js";
|
||||
// import {cosineSimilarity} from "../utils/math.js";
|
||||
import {SkillLibrary} from "./library/skill_library.js";
|
||||
import { DeepSeek } from '../models/deepseek.js';
|
||||
|
||||
export class Prompter {
|
||||
constructor(agent, fp) {
|
||||
|
@ -32,7 +33,6 @@ export class Prompter {
|
|||
this.convo_examples = null;
|
||||
this.coding_examples = null;
|
||||
|
||||
|
||||
let name = this.profile.name;
|
||||
let chat = this.profile.model;
|
||||
this.cooldown = this.profile.cooldown ? this.profile.cooldown : 0;
|
||||
|
@ -63,6 +63,8 @@ export class Prompter {
|
|||
chat.api = 'qwen';
|
||||
else if (chat.model.includes('grok'))
|
||||
chat.api = 'xai';
|
||||
else if (chat.model.includes('deepseek'))
|
||||
chat.api = 'deepseek';
|
||||
else
|
||||
chat.api = 'ollama';
|
||||
}
|
||||
|
@ -90,6 +92,8 @@ export class Prompter {
|
|||
this.chat_model = new Qwen(chat.model, chat.url);
|
||||
else if (chat.api === 'xai')
|
||||
this.chat_model = new Grok(chat.model, chat.url);
|
||||
else if (chat.api === 'deepseek')
|
||||
this.chat_model = new DeepSeek(chat.model, chat.url);
|
||||
else
|
||||
throw new Error('Unknown API:', api);
|
||||
|
||||
|
@ -162,6 +166,7 @@ export class Prompter {
|
|||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async replaceStrings(prompt, messages, examples=null, to_summarize=[], last_goals=null) {
|
||||
prompt = prompt.replaceAll('$NAME', this.agent.name);
|
||||
|
||||
|
@ -241,6 +246,9 @@ export class Prompter {
|
|||
let current_msg_time = this.most_recent_msg_time;
|
||||
for (let i = 0; i < 3; i++) { // try 3 times to avoid hallucinations
|
||||
await this.checkCooldown();
|
||||
if (current_msg_time !== this.most_recent_msg_time) {
|
||||
return '';
|
||||
}
|
||||
let prompt = this.profile.conversing;
|
||||
prompt = await this.replaceStrings(prompt, messages, this.convo_examples);
|
||||
let generation = await this.chat_model.sendRequest(messages, prompt);
|
||||
|
|
56
src/models/deepseek.js
Normal file
56
src/models/deepseek.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
import OpenAIApi from 'openai';
|
||||
import { getKey, hasKey } from '../utils/keys.js';
|
||||
import { strictFormat } from '../utils/text.js';
|
||||
|
||||
export class DeepSeek {
|
||||
constructor(model_name, url) {
|
||||
this.model_name = model_name;
|
||||
|
||||
let config = {};
|
||||
|
||||
config.baseURL = url || 'https://api.deepseek.com';
|
||||
config.apiKey = getKey('DEEPSEEK_API_KEY');
|
||||
|
||||
this.openai = new OpenAIApi(config);
|
||||
}
|
||||
|
||||
async sendRequest(turns, systemMessage, stop_seq='***') {
|
||||
let messages = [{'role': 'system', 'content': systemMessage}].concat(turns);
|
||||
|
||||
messages = strictFormat(messages);
|
||||
|
||||
const pack = {
|
||||
model: this.model_name || "deepseek-chat",
|
||||
messages,
|
||||
stop: stop_seq,
|
||||
};
|
||||
|
||||
let res = null;
|
||||
try {
|
||||
console.log('Awaiting deepseek api response...')
|
||||
// console.log('Messages:', messages);
|
||||
let completion = await this.openai.chat.completions.create(pack);
|
||||
if (completion.choices[0].finish_reason == 'length')
|
||||
throw new Error('Context length exceeded');
|
||||
console.log('Received.')
|
||||
res = completion.choices[0].message.content;
|
||||
}
|
||||
catch (err) {
|
||||
if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) {
|
||||
console.log('Context length exceeded, trying again with shorter context.');
|
||||
return await this.sendRequest(turns.slice(1), systemMessage, stop_seq);
|
||||
} else {
|
||||
console.log(err);
|
||||
res = 'My brain disconnected, try again.';
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
async embed(text) {
|
||||
throw new Error('Embeddings are not supported by Deepseek.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -85,9 +85,9 @@
|
|||
`}
|
||||
</div>
|
||||
</div>
|
||||
<button class="stop-btn" onclick="killAllAgents()">Stop All</button>
|
||||
<button class="stop-btn" onclick="shutdown()">Shutdown</button>
|
||||
`).join('') :
|
||||
`).join('') +
|
||||
`<button class="stop-btn" onclick="killAllAgents()">Stop All</button>
|
||||
<button class="stop-btn" onclick="shutdown()">Shutdown</button>` :
|
||||
'<div class="agent">No agents connected</div>';
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue