UNPKG

naisys

Version:

NAISYS - Autonomous AI agent runner with built-in context management and cost tracking

75 lines 3.77 kB
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