UNPKG

@langchain/community

Version:
1 lines 22.4 kB
{"version":3,"file":"perplexity.cjs","names":["BaseChatModel","OpenAI","AIMessage","HumanMessageChunk","AIMessageChunk","SystemMessageChunk","ChatMessageChunk","ChatGenerationChunk","ReasoningStructuredOutputParser","StructuredOutputParser","ReasoningJsonOutputParser","JsonOutputParser","RunnablePassthrough","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 // oxlint-disable-next-line typescript/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 // oxlint-disable-next-line typescript/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 // oxlint-disable-next-line typescript/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 // oxlint-disable-next-line typescript/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // oxlint-disable-next-line typescript/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<false>\n ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n withStructuredOutput<\n // oxlint-disable-next-line typescript/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // oxlint-disable-next-line typescript/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<true>\n ): Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n withStructuredOutput<\n // oxlint-disable-next-line typescript/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // oxlint-disable-next-line typescript/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 // oxlint-disable-next-line typescript/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 // oxlint-disable-next-line typescript/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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"}