naisys
Version:
NAISYS - Autonomous AI agent runner with built-in context management and cost tracking
75 lines • 3.77 kB
JavaScript
import { LlmApiType } from "@naisys/common";
import { sendWithAnthropic } from "./vendors/anthropic.js";
import { sendWithGoogle } from "./vendors/google.js";
import { sendWithMock } from "./vendors/mock.js";
import { sendWithOpenAiCompatible } from "./vendors/openai-compatible.js";
import { createCodexAccessTokenGetter, sendWithOpenAiOauth, } from "./vendors/openai-oauth.js";
import { sendWithOpenAiStandard } from "./vendors/openai-standard.js";
export function createLLMService(globalConfigService, { agentConfig }, costTracker, tools, modelService, computerService, hubClient) {
const { globalConfig } = globalConfigService;
const getCodexAccessToken = createCodexAccessTokenGetter(globalConfigService, hubClient);
async function query(modelKey, systemMessage, context, source, abortSignal) {
// Check if spend limit has been reached (throws error if so)
// Except for compact as when the spend limit is lifted, we don't want to start querying with an expensive expired cache
if (source != "compact") {
costTracker.checkSpendLimit();
}
const model = modelService.getLlmModel(modelKey);
// Workspaces feature only works with Anthropic models due to cache_control support
if (agentConfig().workspacesEnabled &&
model.apiType !== LlmApiType.Anthropic) {
throw new Error(`Workspaces feature requires an Anthropic model. Current model '${modelKey}' uses ${model.apiType} API.`);
}
const apiKey = model.apiKeyVar
? globalConfig().variableMap[model.apiKeyVar]
: undefined;
if (model.apiType === LlmApiType.None) {
throw "This should be unreachable";
}
else if (model.apiType === LlmApiType.Mock) {
return sendWithMock(abortSignal);
}
// Assert the last message on the context is a user message
const lastMessage = context[context.length - 1];
if (lastMessage && lastMessage.role !== "user") {
throw "Error, last message on context is not a user message";
}
// Use pre-computed desktop config only if current model supports computer use
const effectiveDesktopConfig = model.supportsComputerUse &&
agentConfig().controlDesktop &&
computerService
? computerService.getConfig()
: undefined;
const deps = {
globalConfig: globalConfigService,
modelService,
costTracker,
tools,
useToolsForLlmConsoleResponses: globalConfig().useToolsForLlmConsoleResponses,
desktopConfig: effectiveDesktopConfig,
getCodexAccessToken,
};
if (model.apiType == LlmApiType.Google) {
return sendWithGoogle(deps, modelKey, systemMessage, context, source, apiKey, abortSignal);
}
else if (model.apiType == LlmApiType.Anthropic) {
return sendWithAnthropic(deps, modelKey, systemMessage, context, source, apiKey, abortSignal);
}
else if (model.apiType == LlmApiType.OpenAI) {
return sendWithOpenAiStandard(deps, modelKey, systemMessage, context, source, apiKey, abortSignal);
}
else if (model.apiType == LlmApiType.OpenAICompatible) {
return sendWithOpenAiCompatible(deps, modelKey, systemMessage, context, source, apiKey, abortSignal);
}
else if (model.apiType == LlmApiType.OpenAIOAuth) {
return sendWithOpenAiOauth(deps, modelKey, systemMessage, context, source, abortSignal);
}
else {
throw `Error, unknown LLM API type ${model.apiType}`;
}
}
return {
query,
};
}
//# sourceMappingURL=llmService.js.map