UNPKG

@langchain/community

Version:
1 lines 12.5 kB
{"version":3,"file":"togetherai.cjs","names":["LLM","convertEventStreamToIterableReadableDataStream","GenerationChunk"],"sources":["../../src/llms/togetherai.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n LLM,\n type BaseLLMCallOptions,\n type BaseLLMParams,\n} from \"@langchain/core/language_models/llms\";\nimport { GenerationChunk } from \"@langchain/core/outputs\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { convertEventStreamToIterableReadableDataStream } from \"../utils/event_source_parse.js\";\n\ninterface TogetherAIInferenceResult {\n object: string;\n status: string;\n prompt: Array<string>;\n model: string;\n model_owner: string;\n tags: object;\n num_returns: number;\n args: {\n model: string;\n prompt: string;\n temperature: number;\n top_p: number;\n top_k: number;\n max_tokens: number;\n stop: string[];\n };\n // oxlint-disable-next-line typescript/no-explicit-any\n subjobs: Array<any>;\n output?: {\n choices: Array<{\n finish_reason: string;\n index: number;\n text: string;\n }>;\n raw_compute_time: number;\n result_type: string;\n };\n choices?: Array<{\n finish_reason: string;\n index: number;\n text: string;\n }>;\n}\n\n/**\n * Note that the modelPath is the only required parameter. For testing you\n * can set this in the environment variable `LLAMA_PATH`.\n */\nexport interface TogetherAIInputs extends BaseLLMParams {\n /**\n * The API key to use for the TogetherAI API.\n * @default {process.env.TOGETHER_AI_API_KEY}\n */\n apiKey?: string;\n /**\n * The name of the model to query.\n * Alias for `model`\n */\n modelName?: string;\n /**\n * The name of the model to query.\n */\n model?: string;\n /**\n * A decimal number that determines the degree of randomness in the response.\n * A value of 1 will always yield the same output.\n * A temperature less than 1 favors more correctness and is appropriate for question answering or summarization.\n * A value greater than 1 introduces more randomness in the output.\n * @default {0.7}\n */\n temperature?: number;\n /**\n * Whether or not to stream tokens as they are generated.\n * @default {false}\n */\n streaming?: boolean;\n /**\n * The `topP` (nucleus) parameter is used to dynamically adjust the number of choices for each predicted token based on the cumulative probabilities.\n * It specifies a probability threshold, below which all less likely tokens are filtered out.\n * This technique helps to maintain diversity and generate more fluent and natural-sounding text.\n * @default {0.7}\n */\n topP?: number;\n /**\n * The `topK` parameter is used to limit the number of choices for the next predicted word or token.\n * It specifies the maximum number of tokens to consider at each step, based on their probability of occurrence.\n * This technique helps to speed up the generation process and can improve the quality of the generated text by focusing on the most likely options.\n * @default {50}\n */\n topK?: number;\n /**\n * A number that controls the diversity of generated text by reducing the likelihood of repeated sequences.\n * Higher values decrease repetition.\n * @default {1}\n */\n repetitionPenalty?: number;\n /**\n * An integer that specifies how many top token log probabilities are included in the response for each token generation step.\n */\n logprobs?: number;\n /**\n * Run an LLM-based input-output safeguard model on top of any model.\n */\n safetyModel?: string;\n /**\n * Limit the number of tokens generated.\n */\n maxTokens?: number;\n /**\n * A list of tokens at which the generation should stop.\n */\n stop?: string[];\n}\n\nexport interface TogetherAICallOptions\n extends\n BaseLLMCallOptions,\n Pick<\n TogetherAIInputs,\n | \"modelName\"\n | \"model\"\n | \"temperature\"\n | \"topP\"\n | \"topK\"\n | \"repetitionPenalty\"\n | \"logprobs\"\n | \"safetyModel\"\n | \"maxTokens\"\n | \"stop\"\n > {}\n\nexport class TogetherAI extends LLM<TogetherAICallOptions> {\n lc_serializable = true;\n\n static inputs: TogetherAIInputs;\n\n temperature = 0.7;\n\n topP = 0.7;\n\n topK = 50;\n\n modelName: string;\n\n model: string;\n\n streaming = false;\n\n repetitionPenalty = 1;\n\n logprobs?: number;\n\n maxTokens?: number;\n\n safetyModel?: string;\n\n stop?: string[];\n\n private apiKey: string;\n\n private inferenceAPIUrl = \"https://api.together.xyz/inference\";\n\n static lc_name() {\n return \"TogetherAI\";\n }\n\n /**\n * Check if a model name appears to be a chat/instruct model\n * @param modelName The model name to check\n * @returns true if the model appears to be a chat/instruct model\n */\n private isChatModel(modelName: string): boolean {\n const chatModelPatterns = [/instruct/i, /chat/i, /vision/i, /turbo/i];\n return chatModelPatterns.some((pattern) => pattern.test(modelName));\n }\n\n constructor(inputs: TogetherAIInputs) {\n super(inputs);\n const apiKey =\n inputs.apiKey ?? getEnvironmentVariable(\"TOGETHER_AI_API_KEY\");\n if (!apiKey) {\n throw new Error(\"TOGETHER_AI_API_KEY not found.\");\n }\n if (!inputs.model && !inputs.modelName) {\n throw new Error(\"Model name is required for TogetherAI.\");\n }\n this.apiKey = apiKey;\n this.temperature = inputs?.temperature ?? this.temperature;\n this.topK = inputs?.topK ?? this.topK;\n this.topP = inputs?.topP ?? this.topP;\n this.modelName = inputs.model ?? inputs.modelName ?? \"\";\n this.model = this.modelName;\n this.streaming = inputs.streaming ?? this.streaming;\n this.repetitionPenalty = inputs.repetitionPenalty ?? this.repetitionPenalty;\n this.logprobs = inputs.logprobs;\n this.safetyModel = inputs.safetyModel;\n this.maxTokens = inputs.maxTokens;\n this.stop = inputs.stop;\n\n // Warn if user is trying to use a chat model with the wrong class\n if (this.isChatModel(this.model)) {\n console.warn(\n `Warning: Model '${this.model}' appears to be a chat/instruct model. ` +\n `Consider using ChatTogetherAI from @langchain/community/chat_models/togetherai instead.`\n );\n }\n }\n\n _llmType() {\n return \"together_ai\";\n }\n\n private constructHeaders() {\n return {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n\n private constructBody(prompt: string, options?: this[\"ParsedCallOptions\"]) {\n const body = {\n model: options?.model ?? options?.modelName ?? this?.model,\n prompt,\n temperature: this?.temperature ?? options?.temperature,\n top_k: this?.topK ?? options?.topK,\n top_p: this?.topP ?? options?.topP,\n repetition_penalty: this?.repetitionPenalty ?? options?.repetitionPenalty,\n logprobs: this?.logprobs ?? options?.logprobs,\n stream_tokens: this?.streaming,\n safety_model: this?.safetyModel ?? options?.safetyModel,\n max_tokens: this?.maxTokens ?? options?.maxTokens,\n stop: this?.stop ?? options?.stop,\n };\n return body;\n }\n\n async completionWithRetry(\n prompt: string,\n options?: this[\"ParsedCallOptions\"]\n ) {\n return this.caller.call(async () => {\n const fetchResponse = await fetch(this.inferenceAPIUrl, {\n method: \"POST\",\n headers: {\n ...this.constructHeaders(),\n },\n body: JSON.stringify(this.constructBody(prompt, options)),\n });\n if (fetchResponse.status === 200) {\n return fetchResponse.json();\n }\n const errorResponse = await fetchResponse.json();\n throw new Error(\n `Error getting prompt completion from Together AI. ${JSON.stringify(\n errorResponse,\n null,\n 2\n )}`\n );\n });\n }\n\n /** @ignore */\n async _call(\n prompt: string,\n options?: this[\"ParsedCallOptions\"]\n ): Promise<string> {\n const response: TogetherAIInferenceResult = await this.completionWithRetry(\n prompt,\n options\n );\n\n // Add proper error handling for unexpected response formats\n if (!response.output && !response.choices) {\n throw new Error(\n `Unexpected response format from Together AI. The model '${this.model}' may require the ChatTogetherAI class instead of TogetherAI class. ` +\n `Response: ${JSON.stringify(response, null, 2)}`\n );\n }\n\n if (response.output) {\n return response.output.choices?.[0]?.text ?? \"\";\n } else {\n return response.choices?.[0]?.text ?? \"\";\n }\n }\n\n async *_streamResponseChunks(\n prompt: string,\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<GenerationChunk> {\n const fetchResponse = await fetch(this.inferenceAPIUrl, {\n method: \"POST\",\n headers: {\n ...this.constructHeaders(),\n },\n body: JSON.stringify(this.constructBody(prompt, options)),\n });\n\n if (fetchResponse.status !== 200 || !fetchResponse.body) {\n const errorResponse = await fetchResponse.json();\n throw new Error(\n `Error getting prompt completion from Together AI. ${JSON.stringify(\n errorResponse,\n null,\n 2\n )}`\n );\n }\n const stream = convertEventStreamToIterableReadableDataStream(\n fetchResponse.body\n );\n for await (const chunk of stream) {\n if (chunk !== \"[DONE]\") {\n const parsedChunk = JSON.parse(chunk);\n const generationChunk = new GenerationChunk({\n text: parsedChunk.choices[0].text ?? \"\",\n });\n yield generationChunk;\n // eslint-disable-next-line no-void\n void runManager?.handleLLMNewToken(generationChunk.text ?? \"\");\n }\n }\n }\n}\n"],"mappings":"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"}