added model parameters obj to profile

This commit is contained in:
MaxRobinsonTheGreat 2025-02-04 13:02:57 -06:00
parent 8f545089e1
commit 60187e2317
17 changed files with 134 additions and 74 deletions

View file

@ -42,7 +42,7 @@ You can configure the agent's name, model, and prompts in their profile like `an
| OpenAI | `OPENAI_API_KEY` | `gpt-4o-mini` | [docs](https://platform.openai.com/docs/models) | | OpenAI | `OPENAI_API_KEY` | `gpt-4o-mini` | [docs](https://platform.openai.com/docs/models) |
| Google | `GEMINI_API_KEY` | `gemini-pro` | [docs](https://ai.google.dev/gemini-api/docs/models/gemini) | | Google | `GEMINI_API_KEY` | `gemini-pro` | [docs](https://ai.google.dev/gemini-api/docs/models/gemini) |
| Anthropic | `ANTHROPIC_API_KEY` | `claude-3-haiku-20240307` | [docs](https://docs.anthropic.com/claude/docs/models-overview) | | Anthropic | `ANTHROPIC_API_KEY` | `claude-3-haiku-20240307` | [docs](https://docs.anthropic.com/claude/docs/models-overview) |
| Replicate | `REPLICATE_API_KEY` | `meta/meta-llama-3-70b-instruct` | [docs](https://replicate.com/collections/language-models) | | Replicate | `REPLICATE_API_KEY` | `replicate/meta/meta-llama-3-70b-instruct` | [docs](https://replicate.com/collections/language-models) |
| Ollama (local) | n/a | `llama3` | [docs](https://ollama.com/library) | | Ollama (local) | n/a | `llama3` | [docs](https://ollama.com/library) |
| Groq | `GROQCLOUD_API_KEY` | `groq/mixtral-8x7b-32768` | [docs](https://console.groq.com/docs/models) | | Groq | `GROQCLOUD_API_KEY` | `groq/mixtral-8x7b-32768` | [docs](https://console.groq.com/docs/models) |
| Hugging Face | `HUGGINGFACE_API_KEY` | `huggingface/mistralai/Mistral-Nemo-Instruct-2407` | [docs](https://huggingface.co/models) | | Hugging Face | `HUGGINGFACE_API_KEY` | `huggingface/mistralai/Mistral-Nemo-Instruct-2407` | [docs](https://huggingface.co/models) |

View file

@ -1,5 +1,11 @@
{ {
"name": "gpt", "name": "gpt",
"model": "gpt-4o" "model": {
"model": "gpt-4o-mini",
"params": {
"temperature": 1,
"not_real": true
}
}
} }

View file

@ -1,6 +1,6 @@
import { History } from './history.js'; import { History } from './history.js';
import { Coder } from './coder.js'; import { Coder } from './coder.js';
import { Prompter } from './prompter.js'; import { Prompter } from '../models/prompter.js';
import { initModes } from './modes.js'; import { initModes } from './modes.js';
import { initBot } from '../utils/mcdata.js'; import { initBot } from '../utils/mcdata.js';
import { containsCommand, commandExists, executeCommand, truncCommandMessage, isAction, blacklistCommands } from './commands/index.js'; import { containsCommand, commandExists, executeCommand, truncCommandMessage, isAction, blacklistCommands } from './commands/index.js';
@ -100,11 +100,9 @@ export class Agent {
}); });
} catch (error) { } catch (error) {
// Ensure we're not losing error details // Ensure we're not losing error details
console.error('Agent start failed with error:', { console.error('Agent start failed with error')
message: error.message || 'No error message', console.error(error)
stack: error.stack || 'No stack trace',
error: error
});
throw error; // Re-throw with preserved details throw error; // Re-throw with preserved details
} }
} }

View file

