Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/beige-colts-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/ai': minor
---

Added telemetry field to activities and events
21 changes: 15 additions & 6 deletions packages/typescript/ai/src/activities/chat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type {
RunFinishedEvent,
SchemaInput,
StreamChunk,
Telemetry,
TextMessageContentEvent,
TextOptions,
Tool,
Expand Down Expand Up @@ -130,6 +131,10 @@ export interface TextActivityOptions<
* ```
*/
stream?: TStream
/**
* Telemetry data for tracking and monitoring.
*/
telemetry?: TextOptions['telemetry']
}

// ===========================
Expand Down Expand Up @@ -175,8 +180,8 @@ export type TextActivityResult<
> = TSchema extends SchemaInput
? Promise<InferSchemaType<TSchema>>
: TStream extends false
? Promise<string>
: AsyncIterable<StreamChunk>
? Promise<string>
: AsyncIterable<StreamChunk>

// ===========================
// ChatEngine Implementation
Expand Down Expand Up @@ -209,6 +214,7 @@ class TextEngine<
private readonly streamId: string
private readonly effectiveRequest?: Request | RequestInit
private readonly effectiveSignal?: AbortSignal
private readonly telemetry?: Telemetry

private messages: Array<ModelMessage>
private iterationCount = 0
Expand Down Expand Up @@ -241,6 +247,7 @@ class TextEngine<
? { signal: config.params.abortController.signal }
: undefined
this.effectiveSignal = config.params.abortController?.signal
this.telemetry = config.params.telemetry
}

/** Get the accumulated content after the chat loop completes */
Expand Down Expand Up @@ -942,6 +949,7 @@ class TextEngine<
messageCount: number
hasTools: boolean
streaming: boolean
telemetry?: Telemetry
} {
return {
requestId: this.requestId,
Expand All @@ -960,6 +968,7 @@ class TextEngine<
messageCount: this.initialMessageCount,
hasTools: this.tools.length > 0,
streaming: true,
telemetry: this.telemetry,
}
}

Expand Down Expand Up @@ -1194,10 +1203,10 @@ async function runAgenticStructuredOutput<TSchema extends SchemaInput>(
}

// Re-export adapter types
export { BaseTextAdapter } from './adapter'
export type {
TextAdapter,
TextAdapterConfig,
StructuredOutputOptions,
StructuredOutputResult,
StructuredOutputResult, TextAdapter,
TextAdapterConfig
} from './adapter'
export { BaseTextAdapter } from './adapter'

49 changes: 28 additions & 21 deletions packages/typescript/ai/src/activities/generateImage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/

import { aiEventClient } from '../../event-client.js'
import type { ImageGenerationOptions, ImageGenerationResult } from '../../types'
import type { ImageAdapter } from './adapter'
import type { ImageGenerationResult } from '../../types'

// ===========================
// Activity Kind
Expand All @@ -27,29 +27,29 @@ export const kind = 'image' as const
*/
export type ImageProviderOptionsForModel<TAdapter, TModel extends string> =
TAdapter extends ImageAdapter<any, infer BaseOptions, infer ModelOptions, any>
? string extends keyof ModelOptions
? // ModelOptions is Record<string, unknown> or has index signature - use BaseOptions
BaseOptions
: // ModelOptions has explicit keys - check if TModel is one of them
TModel extends keyof ModelOptions
? ModelOptions[TModel]
: BaseOptions
: object
? string extends keyof ModelOptions
? // ModelOptions is Record<string, unknown> or has index signature - use BaseOptions
BaseOptions
: // ModelOptions has explicit keys - check if TModel is one of them
TModel extends keyof ModelOptions
? ModelOptions[TModel]
: BaseOptions
: object

/**
* Extract model-specific size options from an ImageAdapter via ~types.
* If the model has specific sizes defined, use those; otherwise fall back to string.
*/
export type ImageSizeForModel<TAdapter, TModel extends string> =
TAdapter extends ImageAdapter<any, any, any, infer SizeByName>
? string extends keyof SizeByName
? // SizeByName has index signature - fall back to string
string
: // SizeByName has explicit keys - check if TModel is one of them
TModel extends keyof SizeByName
? SizeByName[TModel]
: string
: string
? string extends keyof SizeByName
? // SizeByName has index signature - fall back to string
string
: // SizeByName has explicit keys - check if TModel is one of them
TModel extends keyof SizeByName
? SizeByName[TModel]
: string
: string

// ===========================
// Activity Options Type
Expand All @@ -74,6 +74,10 @@ export interface ImageActivityOptions<
size?: ImageSizeForModel<TAdapter, TAdapter['model']>
/** Provider-specific options for image generation */
modelOptions?: ImageProviderOptionsForModel<TAdapter, TAdapter['model']>
/**
* Telemetry data for tracking and monitoring.
*/
telemetry?: ImageGenerationOptions['telemetry']
}

// ===========================
Expand Down Expand Up @@ -152,6 +156,7 @@ export async function generateImage<
numberOfImages: rest.numberOfImages,
size: rest.size as string | undefined,
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
telemetry: rest.telemetry,
timestamp: startTime,
})

Expand All @@ -168,6 +173,7 @@ export async function generateImage<
})),
duration,
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
telemetry: rest.telemetry,
timestamp: Date.now(),
})

Expand All @@ -177,6 +183,7 @@ export async function generateImage<
model,
usage: result.usage,
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
telemetry: rest.telemetry,
timestamp: Date.now(),
})
}
Expand All @@ -199,9 +206,9 @@ export function createImageOptions<
}

// Re-export adapter types
export { BaseImageAdapter } from './adapter'
export type {
ImageAdapter,
ImageAdapterConfig,
AnyImageAdapter,
AnyImageAdapter, ImageAdapter,
ImageAdapterConfig
} from './adapter'
export { BaseImageAdapter } from './adapter'

15 changes: 11 additions & 4 deletions packages/typescript/ai/src/activities/generateSpeech/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/

import { aiEventClient } from '../../event-client.js'
import type { TTSOptions, TTSResult } from '../../types'
import type { TTSAdapter } from './adapter'
import type { TTSResult } from '../../types'

// ===========================
// Activity Kind
Expand All @@ -25,8 +25,8 @@ export const kind = 'tts' as const
*/
export type TTSProviderOptions<TAdapter> =
TAdapter extends TTSAdapter<any, any>
? TAdapter['~types']['providerOptions']
: object
? TAdapter['~types']['providerOptions']
: object

// ===========================
// Activity Options Type
Expand All @@ -53,6 +53,10 @@ export interface TTSActivityOptions<
speed?: number
/** Provider-specific options for TTS generation */
modelOptions?: TTSProviderOptions<TAdapter>
/**
* Telemetry data for tracking and monitoring.
*/
telemetry?: TTSOptions['telemetry']
}

// ===========================
Expand Down Expand Up @@ -117,6 +121,7 @@ export async function generateSpeech<
format: rest.format,
speed: rest.speed,
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
telemetry: rest.telemetry,
timestamp: startTime,
})

Expand All @@ -133,6 +138,7 @@ export async function generateSpeech<
contentType: result.contentType,
duration,
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
telemetry: rest.telemetry,
timestamp: Date.now(),
})

Expand All @@ -154,5 +160,6 @@ export function createSpeechOptions<
}

// Re-export adapter types
export type { TTSAdapter, TTSAdapterConfig, AnyTTSAdapter } from './adapter'
export { BaseTTSAdapter } from './adapter'
export type { AnyTTSAdapter, TTSAdapter, TTSAdapterConfig } from './adapter'

Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/

import { aiEventClient } from '../../event-client.js'
import type { TranscriptionOptions, TranscriptionResult } from '../../types'
import type { TranscriptionAdapter } from './adapter'
import type { TranscriptionResult } from '../../types'

// ===========================
// Activity Kind
Expand All @@ -25,8 +25,8 @@ export const kind = 'transcription' as const
*/
export type TranscriptionProviderOptions<TAdapter> =
TAdapter extends TranscriptionAdapter<any, any>
? TAdapter['~types']['providerOptions']
: object
? TAdapter['~types']['providerOptions']
: object

// ===========================
// Activity Options Type
Expand All @@ -53,6 +53,10 @@ export interface TranscriptionActivityOptions<
responseFormat?: 'json' | 'text' | 'srt' | 'verbose_json' | 'vtt'
/** Provider-specific options for transcription */
modelOptions?: TranscriptionProviderOptions<TAdapter>
/**
* Telemetry data for tracking and monitoring.
*/
telemetry?: TranscriptionOptions['telemetry']
}

// ===========================
Expand Down Expand Up @@ -120,6 +124,7 @@ export async function generateTranscription<
prompt: rest.prompt,
responseFormat: rest.responseFormat,
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
telemetry: rest.telemetry,
timestamp: startTime,
})

Expand All @@ -134,6 +139,7 @@ export async function generateTranscription<
language: result.language,
duration,
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
telemetry: rest.telemetry,
timestamp: Date.now(),
})

Expand All @@ -156,9 +162,9 @@ export function createTranscriptionOptions<
}

// Re-export adapter types
export { BaseTranscriptionAdapter } from './adapter'
export type {
TranscriptionAdapter,
TranscriptionAdapterConfig,
AnyTranscriptionAdapter,
AnyTranscriptionAdapter, TranscriptionAdapter,
TranscriptionAdapterConfig
} from './adapter'
export { BaseTranscriptionAdapter } from './adapter'

Loading