@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 23.2 kB
Source Map (JSON)
{"version":3,"file":"perplexity.cjs","names":["BaseChatModel","fields: PerplexityChatInput","OpenAI","options?: this[\"ParsedCallOptions\"]","message: BaseMessage","messages: BaseMessage[]","options: this[\"ParsedCallOptions\"]","runManager?: CallbackManagerForLLMRun","tokenUsage: TokenUsage","message","finalChunks: Record<number, ChatGenerationChunk>","generations","generations: ChatGeneration[]","AIMessage","messageChunk: BaseMessageChunk","HumanMessageChunk","AIMessageChunk","SystemMessageChunk","ChatMessageChunk","ChatGenerationChunk","outputSchema:\n | InteropZodType<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>","config?: StructuredOutputMethodOptions<boolean>","schema: InteropZodType<RunOutput> | Record<string, any>","llm: Runnable<BaseLanguageModelInput>","outputParser: BaseLLMOutputParser","ReasoningStructuredOutputParser","StructuredOutputParser","ReasoningJsonOutputParser","JsonOutputParser","RunnablePassthrough","input: any","config","RunnableSequence"],"sources":["../../src/chat_models/perplexity.ts"],"sourcesContent":["import {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n BaseMessageChunk,\n ChatMessageChunk,\n HumanMessageChunk,\n SystemMessageChunk,\n} from \"@langchain/core/messages\";\nimport { concat } from \"@langchain/core/utils/stream\";\nimport {\n BaseChatModel,\n BaseChatModelParams,\n BaseChatModelCallOptions,\n} from \"@langchain/core/language_models/chat_models\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n ChatGeneration,\n ChatGenerationChunk,\n ChatResult,\n} from \"@langchain/core/outputs\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport OpenAI from \"openai\";\nimport { NewTokenIndices } from \"@langchain/core/callbacks/base\";\nimport {\n RunnableSequence,\n Runnable,\n RunnablePassthrough,\n} from \"@langchain/core/runnables\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n TokenUsage,\n} from \"@langchain/core/language_models/base\";\nimport {\n InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n type BaseLLMOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport {\n ReasoningJsonOutputParser,\n ReasoningStructuredOutputParser,\n} from \"../utils/output_parsers.js\";\n\n/**\n * Type representing the role of a message in the Perplexity chat model.\n */\nexport type PerplexityRole = \"system\" | \"user\" | \"assistant\";\n\nexport interface WebSearchOptions {\n /**\n * Determines how much search context is retrieved for the model.\n * Options are: low (minimizes context for cost savings but less comprehensive answers), medium (balanced approach suitable for most queries), and high (maximizes context for comprehensive answers but at higher cost).\n */\n search_context_size?: \"low\" | \"medium\" | \"high\";\n\n /**\n * To refine search results based on geography, you can specify an approximate user location.\n */\n user_location?: {\n /**\n * The latitude of the user's location.\n */\n latitude: number;\n\n /**\n * The longitude of the user's location.\n */\n longitude: number;\n\n /**\n * The two letter ISO country code of the user's location.\n */\n country: string;\n };\n}\n\n/**\n * Interface defining the parameters for the Perplexity chat model.\n */\nexport interface PerplexityChatInput extends BaseChatModelParams {\n /** Model name to use */\n model: string;\n\n /** Maximum number of tokens to generate */\n maxTokens?: number;\n\n /** Temperature parameter between 0 and 2 */\n temperature?: number;\n\n /** Top P parameter between 0 and 1 */\n topP?: number;\n\n /** Search domain filter - limit the citations used by the online model to URLs from the specified domains. */\n searchDomainFilter?: unknown[];\n\n /** Whether to return images */\n returnImages?: boolean;\n\n /** Determines whether or not a request to an online model should return related questions. */\n returnRelatedQuestions?: boolean;\n\n /** Returns search results within the specified time interval - does not apply to images. Values include month, week, day, hour. */\n searchRecencyFilter?: string;\n\n /** Top K parameter between 1 and 2048 */\n topK?: number;\n\n /** Presence penalty between -2 and 2 */\n presencePenalty?: number;\n\n /** Frequency penalty greater than 0 */\n frequencyPenalty?: number;\n\n /** API key for Perplexity. Defaults to the value of\n * PERPLEXITY_API_KEY environment variable.\n */\n apiKey?: string;\n\n /** Whether to stream the results or not */\n streaming?: boolean;\n\n /** Timeout for requests to Perplexity */\n timeout?: number;\n\n /** Controls the search mode used for the request. When set to 'academic', results will prioritize scholarly sources. */\n searchMode?: \"academic\" | \"web\";\n\n /** Controls how much computational effort the AI dedicates to each query for deep research models. Only applicable for sonar-deep-research. */\n reasoningEffort?: \"low\" | \"medium\" | \"high\";\n\n /** Filters search results to only include content published after this date. */\n searchAfterDateFilter?: string;\n\n /** Filters search results to only include content published before this date. */\n searchBeforeDateFilter?: string;\n\n /** Filters search results to only include content last updated after this date. */\n lastUpdatedAfterFilter?: string;\n\n /** Filters search results to only include content last updated before this date. */\n lastUpdatedBeforeFilter?: string;\n\n /** When set to true, disables web search completely and the model will only use its training data to respond. This is useful when you want deterministic responses without external information. */\n disableSearch?: boolean;\n\n /** Enables a classifier that decides if web search is needed based on your query. */\n enableSearchClassifier?: boolean;\n\n /**\n * Configuration for using web search in model responses.\n */\n webSearchOptions?: WebSearchOptions;\n}\n\nexport interface PerplexityChatCallOptions extends BaseChatModelCallOptions {\n response_format?: {\n type: \"json_schema\";\n json_schema: {\n name: string;\n description: string;\n schema: Record<string, unknown>;\n };\n };\n}\n\n/**\n * Wrapper around Perplexity large language models that use the Chat endpoint.\n */\nexport class ChatPerplexity\n extends BaseChatModel<PerplexityChatCallOptions>\n implements PerplexityChatInput\n{\n static lc_name() {\n return \"ChatPerplexity\";\n }\n\n model: string;\n\n temperature?: number;\n\n maxTokens?: number;\n\n apiKey?: string;\n\n timeout?: number;\n\n streaming?: boolean;\n\n topP?: number;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n searchDomainFilter?: any[];\n\n returnImages?: boolean;\n\n returnRelatedQuestions?: boolean;\n\n searchRecencyFilter?: string;\n\n topK?: number;\n\n presencePenalty?: number;\n\n frequencyPenalty?: number;\n\n searchMode?: \"academic\" | \"web\";\n\n reasoningEffort?: \"low\" | \"medium\" | \"high\";\n\n searchAfterDateFilter?: string;\n\n searchBeforeDateFilter?: string;\n\n lastUpdatedAfterFilter?: string;\n\n lastUpdatedBeforeFilter?: string;\n\n disableSearch?: boolean;\n\n enableSearchClassifier?: boolean;\n\n webSearchOptions?: WebSearchOptions;\n\n private client: OpenAI;\n\n constructor(fields: PerplexityChatInput) {\n super(fields ?? {});\n\n this.model = fields.model;\n this.temperature = fields?.temperature ?? this.temperature;\n this.maxTokens = fields?.maxTokens;\n this.apiKey =\n fields?.apiKey ?? getEnvironmentVariable(\"PERPLEXITY_API_KEY\");\n this.streaming = fields?.streaming ?? this.streaming;\n this.timeout = fields?.timeout;\n this.topP = fields?.topP ?? this.topP;\n this.returnImages = fields?.returnImages ?? this.returnImages;\n this.returnRelatedQuestions =\n fields?.returnRelatedQuestions ?? this.returnRelatedQuestions;\n this.topK = fields?.topK ?? this.topK;\n this.presencePenalty = fields?.presencePenalty ?? this.presencePenalty;\n this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty;\n this.searchDomainFilter =\n fields?.searchDomainFilter ?? this.searchDomainFilter;\n this.searchRecencyFilter =\n fields?.searchRecencyFilter ?? this.searchRecencyFilter;\n this.searchMode = fields?.searchMode;\n this.reasoningEffort = fields?.reasoningEffort;\n this.searchAfterDateFilter = fields?.searchAfterDateFilter;\n this.searchBeforeDateFilter = fields?.searchBeforeDateFilter;\n this.webSearchOptions = fields?.webSearchOptions;\n\n if (!this.apiKey) {\n throw new Error(\"Perplexity API key not found\");\n }\n\n this.client = new OpenAI({\n apiKey: this.apiKey,\n baseURL: \"https://api.perplexity.ai\",\n });\n }\n\n _llmType() {\n return \"perplexity\";\n }\n\n /**\n * Get the parameters used to invoke the model\n */\n invocationParams(options?: this[\"ParsedCallOptions\"]) {\n return {\n model: this.model as string,\n temperature: this.temperature,\n max_tokens: this.maxTokens,\n stream: this.streaming,\n top_p: this.topP,\n return_images: this.returnImages,\n return_related_questions: this.returnRelatedQuestions,\n top_k: this.topK,\n presence_penalty: this.presencePenalty,\n frequency_penalty: this.frequencyPenalty,\n response_format: options?.response_format,\n search_domain_filter: this.searchDomainFilter,\n search_recency_filter: this.searchRecencyFilter,\n search_mode: this.searchMode,\n reasoning_effort: this.reasoningEffort,\n search_after_date_filter: this.searchAfterDateFilter,\n search_before_date_filter: this.searchBeforeDateFilter,\n last_updated_after_filter: this.lastUpdatedAfterFilter,\n last_updated_before_filter: this.lastUpdatedBeforeFilter,\n disable_search: this.disableSearch,\n enable_search_classifier: this.enableSearchClassifier,\n web_search_options: this.webSearchOptions as Record<string, unknown>, // Cast WebSearchOptions to generic type to avoid conflict with OpenAI's WebSearchOptions interface\n };\n }\n\n /**\n * Convert a message to a format that the model expects\n */\n private messageToPerplexityRole(message: BaseMessage): {\n role: PerplexityRole;\n content: string;\n } {\n if (message._getType() === \"human\") {\n return {\n role: \"user\",\n content: message.content.toString(),\n };\n } else if (message._getType() === \"ai\") {\n return {\n role: \"assistant\",\n content: message.content.toString(),\n };\n } else if (message._getType() === \"system\") {\n return {\n role: \"system\",\n content: message.content.toString(),\n };\n }\n throw new Error(`Unknown message type: ${message}`);\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const tokenUsage: TokenUsage = {};\n const messagesList = messages.map((message) =>\n this.messageToPerplexityRole(message)\n );\n\n if (this.streaming) {\n const stream = this._streamResponseChunks(messages, options, runManager);\n const finalChunks: Record<number, ChatGenerationChunk> = {};\n for await (const chunk of stream) {\n const index =\n (chunk.generationInfo as NewTokenIndices)?.completion ?? 0;\n if (finalChunks[index] === undefined) {\n finalChunks[index] = chunk;\n } else {\n finalChunks[index] = concat(finalChunks[index], chunk);\n }\n }\n\n const generations = Object.entries(finalChunks)\n .sort(([aKey], [bKey]) => parseInt(aKey, 10) - parseInt(bKey, 10))\n .map(([_, value]) => value);\n return { generations };\n }\n\n const response = await this.client.chat.completions.create({\n messages: messagesList,\n ...this.invocationParams(options),\n stream: false,\n });\n\n const { message } = response.choices[0];\n\n const generations: ChatGeneration[] = [];\n\n generations.push({\n text: message.content ?? \"\",\n message: new AIMessage({\n content: message.content ?? \"\",\n additional_kwargs: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n citations: (response as any).citations,\n },\n }),\n });\n\n if (response.usage) {\n tokenUsage.promptTokens = response.usage.prompt_tokens;\n tokenUsage.completionTokens = response.usage.completion_tokens;\n tokenUsage.totalTokens = response.usage.total_tokens;\n }\n\n return {\n generations,\n llmOutput: {\n tokenUsage,\n },\n };\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const messagesList = messages.map((message) =>\n this.messageToPerplexityRole(message)\n );\n\n const stream = await this.client.chat.completions.create({\n messages: messagesList,\n ...this.invocationParams(options),\n stream: true,\n });\n\n let firstChunk = true;\n for await (const chunk of stream) {\n const choice = chunk.choices[0];\n const { delta } = choice;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const citations = (chunk as any).citations ?? [];\n\n if (!delta.content) continue;\n\n let messageChunk: BaseMessageChunk;\n if (delta.role === \"user\") {\n messageChunk = new HumanMessageChunk({ content: delta.content });\n } else if (delta.role === \"assistant\") {\n messageChunk = new AIMessageChunk({ content: delta.content });\n } else if (delta.role === \"system\") {\n messageChunk = new SystemMessageChunk({ content: delta.content });\n } else {\n messageChunk = new ChatMessageChunk({\n content: delta.content,\n role: delta.role ?? \"assistant\",\n });\n }\n\n if (firstChunk) {\n messageChunk.additional_kwargs.citations = citations;\n firstChunk = false;\n }\n\n const generationChunk = new ChatGenerationChunk({\n message: messageChunk,\n text: delta.content,\n generationInfo: {\n finishReason: choice.finish_reason,\n },\n });\n\n yield generationChunk;\n\n // Emit the chunk to the callback manager if provided\n if (runManager) {\n await runManager.handleLLMNewToken(delta.content);\n }\n }\n }\n\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<false>\n ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<true>\n ): Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n {\n raw: BaseMessage;\n parsed: RunOutput;\n }\n > {\n if (config?.strict) {\n throw new Error(`\"strict\" mode is not supported for this model.`);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let schema: InteropZodType<RunOutput> | Record<string, any> = outputSchema;\n if (isInteropZodSchema(schema)) {\n schema = toJsonSchema(schema);\n }\n const name = config?.name;\n const description =\n schema.description ?? \"Format to use when returning your response\";\n const method = config?.method ?? \"jsonSchema\";\n const includeRaw = config?.includeRaw;\n if (method !== \"jsonSchema\") {\n throw new Error(\n `Perplexity only supports \"jsonSchema\" as a structured output method.`\n );\n }\n const llm: Runnable<BaseLanguageModelInput> = this.withConfig({\n response_format: {\n type: \"json_schema\",\n json_schema: {\n name: name ?? \"extract\",\n description,\n schema,\n },\n },\n });\n\n let outputParser: BaseLLMOutputParser;\n // Check if this is a reasoning model\n const isReasoningModel = this.model.toLowerCase().includes(\"reasoning\");\n\n if (isInteropZodSchema(schema)) {\n if (isReasoningModel) {\n outputParser = new ReasoningStructuredOutputParser(schema);\n } else {\n outputParser = StructuredOutputParser.fromZodSchema(schema);\n }\n } else {\n if (isReasoningModel) {\n outputParser = new ReasoningJsonOutputParser(schema);\n } else {\n outputParser = new JsonOutputParser<RunOutput>();\n }\n }\n\n if (!includeRaw) {\n return llm.pipe(outputParser) as Runnable<\n BaseLanguageModelInput,\n RunOutput\n >;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([\n {\n raw: llm,\n },\n parsedWithFallback,\n ]);\n }\n}\n"],"mappings":"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"}