@@ -156,3 +156,3 @@ "use strict"; | ||
| // src/version.ts | ||
| var VERSION = true ? "7.0.0-beta.38" : "0.0.0-test"; | ||
| var VERSION = true ? "7.0.0-beta.39" : "0.0.0-test"; | ||
@@ -159,0 +159,0 @@ // src/util/download/download.ts |
@@ -136,3 +136,3 @@ // internal/index.ts | ||
| // src/version.ts | ||
| var VERSION = true ? "7.0.0-beta.38" : "0.0.0-test"; | ||
| var VERSION = true ? "7.0.0-beta.39" : "0.0.0-test"; | ||
@@ -139,0 +139,0 @@ // src/util/download/download.ts |
+1
-1
| { | ||
| "name": "ai", | ||
| "version": "7.0.0-beta.38", | ||
| "version": "7.0.0-beta.39", | ||
| "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript", | ||
@@ -5,0 +5,0 @@ "license": "Apache-2.0", |
| export { rerank } from './rerank'; | ||
| export type { RerankResult } from './rerank-result'; | ||
| export type { RerankOnStartEvent, RerankOnFinishEvent } from './rerank-events'; | ||
| export type { | ||
| RerankOnStartEvent, | ||
| RerankOnFinishEvent, | ||
| RerankStartEvent, | ||
| RerankFinishEvent, | ||
| } from './rerank-events'; |
@@ -121,1 +121,70 @@ import type { JSONObject, JSONValue } from '@ai-sdk/provider'; | ||
| } | ||
| /** | ||
| * Event fired when an individual reranking model call (inner doRerank) begins. | ||
| */ | ||
| export interface RerankStartEvent { | ||
| /** Unique identifier for this rerank call, used to correlate events. */ | ||
| readonly callId: string; | ||
| /** Identifies the inner operation ('ai.rerank.doRerank'). */ | ||
| readonly operationId: string; | ||
| /** The provider identifier. */ | ||
| readonly provider: string; | ||
| /** The specific model identifier. */ | ||
| readonly modelId: string; | ||
| /** The documents being reranked. */ | ||
| readonly documents: Array<JSONObject | string>; | ||
| /** The type of documents ('text' or 'object'). */ | ||
| readonly documentsType: string; | ||
| /** The query to rerank against. */ | ||
| readonly query: string; | ||
| /** Number of top documents to return. */ | ||
| readonly topN: number | undefined; | ||
| /** Whether telemetry is enabled. */ | ||
| readonly isEnabled: boolean | undefined; | ||
| /** Whether to record inputs in telemetry. Enabled by default. */ | ||
| readonly recordInputs: boolean | undefined; | ||
| /** Whether to record outputs in telemetry. Enabled by default. */ | ||
| readonly recordOutputs: boolean | undefined; | ||
| /** Identifier from telemetry settings for grouping related operations. */ | ||
| readonly functionId: string | undefined; | ||
| /** Additional metadata from telemetry settings. */ | ||
| readonly metadata: Record<string, JSONValue> | undefined; | ||
| } | ||
| /** | ||
| * Event fired when an individual reranking model call (doRerank) completes. | ||
| * | ||
| * Contains the ranking results from the model response. | ||
| */ | ||
| export interface RerankFinishEvent { | ||
| /** Unique identifier for this rerank call, used to correlate events. */ | ||
| readonly callId: string; | ||
| /** Identifies the inner operation ('ai.rerank.doRerank'). */ | ||
| readonly operationId: string; | ||
| /** The provider identifier. */ | ||
| readonly provider: string; | ||
| /** The specific model identifier. */ | ||
| readonly modelId: string; | ||
| /** The type of documents ('text' or 'object'). */ | ||
| readonly documentsType: string; | ||
| /** The ranking results from the model. */ | ||
| readonly ranking: Array<{ index: number; relevanceScore: number }>; | ||
| } |
+109
-131
@@ -5,7 +5,3 @@ import { JSONObject, RerankingModelV4CallOptions } from '@ai-sdk/provider'; | ||
| import { logWarnings } from '../logger/log-warnings'; | ||
| import { assembleOperationName } from '../telemetry/assemble-operation-name'; | ||
| import { getBaseTelemetryAttributes } from '../telemetry/get-base-telemetry-attributes'; | ||
| import { getTracer } from '../telemetry/get-tracer'; | ||
| import { recordSpan } from '../telemetry/record-span'; | ||
| import { selectTelemetryAttributes } from '../telemetry/select-telemetry-attributes'; | ||
| import { getGlobalTelemetryIntegration } from '../telemetry/get-global-telemetry-integration'; | ||
| import { TelemetrySettings } from '../telemetry/telemetry-settings'; | ||
@@ -124,2 +120,7 @@ import { RerankingModel } from '../types'; | ||
| const createGlobalTelemetry = getGlobalTelemetryIntegration(); | ||
| const globalTelemetry = createGlobalTelemetry({ | ||
| integrations: telemetry?.integrations, | ||
| }); | ||
| if (documents.length === 0) { | ||
@@ -145,3 +146,3 @@ await notify({ | ||
| }, | ||
| callbacks: [onStart], | ||
| callbacks: [onStart, globalTelemetry.onStart], | ||
| }); | ||
@@ -170,3 +171,3 @@ | ||
| }, | ||
| callbacks: [onFinish], | ||
| callbacks: [onFinish, globalTelemetry.onFinish], | ||
| }); | ||
@@ -190,2 +191,7 @@ | ||
| const documentsToSend: RerankingModelV4CallOptions['documents'] = | ||
| typeof documents[0] === 'string' | ||
| ? { type: 'text', values: documents as string[] } | ||
| : { type: 'object', values: documents as JSONObject[] }; | ||
| await notify({ | ||
@@ -210,133 +216,79 @@ event: { | ||
| }, | ||
| callbacks: [onStart], | ||
| callbacks: [onStart, globalTelemetry.onStart], | ||
| }); | ||
| // detect the type of the documents: | ||
| const documentsToSend: RerankingModelV4CallOptions['documents'] = | ||
| typeof documents[0] === 'string' | ||
| ? { type: 'text', values: documents as string[] } | ||
| : { type: 'object', values: documents as JSONObject[] }; | ||
| try { | ||
| const { ranking, response, providerMetadata, warnings } = await retry( | ||
| async () => { | ||
| await notify({ | ||
| event: { | ||
| callId, | ||
| operationId: 'ai.rerank.doRerank', | ||
| provider: model.provider, | ||
| modelId: model.modelId, | ||
| documents, | ||
| documentsType: documentsToSend.type, | ||
| query, | ||
| topN, | ||
| isEnabled: telemetry?.isEnabled, | ||
| recordInputs: telemetry?.recordInputs, | ||
| recordOutputs: telemetry?.recordOutputs, | ||
| functionId: telemetry?.functionId, | ||
| metadata: telemetry?.metadata, | ||
| }, | ||
| callbacks: [globalTelemetry.onRerankStart], | ||
| }); | ||
| const baseTelemetryAttributes = getBaseTelemetryAttributes({ | ||
| model, | ||
| telemetry, | ||
| headers, | ||
| settings: { maxRetries }, | ||
| }); | ||
| const modelResponse = await model.doRerank({ | ||
| documents: documentsToSend, | ||
| query, | ||
| topN, | ||
| providerOptions, | ||
| abortSignal, | ||
| headers, | ||
| }); | ||
| const tracer = getTracer(telemetry); | ||
| const ranking = modelResponse.ranking; | ||
| return recordSpan({ | ||
| name: 'ai.rerank', | ||
| attributes: selectTelemetryAttributes({ | ||
| telemetry, | ||
| attributes: { | ||
| ...assembleOperationName({ operationId: 'ai.rerank', telemetry }), | ||
| ...baseTelemetryAttributes, | ||
| 'ai.documents': { | ||
| input: () => documents.map(document => JSON.stringify(document)), | ||
| }, | ||
| await notify({ | ||
| event: { | ||
| callId, | ||
| operationId: 'ai.rerank.doRerank', | ||
| provider: model.provider, | ||
| modelId: model.modelId, | ||
| documentsType: documentsToSend.type, | ||
| ranking, | ||
| }, | ||
| callbacks: [globalTelemetry.onRerankFinish], | ||
| }); | ||
| return { | ||
| ranking, | ||
| providerMetadata: modelResponse.providerMetadata, | ||
| response: modelResponse.response, | ||
| warnings: modelResponse.warnings, | ||
| }; | ||
| }, | ||
| }), | ||
| tracer, | ||
| fn: async () => { | ||
| const { ranking, response, providerMetadata, warnings } = await retry( | ||
| () => | ||
| recordSpan({ | ||
| name: 'ai.rerank.doRerank', | ||
| attributes: selectTelemetryAttributes({ | ||
| telemetry, | ||
| attributes: { | ||
| ...assembleOperationName({ | ||
| operationId: 'ai.rerank.doRerank', | ||
| telemetry, | ||
| }), | ||
| ...baseTelemetryAttributes, | ||
| // specific settings that only make sense on the outer level: | ||
| 'ai.documents': { | ||
| input: () => | ||
| documents.map(document => JSON.stringify(document)), | ||
| }, | ||
| }, | ||
| }), | ||
| tracer, | ||
| fn: async doRerankSpan => { | ||
| const modelResponse = await model.doRerank({ | ||
| documents: documentsToSend, | ||
| query, | ||
| topN, | ||
| providerOptions, | ||
| abortSignal, | ||
| headers, | ||
| }); | ||
| ); | ||
| const ranking = modelResponse.ranking; | ||
| logWarnings({ | ||
| warnings: warnings ?? [], | ||
| provider: model.provider, | ||
| model: model.modelId, | ||
| }); | ||
| doRerankSpan.setAttributes( | ||
| await selectTelemetryAttributes({ | ||
| telemetry, | ||
| attributes: { | ||
| 'ai.ranking.type': documentsToSend.type, | ||
| 'ai.ranking': { | ||
| output: () => | ||
| ranking.map(ranking => JSON.stringify(ranking)), | ||
| }, | ||
| }, | ||
| }), | ||
| ); | ||
| return { | ||
| ranking, | ||
| providerMetadata: modelResponse.providerMetadata, | ||
| response: modelResponse.response, | ||
| warnings: modelResponse.warnings, | ||
| }; | ||
| }, | ||
| }), | ||
| ); | ||
| logWarnings({ | ||
| warnings: warnings ?? [], | ||
| await notify({ | ||
| event: { | ||
| callId, | ||
| operationId: 'ai.rerank', | ||
| provider: model.provider, | ||
| model: model.modelId, | ||
| }); | ||
| await notify({ | ||
| event: { | ||
| callId, | ||
| operationId: 'ai.rerank', | ||
| provider: model.provider, | ||
| modelId: model.modelId, | ||
| documents, | ||
| query, | ||
| ranking: ranking.map(r => ({ | ||
| originalIndex: r.index, | ||
| score: r.relevanceScore, | ||
| document: documents[r.index], | ||
| })), | ||
| warnings: warnings ?? [], | ||
| providerMetadata, | ||
| response: { | ||
| id: response?.id, | ||
| timestamp: response?.timestamp ?? new Date(), | ||
| modelId: response?.modelId ?? model.modelId, | ||
| headers: response?.headers, | ||
| body: response?.body, | ||
| }, | ||
| isEnabled: telemetry?.isEnabled, | ||
| recordInputs: telemetry?.recordInputs, | ||
| recordOutputs: telemetry?.recordOutputs, | ||
| functionId: telemetry?.functionId, | ||
| metadata: telemetry?.metadata, | ||
| }, | ||
| callbacks: [onFinish], | ||
| }); | ||
| return new DefaultRerankResult({ | ||
| originalDocuments: documents, | ||
| ranking: ranking.map(ranking => ({ | ||
| originalIndex: ranking.index, | ||
| score: ranking.relevanceScore, | ||
| document: documents[ranking.index], | ||
| modelId: model.modelId, | ||
| documents, | ||
| query, | ||
| ranking: ranking.map(r => ({ | ||
| originalIndex: r.index, | ||
| score: r.relevanceScore, | ||
| document: documents[r.index], | ||
| })), | ||
| warnings: warnings ?? [], | ||
| providerMetadata, | ||
@@ -350,5 +302,31 @@ response: { | ||
| }, | ||
| }); | ||
| }, | ||
| }); | ||
| isEnabled: telemetry?.isEnabled, | ||
| recordInputs: telemetry?.recordInputs, | ||
| recordOutputs: telemetry?.recordOutputs, | ||
| functionId: telemetry?.functionId, | ||
| metadata: telemetry?.metadata, | ||
| }, | ||
| callbacks: [onFinish, globalTelemetry.onFinish], | ||
| }); | ||
| return new DefaultRerankResult({ | ||
| originalDocuments: documents, | ||
| ranking: ranking.map(ranking => ({ | ||
| originalIndex: ranking.index, | ||
| score: ranking.relevanceScore, | ||
| document: documents[ranking.index], | ||
| })), | ||
| providerMetadata, | ||
| response: { | ||
| id: response?.id, | ||
| timestamp: response?.timestamp ?? new Date(), | ||
| modelId: response?.modelId ?? model.modelId, | ||
| headers: response?.headers, | ||
| body: response?.body, | ||
| }, | ||
| }); | ||
| } catch (error) { | ||
| await globalTelemetry.onError?.({ callId, error }); | ||
| throw error; | ||
| } | ||
| } | ||
@@ -355,0 +333,0 @@ |
@@ -29,2 +29,4 @@ import type { Output } from '../generate-text/output'; | ||
| onEmbedFinish: integration.onEmbedFinish?.bind(integration), | ||
| onRerankStart: integration.onRerankStart?.bind(integration), | ||
| onRerankFinish: integration.onRerankFinish?.bind(integration), | ||
| onFinish: integration.onFinish?.bind(integration), | ||
@@ -104,2 +106,8 @@ onError: integration.onError?.bind(integration), | ||
| ), | ||
| onRerankStart: createTelemetryComposite( | ||
| integration => integration.onRerankStart, | ||
| ), | ||
| onRerankFinish: createTelemetryComposite( | ||
| integration => integration.onRerankFinish, | ||
| ), | ||
| onFinish: createTelemetryComposite(integration => integration.onFinish), | ||
@@ -106,0 +114,0 @@ onError: createTelemetryComposite(integration => integration.onError), |
@@ -19,2 +19,8 @@ import { LanguageModelV4Prompt } from '@ai-sdk/provider'; | ||
| import type { | ||
| RerankOnStartEvent, | ||
| RerankOnFinishEvent, | ||
| RerankStartEvent, | ||
| RerankFinishEvent, | ||
| } from '../rerank/rerank-events'; | ||
| import type { | ||
| OnChunkEvent, | ||
@@ -122,2 +128,3 @@ OnFinishEvent, | ||
| embedSpans: Map<string, { span: Span; context: Context }>; | ||
| rerankSpan: { span: Span; context: Context } | undefined; | ||
| toolSpans: Map<string, { span: Span; context: Context }>; | ||
@@ -170,3 +177,8 @@ baseTelemetryAttributes: Attributes; | ||
| onStart(event: OnStartEvent<ToolSet, Output> | EmbedOnStartEvent): void { | ||
| onStart( | ||
| event: | ||
| | OnStartEvent<ToolSet, Output> | ||
| | EmbedOnStartEvent | ||
| | RerankOnStartEvent, | ||
| ): void { | ||
| if (event.isEnabled !== true) return; | ||
@@ -182,2 +194,7 @@ | ||
| if (event.operationId === 'ai.rerank') { | ||
| this.onRerankOperationStart(event as RerankOnStartEvent); | ||
| return; | ||
| } | ||
| this.onGenerateStart(event as OnStartEvent<ToolSet, Output>); | ||
@@ -243,2 +260,3 @@ } | ||
| embedSpans: new Map(), | ||
| rerankSpan: undefined, | ||
| toolSpans: new Map(), | ||
@@ -303,2 +321,3 @@ baseTelemetryAttributes, | ||
| embedSpans: new Map(), | ||
| rerankSpan: undefined, | ||
| toolSpans: new Map(), | ||
@@ -506,3 +525,5 @@ baseTelemetryAttributes, | ||
| onFinish(event: OnFinishEvent<ToolSet> | EmbedOnFinishEvent): void { | ||
| onFinish( | ||
| event: OnFinishEvent<ToolSet> | EmbedOnFinishEvent | RerankOnFinishEvent, | ||
| ): void { | ||
| const state = this.getCallState(event.callId); | ||
@@ -519,2 +540,7 @@ if (!state?.rootSpan) return; | ||
| if (state.operationId === 'ai.rerank') { | ||
| this.onRerankOperationFinish(event as RerankOnFinishEvent); | ||
| return; | ||
| } | ||
| this.onGenerateFinish(event as OnFinishEvent<ToolSet>); | ||
@@ -665,2 +691,106 @@ } | ||
| private onRerankOperationStart(event: RerankOnStartEvent): void { | ||
| const telemetry: TelemetrySettings = { | ||
| isEnabled: event.isEnabled, | ||
| recordInputs: event.recordInputs, | ||
| recordOutputs: event.recordOutputs, | ||
| functionId: event.functionId, | ||
| metadata: event.metadata, | ||
| }; | ||
| const settings: Record<string, unknown> = { | ||
| maxRetries: event.maxRetries, | ||
| }; | ||
| const baseTelemetryAttributes = getBaseTelemetryAttributes({ | ||
| model: { provider: event.provider, modelId: event.modelId }, | ||
| telemetry, | ||
| headers: event.headers, | ||
| settings, | ||
| }); | ||
| const attributes = selectAttributes(telemetry, { | ||
| ...assembleOperationName({ | ||
| operationId: event.operationId, | ||
| telemetry, | ||
| }), | ||
| ...baseTelemetryAttributes, | ||
| 'ai.documents': { | ||
| input: () => event.documents.map(d => JSON.stringify(d)), | ||
| }, | ||
| }); | ||
| const rootSpan = this.tracer.startSpan(event.operationId, { attributes }); | ||
| const rootContext = trace.setSpan(context.active(), rootSpan); | ||
| this.callStates.set(event.callId, { | ||
| operationId: event.operationId, | ||
| telemetry, | ||
| rootSpan, | ||
| rootContext, | ||
| stepSpan: undefined, | ||
| stepContext: undefined, | ||
| embedSpans: new Map(), | ||
| rerankSpan: undefined, | ||
| toolSpans: new Map(), | ||
| baseTelemetryAttributes, | ||
| settings, | ||
| }); | ||
| } | ||
| private onRerankOperationFinish(event: RerankOnFinishEvent): void { | ||
| const state = this.getCallState(event.callId); | ||
| if (!state?.rootSpan) return; | ||
| state.rootSpan.end(); | ||
| this.cleanupCallState(event.callId); | ||
| } | ||
| onRerankStart(event: RerankStartEvent): void { | ||
| const state = this.getCallState(event.callId); | ||
| if (!state?.rootSpan || !state.rootContext) return; | ||
| const { telemetry } = state; | ||
| const attributes = selectAttributes(telemetry, { | ||
| ...assembleOperationName({ | ||
| operationId: event.operationId, | ||
| telemetry, | ||
| }), | ||
| ...state.baseTelemetryAttributes, | ||
| 'ai.documents': { | ||
| input: () => event.documents.map(d => JSON.stringify(d)), | ||
| }, | ||
| }); | ||
| const rerankSpan = this.tracer.startSpan( | ||
| event.operationId, | ||
| { attributes }, | ||
| state.rootContext, | ||
| ); | ||
| const rerankContext = trace.setSpan(state.rootContext, rerankSpan); | ||
| state.rerankSpan = { span: rerankSpan, context: rerankContext }; | ||
| } | ||
| onRerankFinish(event: RerankFinishEvent): void { | ||
| const state = this.getCallState(event.callId); | ||
| if (!state?.rerankSpan) return; | ||
| const { span } = state.rerankSpan; | ||
| const { telemetry } = state; | ||
| span.setAttributes( | ||
| selectAttributes(telemetry, { | ||
| 'ai.ranking.type': event.documentsType, | ||
| 'ai.ranking': { | ||
| output: () => event.ranking.map(r => JSON.stringify(r)), | ||
| }, | ||
| }), | ||
| ); | ||
| span.end(); | ||
| state.rerankSpan = undefined; | ||
| } | ||
| onChunk(event: OnChunkEvent<ToolSet>): void { | ||
@@ -719,2 +849,8 @@ const chunk = event.chunk as { | ||
| if (state.rerankSpan) { | ||
| recordSpanError(state.rerankSpan.span, actualError); | ||
| state.rerankSpan.span.end(); | ||
| state.rerankSpan = undefined; | ||
| } | ||
| recordSpanError(state.rootSpan, actualError); | ||
@@ -721,0 +857,0 @@ |
@@ -18,2 +18,8 @@ import type { | ||
| } from '../embed/embed-events'; | ||
| import type { | ||
| RerankOnStartEvent, | ||
| RerankOnFinishEvent, | ||
| RerankStartEvent, | ||
| RerankFinishEvent, | ||
| } from '../rerank/rerank-events'; | ||
| import { Listener } from '../util/notify'; | ||
@@ -32,3 +38,5 @@ | ||
| */ | ||
| onStart?: Listener<OnStartEvent<ToolSet, Output> | EmbedOnStartEvent>; | ||
| onStart?: Listener< | ||
| OnStartEvent<ToolSet, Output> | EmbedOnStartEvent | RerankOnStartEvent | ||
| >; | ||
@@ -89,2 +97,14 @@ /** | ||
| /** | ||
| * Called when an individual reranking model call (doRerank) begins. | ||
| * There is one call per `rerank` invocation. | ||
| */ | ||
| onRerankStart?: Listener<RerankStartEvent>; | ||
| /** | ||
| * Called when an individual reranking model call (doRerank) completes. | ||
| * Contains the ranking results from the model response. | ||
| */ | ||
| onRerankFinish?: Listener<RerankFinishEvent>; | ||
| /** | ||
| * Called when an operation completes. Fired for both text generation | ||
@@ -95,3 +115,5 @@ * (generateText/streamText) and embedding (embed/embedMany) operations. | ||
| */ | ||
| onFinish?: Listener<OnFinishEvent<ToolSet> | EmbedOnFinishEvent>; | ||
| onFinish?: Listener< | ||
| OnFinishEvent<ToolSet> | EmbedOnFinishEvent | RerankOnFinishEvent | ||
| >; | ||
@@ -98,0 +120,0 @@ /** |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
6884614
0.41%66629
0.66%140
4.48%