@ -3,8 +3,9 @@ import { strictFormat } from '../utils/text.js';
import { getKey } from '../utils/keys.js'; import { getKey } from '../utils/keys.js';
export class Claude { export class Claude {
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name; this.model_name = model_name;
this.params = params;
let config = {}; let config = {};
if (url) if (url)
@ -20,13 +21,16 @@ export class Claude {
let res = null; let res = null;
try { try {
console.log('Awaiting anthropic api response...') console.log('Awaiting anthropic api response...')
// console.log('Messages:', messages); if (!this.params.max_tokens) {
this.params.max_tokens = 4096;
}
const resp = await this.anthropic.messages.create({ const resp = await this.anthropic.messages.create({
model: this.model_name || "claude-3-sonnet-20240229", model: this.model_name || "claude-3-sonnet-20240229",
system: systemMessage, system: systemMessage,
max_tokens: 2048,
messages: messages, messages: messages,
...(this.params || {})
}); });
console.log('Received.') console.log('Received.')
res = resp.content[0].text; res = resp.content[0].text;
} }

View file

@ -3,8 +3,9 @@ import { getKey, hasKey } from '../utils/keys.js';
import { strictFormat } from '../utils/text.js'; import { strictFormat } from '../utils/text.js';
export class DeepSeek { export class DeepSeek {
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name; this.model_name = model_name;
this.params = params;
let config = {}; let config = {};
@ -23,6 +24,7 @@ export class DeepSeek {
model: this.model_name || "deepseek-chat", model: this.model_name || "deepseek-chat",
messages, messages,
stop: stop_seq, stop: stop_seq,
...(this.params || {})
}; };
let res = null; let res = null;

View file

@ -3,8 +3,9 @@ import { toSinglePrompt } from '../utils/text.js';
import { getKey } from '../utils/keys.js'; import { getKey } from '../utils/keys.js';
export class Gemini { export class Gemini {
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name; this.model_name = model_name;
this.params = params;
this.url = url; this.url = url;
this.safetySettings = [ this.safetySettings = [
{ {
@ -34,15 +35,20 @@ export class Gemini {
async sendRequest(turns, systemMessage) { async sendRequest(turns, systemMessage) {
let model; let model;
const modelConfig = {
model: this.model_name || "gemini-1.5-flash",
...(this.params || {})
};
if (this.url) { if (this.url) {
model = this.genAI.getGenerativeModel( model = this.genAI.getGenerativeModel(
{ model: this.model_name || "gemini-1.5-flash" }, modelConfig,
{ baseUrl: this.url }, { baseUrl: this.url },
{ safetySettings: this.safetySettings } { safetySettings: this.safetySettings }
); );
} else { } else {
model = this.genAI.getGenerativeModel( model = this.genAI.getGenerativeModel(
{ model: this.model_name || "gemini-1.5-flash" }, modelConfig,
{ safetySettings: this.safetySettings } { safetySettings: this.safetySettings }
); );
} }
@ -50,12 +56,27 @@ export class Gemini {
const stop_seq = '***'; const stop_seq = '***';
const prompt = toSinglePrompt(turns, systemMessage, stop_seq, 'model'); const prompt = toSinglePrompt(turns, systemMessage, stop_seq, 'model');
console.log('Awaiting Google API response...'); console.log('Awaiting Google API response...');
const result = await model.generateContent(prompt); const result = await model.generateContent({
contents: [
{
role: 'user',
parts: [
{
text: "Explain how AI works",
}
],
}
],
generateConfig: {
...(this.params || {})
}
});
const response = await result.response; const response = await result.response;
const text = response.text(); const text = response.text();
console.log('Received.'); console.log('Received.');
if (!text.includes(stop_seq)) return text; if (!text.includes(stop_seq)) return text;
const idx = text.indexOf(stop_seq); const idx = text.indexOf(stop_seq);
return text.slice(0, idx); return text.slice(0, idx);
} }

View file

@ -3,8 +3,9 @@ import { getKey, hasKey } from '../utils/keys.js';
import { strictFormat } from '../utils/text.js'; import { strictFormat } from '../utils/text.js';
export class GPT { export class GPT {
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name; this.model_name = model_name;
this.params = params;
let config = {}; let config = {};
if (url) if (url)
@ -25,6 +26,7 @@ export class GPT {
model: this.model_name || "gpt-3.5-turbo", model: this.model_name || "gpt-3.5-turbo",
messages, messages,
stop: stop_seq, stop: stop_seq,
...(this.params || {})
}; };
if (this.model_name.includes('o1')) { if (this.model_name.includes('o1')) {
pack.messages = strictFormat(messages); pack.messages = strictFormat(messages);
@ -32,6 +34,7 @@ export class GPT {
} }
let res = null; let res = null;
try { try {
console.log('Awaiting openai api response from model', this.model_name) console.log('Awaiting openai api response from model', this.model_name)
// console.log('Messages:', messages); // console.log('Messages:', messages);

View file

@ -3,8 +3,10 @@ import { getKey } from '../utils/keys.js';
// xAI doesn't supply a SDK for their models, but fully supports OpenAI and Anthropic SDKs // xAI doesn't supply a SDK for their models, but fully supports OpenAI and Anthropic SDKs
export class Grok { export class Grok {
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name; this.model_name = model_name;
this.url = url;
this.params = params;
let config = {}; let config = {};
if (url) if (url)
@ -23,7 +25,8 @@ export class Grok {
const pack = { const pack = {
model: this.model_name || "grok-beta", model: this.model_name || "grok-beta",
messages, messages,
stop: [stop_seq] stop: [stop_seq],
...(this.params || {})
}; };
let res = null; let res = null;

View file

@ -4,12 +4,13 @@ import { getKey } from '../utils/keys.js';
// Umbrella class for Mixtral, LLama, Gemma... // Umbrella class for Mixtral, LLama, Gemma...
export class GroqCloudAPI { export class GroqCloudAPI {
constructor(model_name, url, max_tokens=16384) { constructor(model_name, url, params) {
this.model_name = model_name; this.model_name = model_name;
this.url = url; this.url = url;
this.max_tokens = max_tokens; this.params = params;
// ReplicateAPI theft :3 // ReplicateAPI theft :3
if (this.url) { if (this.url) {
console.warn("Groq Cloud has no implementation for custom URLs. Ignoring provided URL."); console.warn("Groq Cloud has no implementation for custom URLs. Ignoring provided URL.");
} }
this.groq = new Groq({ apiKey: getKey('GROQCLOUD_API_KEY') }); this.groq = new Groq({ apiKey: getKey('GROQCLOUD_API_KEY') });
@ -20,14 +21,15 @@ export class GroqCloudAPI {
let res = null; let res = null;
try { try {
console.log("Awaiting Groq response..."); console.log("Awaiting Groq response...");
if (!this.params.max_tokens) {
this.params.max_tokens = 16384;
}
let completion = await this.groq.chat.completions.create({ let completion = await this.groq.chat.completions.create({
"messages": messages, "messages": messages,
"model": this.model_name || "mixtral-8x7b-32768", "model": this.model_name || "mixtral-8x7b-32768",
"temperature": 0.2,
"max_tokens": this.max_tokens, // maximum token limit, differs from model to model
"top_p": 1,
"stream": true, "stream": true,
"stop": stop_seq // "***" "stop": stop_seq,
...(this.params || {})
}); });
let temp_res = ""; let temp_res = "";

View file

@ -3,9 +3,10 @@ import {getKey} from '../utils/keys.js';
import {HfInference} from "@huggingface/inference"; import {HfInference} from "@huggingface/inference";
export class HuggingFace { export class HuggingFace {
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name.replace('huggingface/',''); this.model_name = model_name.replace('huggingface/','');
this.url = url; this.url = url;
this.params = params;
if (this.url) { if (this.url) {
console.warn("Hugging Face doesn't support custom urls!"); console.warn("Hugging Face doesn't support custom urls!");
@ -25,7 +26,8 @@ export class HuggingFace {
console.log('Awaiting Hugging Face API response...'); console.log('Awaiting Hugging Face API response...');
for await (const chunk of this.huggingface.chatCompletionStream({ for await (const chunk of this.huggingface.chatCompletionStream({
model: model_name, model: model_name,
messages: [{ role: "user", content: input }] messages: [{ role: "user", content: input }],
...(this.params || {})
})) { })) {
res += (chunk.choices[0]?.delta?.content || ""); res += (chunk.choices[0]?.delta?.content || "");
} }

View file

@ -1,8 +1,9 @@
import { strictFormat } from '../utils/text.js'; import { strictFormat } from '../utils/text.js';
export class Local { export class Local {
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name; this.model_name = model_name;
this.params = params;
this.url = url || 'http://127.0.0.1:11434'; this.url = url || 'http://127.0.0.1:11434';
this.chat_endpoint = '/api/chat'; this.chat_endpoint = '/api/chat';
this.embedding_endpoint = '/api/embeddings'; this.embedding_endpoint = '/api/embeddings';
@ -15,7 +16,12 @@ export class Local {
let res = null; let res = null;
try { try {
console.log(`Awaiting local response... (model: ${model})`) console.log(`Awaiting local response... (model: ${model})`)
res = await this.send(this.chat_endpoint, {model: model, messages: messages, stream: false}); res = await this.send(this.chat_endpoint, {
model: model,
messages: messages,
stream: false,
...(this.params || {})
});
if (res) if (res)
res = res['message']['content']; res = res['message']['content'];
} }

View file

@ -5,10 +5,13 @@ import { strictFormat } from '../utils/text.js';
export class Mistral { export class Mistral {
#client; #client;
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name;
this.params = params;
if (typeof url === "string") { if (typeof url === "string") {
console.warn("Mistral does not support custom URL's, ignoring!"); console.warn("Mistral does not support custom URL's, ignoring!");
} }
if (!getKey("MISTRAL_API_KEY")) { if (!getKey("MISTRAL_API_KEY")) {
@ -22,8 +25,6 @@ export class Mistral {
); );
this.model_name = model_name;
// Prevents the following code from running when model not specified // Prevents the following code from running when model not specified
if (typeof this.model_name === "undefined") return; if (typeof this.model_name === "undefined") return;
@ -49,6 +50,7 @@ export class Mistral {
const response = await this.#client.chat.complete({ const response = await this.#client.chat.complete({
model, model,
messages, messages,
...(this.params || {})
}); });
result = response.choices[0].message.content; result = response.choices[0].message.content;

View file

@ -4,9 +4,11 @@ import { strictFormat } from '../utils/text.js';
// llama, mistral // llama, mistral
export class Novita { export class Novita {
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name.replace('novita/', ''); this.model_name = model_name.replace('novita/', '');
this.url = url || 'https://api.novita.ai/v3/openai'; this.url = url || 'https://api.novita.ai/v3/openai';
this.params = params;
let config = { let config = {
baseURL: this.url baseURL: this.url
@ -26,6 +28,7 @@ export class Novita {
model: this.model_name || "meta-llama/llama-3.1-70b-instruct", model: this.model_name || "meta-llama/llama-3.1-70b-instruct",
messages, messages,
stop: [stop_seq], stop: [stop_seq],
...(this.params || {})
}; };
let res = null; let res = null;

View file

@ -1,23 +1,23 @@
import { readFileSync, mkdirSync, writeFileSync} from 'fs'; import { readFileSync, mkdirSync, writeFileSync} from 'fs';
import { Examples } from '../utils/examples.js'; import { Examples } from '../utils/examples.js';
import { getCommandDocs } from './commands/index.js'; import { getCommandDocs } from '../agent/commands/index.js';
import { getSkillDocs } from './library/index.js'; import { getSkillDocs } from '../agent/library/index.js';
import { stringifyTurns } from '../utils/text.js'; import { stringifyTurns } from '../utils/text.js';
import { getCommand } from './commands/index.js'; import { getCommand } from '../agent/commands/index.js';
import settings from '../../settings.js'; import settings from '../../settings.js';
import { Gemini } from '../models/gemini.js'; import { Gemini } from './gemini.js';
import { GPT } from '../models/gpt.js'; import { GPT } from './gpt.js';
import { Claude } from '../models/claude.js'; import { Claude } from './claude.js';
import { Mistral } from '../models/mistral.js'; import { Mistral } from './mistral.js';
import { ReplicateAPI } from '../models/replicate.js'; import { ReplicateAPI } from './replicate.js';
import { Local } from '../models/local.js'; import { Local } from './local.js';
import { Novita } from '../models/novita.js'; import { Novita } from './novita.js';
import { GroqCloudAPI } from '../models/groq.js'; import { GroqCloudAPI } from './groq.js';
import { HuggingFace } from '../models/huggingface.js'; import { HuggingFace } from './huggingface.js';
import { Qwen } from "../models/qwen.js"; import { Qwen } from "./qwen.js";
import { Grok } from "../models/grok.js"; import { Grok } from "./grok.js";
import { DeepSeek } from '../models/deepseek.js'; import { DeepSeek } from './deepseek.js';
export class Prompter { export class Prompter {
constructor(agent, fp) { constructor(agent, fp) {
@ -102,6 +102,8 @@ export class Prompter {
_selectAPI(profile) { _selectAPI(profile) {
if (typeof profile === 'string' || profile instanceof String) { if (typeof profile === 'string' || profile instanceof String) {
profile = {model: profile}; profile = {model: profile};
}
if (!profile.api) {
if (profile.model.includes('gemini')) if (profile.model.includes('gemini'))
profile.api = 'google'; profile.api = 'google';
else if (profile.model.includes('gpt') || profile.model.includes('o1')|| profile.model.includes('o3')) else if (profile.model.includes('gpt') || profile.model.includes('o1')|| profile.model.includes('o3'))
@ -110,7 +112,7 @@ export class Prompter {
profile.api = 'anthropic'; profile.api = 'anthropic';
else if (profile.model.includes('huggingface/')) else if (profile.model.includes('huggingface/'))
profile.api = "huggingface"; profile.api = "huggingface";
else if (profile.model.includes('meta/') || profile.model.includes('replicate/')) else if (profile.model.includes('replicate/'))
profile.api = 'replicate'; profile.api = 'replicate';
else if (profile.model.includes('mistralai/') || profile.model.includes("mistral/")) else if (profile.model.includes('mistralai/') || profile.model.includes("mistral/"))
model_profile.api = 'mistral'; model_profile.api = 'mistral';
@ -133,32 +135,31 @@ export class Prompter {
_createModel(profile) { _createModel(profile) {
let model = null; let model = null;
if (profile.api === 'google') if (profile.api === 'google')
model = new Gemini(profile.model, profile.url); model = new Gemini(profile.model, profile.url, profile.params);
else if (profile.api === 'openai') else if (profile.api === 'openai')
model = new GPT(profile.model, profile.url); model = new GPT(profile.model, profile.url, profile.params);
else if (profile.api === 'anthropic') else if (profile.api === 'anthropic')
model = new Claude(profile.model, profile.url); model = new Claude(profile.model, profile.url, profile.params);
else if (profile.api === 'replicate') else if (profile.api === 'replicate')
model = new ReplicateAPI(profile.model, profile.url); model = new ReplicateAPI(profile.model, profile.url, profile.params);
else if (profile.api === 'ollama') else if (profile.api === 'ollama')
model = new Local(profile.model, profile.url); model = new Local(profile.model, profile.url, profile.params);
else if (profile.api === 'mistral') else if (profile.api === 'mistral')
model = new Mistral(profile.model, profile.url); model = new Mistral(profile.model, profile.url, profile.params);
else if (profile.api === 'groq') { else if (profile.api === 'groq')
model = new GroqCloudAPI(profile.model.replace('groq/', '').replace('groqcloud/', ''), profile.url, max_tokens ? max_tokens : 8192); model = new GroqCloudAPI(profile.model.replace('groq/', '').replace('groqcloud/', ''), profile.url, profile.params);
}
else if (profile.api === 'huggingface') else if (profile.api === 'huggingface')
model = new HuggingFace(profile.model, profile.url); model = new HuggingFace(profile.model, profile.url, profile.params);
else if (profile.api === 'novita') else if (profile.api === 'novita')
model = new Novita(profile.model.replace('novita/', ''), profile.url); model = new Novita(profile.model.replace('novita/', ''), profile.url, profile.params);
else if (profile.api === 'qwen') else if (profile.api === 'qwen')
model = new Qwen(profile.model, profile.url); model = new Qwen(profile.model, profile.url, profile.params);
else if (profile.api === 'xai') else if (profile.api === 'xai')
model = new Grok(profile.model, profile.url); model = new Grok(profile.model, profile.url, profile.params);
else if (profile.api === 'deepseek') else if (profile.api === 'deepseek')
model = new DeepSeek(profile.model, profile.url); model = new DeepSeek(profile.model, profile.url, profile.params);
else else
throw new Error('Unknown API:', api); throw new Error('Unknown API:', profile.api);
return model; return model;
} }

View file

@ -4,8 +4,9 @@
import { getKey } from '../utils/keys.js'; import { getKey } from '../utils/keys.js';
export class Qwen { export class Qwen {
constructor(modelName, url) { constructor(model_name, url, params) {
this.modelName = modelName; this.model_name = model_name;
this.params = params;
this.url = url || 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation'; this.url = url || 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
this.apiKey = getKey('QWEN_API_KEY'); this.apiKey = getKey('QWEN_API_KEY');
} }
@ -19,7 +20,11 @@ export class Qwen {
const data = { const data = {
model: this.modelName || 'qwen-plus', model: this.modelName || 'qwen-plus',
input: { messages: [{ role: 'system', content: systemMessage }, ...turns] }, input: { messages: [{ role: 'system', content: systemMessage }, ...turns] },
parameters: { result_format: 'message', stop: stopSeq }, parameters: {
result_format: 'message',
stop: stopSeq,
...(this.params || {})
},
}; };
// Add default user message if all messages are 'system' role // Add default user message if all messages are 'system' role

View file

@ -4,9 +4,10 @@ import { getKey } from '../utils/keys.js';
// llama, mistral // llama, mistral
export class ReplicateAPI { export class ReplicateAPI {
constructor(model_name, url) { constructor(model_name, url, params) {
this.model_name = model_name; this.model_name = model_name;
this.url = url; this.url = url;
this.params = params;
if (this.url) { if (this.url) {
console.warn('Replicate API does not support custom URLs. Ignoring provided URL.'); console.warn('Replicate API does not support custom URLs. Ignoring provided URL.');
@ -22,7 +23,11 @@ export class ReplicateAPI {
const prompt = toSinglePrompt(turns, null, stop_seq); const prompt = toSinglePrompt(turns, null, stop_seq);
let model_name = this.model_name || 'meta/meta-llama-3-70b-instruct'; let model_name = this.model_name || 'meta/meta-llama-3-70b-instruct';
const input = { prompt, system_prompt: systemMessage }; const input = {
prompt,
system_prompt: systemMessage,
...(this.params || {})
};
let res = null; let res = null;
try { try {
console.log('Awaiting Replicate API response...'); console.log('Awaiting Replicate API response...');

View file

@ -57,11 +57,8 @@ const argv = yargs(args)
const agent = new Agent(); const agent = new Agent();
await agent.start(argv.profile, argv.load_memory, argv.init_message, argv.count_id, argv.task_path, argv.task_id); await agent.start(argv.profile, argv.load_memory, argv.init_message, argv.count_id, argv.task_path, argv.task_id);
} catch (error) { } catch (error) {
console.error('Failed to start agent process:', { console.error('Failed to start agent process:');
message: error.message || 'No error message', console.error(error);
stack: error.stack || 'No stack trace',
error: error
});
process.exit(1); process.exit(1);
} }
})(); })();