@tanstack/ai 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/activities/chat/adapter.d.ts +6 -1
- package/dist/esm/activities/chat/adapter.js.map +1 -1
- package/dist/esm/activities/chat/index.d.ts +8 -0
- package/dist/esm/activities/chat/index.js +78 -17
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/chat/middleware/compose.d.ts +3 -1
- package/dist/esm/activities/chat/middleware/compose.js +79 -1
- package/dist/esm/activities/chat/middleware/compose.js.map +1 -1
- package/dist/esm/activities/error-payload.d.ts +12 -0
- package/dist/esm/activities/error-payload.js +25 -0
- package/dist/esm/activities/error-payload.js.map +1 -0
- package/dist/esm/activities/generateAudio/adapter.d.ts +62 -0
- package/dist/esm/activities/generateAudio/adapter.js +14 -0
- package/dist/esm/activities/generateAudio/adapter.js.map +1 -0
- package/dist/esm/activities/generateAudio/index.d.ts +74 -0
- package/dist/esm/activities/generateAudio/index.js +80 -0
- package/dist/esm/activities/generateAudio/index.js.map +1 -0
- package/dist/esm/activities/generateImage/adapter.d.ts +1 -1
- package/dist/esm/activities/generateImage/adapter.js +1 -1
- package/dist/esm/activities/generateImage/adapter.js.map +1 -1
- package/dist/esm/activities/generateImage/index.d.ts +7 -0
- package/dist/esm/activities/generateImage/index.js +19 -3
- package/dist/esm/activities/generateImage/index.js.map +1 -1
- package/dist/esm/activities/generateSpeech/adapter.d.ts +1 -1
- package/dist/esm/activities/generateSpeech/adapter.js +1 -1
- package/dist/esm/activities/generateSpeech/adapter.js.map +1 -1
- package/dist/esm/activities/generateSpeech/index.d.ts +10 -3
- package/dist/esm/activities/generateSpeech/index.js +32 -3
- package/dist/esm/activities/generateSpeech/index.js.map +1 -1
- package/dist/esm/activities/generateTranscription/adapter.d.ts +1 -1
- package/dist/esm/activities/generateTranscription/adapter.js +1 -1
- package/dist/esm/activities/generateTranscription/adapter.js.map +1 -1
- package/dist/esm/activities/generateTranscription/index.d.ts +10 -3
- package/dist/esm/activities/generateTranscription/index.js +43 -13
- package/dist/esm/activities/generateTranscription/index.js.map +1 -1
- package/dist/esm/activities/generateVideo/index.d.ts +7 -0
- package/dist/esm/activities/generateVideo/index.js +55 -13
- package/dist/esm/activities/generateVideo/index.js.map +1 -1
- package/dist/esm/activities/index.d.ts +5 -2
- package/dist/esm/activities/index.js +11 -6
- package/dist/esm/activities/index.js.map +1 -1
- package/dist/esm/activities/stream-generation-result.js +5 -6
- package/dist/esm/activities/stream-generation-result.js.map +1 -1
- package/dist/esm/activities/summarize/index.d.ts +7 -0
- package/dist/esm/activities/summarize/index.js +54 -19
- package/dist/esm/activities/summarize/index.js.map +1 -1
- package/dist/esm/adapter-internals.d.ts +4 -0
- package/dist/esm/adapter-internals.js +9 -0
- package/dist/esm/adapter-internals.js.map +1 -0
- package/dist/esm/index.d.ts +5 -2
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/logger/console-logger.d.ts +11 -0
- package/dist/esm/logger/console-logger.js +27 -0
- package/dist/esm/logger/console-logger.js.map +1 -0
- package/dist/esm/logger/internal-logger.d.ts +33 -0
- package/dist/esm/logger/internal-logger.js +69 -0
- package/dist/esm/logger/internal-logger.js.map +1 -0
- package/dist/esm/logger/resolve.d.ts +14 -0
- package/dist/esm/logger/resolve.js +54 -0
- package/dist/esm/logger/resolve.js.map +1 -0
- package/dist/esm/logger/types.d.ts +75 -0
- package/dist/esm/stream-to-response.js +3 -8
- package/dist/esm/stream-to-response.js.map +1 -1
- package/dist/esm/types.d.ts +97 -6
- package/package.json +6 -2
- package/skills/ai-core/SKILL.md +5 -3
- package/skills/ai-core/debug-logging/SKILL.md +263 -0
- package/skills/ai-core/media-generation/SKILL.md +154 -10
- package/src/activities/chat/adapter.ts +6 -1
- package/src/activities/chat/index.ts +104 -22
- package/src/activities/chat/middleware/compose.ts +84 -1
- package/src/activities/error-payload.ts +35 -0
- package/src/activities/generateAudio/adapter.ts +89 -0
- package/src/activities/generateAudio/index.ts +224 -0
- package/src/activities/generateImage/adapter.ts +1 -1
- package/src/activities/generateImage/index.ts +29 -3
- package/src/activities/generateSpeech/adapter.ts +1 -1
- package/src/activities/generateSpeech/index.ts +51 -9
- package/src/activities/generateTranscription/adapter.ts +1 -1
- package/src/activities/generateTranscription/index.ts +72 -17
- package/src/activities/generateVideo/index.ts +72 -13
- package/src/activities/index.ts +22 -0
- package/src/activities/stream-generation-result.ts +6 -7
- package/src/activities/summarize/index.ts +66 -20
- package/src/adapter-internals.ts +8 -0
- package/src/index.ts +13 -0
- package/src/logger/console-logger.ts +49 -0
- package/src/logger/internal-logger.ts +107 -0
- package/src/logger/resolve.ts +72 -0
- package/src/logger/types.ts +78 -0
- package/src/stream-to-response.ts +5 -10
- package/src/types.ts +110 -5
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
import { aiEventClient } from '@tanstack/ai-event-client'
|
|
9
9
|
import { streamGenerationResult } from '../stream-generation-result.js'
|
|
10
|
+
import { resolveDebugOption } from '../../logger/resolve'
|
|
11
|
+
import type { InternalLogger } from '../../logger/internal-logger'
|
|
12
|
+
import type { DebugOption } from '../../logger/types'
|
|
10
13
|
import type { TranscriptionAdapter } from './adapter'
|
|
11
14
|
import type { StreamChunk, TranscriptionResult } from '../../types'
|
|
12
15
|
|
|
@@ -41,7 +44,10 @@ export type TranscriptionProviderOptions<TAdapter> =
|
|
|
41
44
|
* @template TStream - Whether to stream the output
|
|
42
45
|
*/
|
|
43
46
|
export interface TranscriptionActivityOptions<
|
|
44
|
-
TAdapter extends TranscriptionAdapter<
|
|
47
|
+
TAdapter extends TranscriptionAdapter<
|
|
48
|
+
string,
|
|
49
|
+
TranscriptionProviderOptions<TAdapter>
|
|
50
|
+
>,
|
|
45
51
|
TStream extends boolean = false,
|
|
46
52
|
> {
|
|
47
53
|
/** The transcription adapter to use (must be created with a model) */
|
|
@@ -64,6 +70,12 @@ export interface TranscriptionActivityOptions<
|
|
|
64
70
|
* @default false
|
|
65
71
|
*/
|
|
66
72
|
stream?: TStream
|
|
73
|
+
/**
|
|
74
|
+
* Enable debug logging. Pass `true` to enable all categories, `false` to
|
|
75
|
+
* silence everything including errors, or a `DebugConfig` object for granular
|
|
76
|
+
* control and/or a custom `Logger`.
|
|
77
|
+
*/
|
|
78
|
+
debug?: DebugOption
|
|
67
79
|
}
|
|
68
80
|
|
|
69
81
|
// ===========================
|
|
@@ -132,7 +144,10 @@ function createId(prefix: string): string {
|
|
|
132
144
|
* ```
|
|
133
145
|
*/
|
|
134
146
|
export function generateTranscription<
|
|
135
|
-
TAdapter extends TranscriptionAdapter<
|
|
147
|
+
TAdapter extends TranscriptionAdapter<
|
|
148
|
+
string,
|
|
149
|
+
TranscriptionProviderOptions<TAdapter>
|
|
150
|
+
>,
|
|
136
151
|
TStream extends boolean = false,
|
|
137
152
|
>(
|
|
138
153
|
options: TranscriptionActivityOptions<TAdapter, TStream>,
|
|
@@ -152,14 +167,22 @@ export function generateTranscription<
|
|
|
152
167
|
* Run non-streaming transcription
|
|
153
168
|
*/
|
|
154
169
|
async function runGenerateTranscription<
|
|
155
|
-
TAdapter extends TranscriptionAdapter<
|
|
170
|
+
TAdapter extends TranscriptionAdapter<
|
|
171
|
+
string,
|
|
172
|
+
TranscriptionProviderOptions<TAdapter>
|
|
173
|
+
>,
|
|
156
174
|
>(
|
|
157
175
|
options: TranscriptionActivityOptions<TAdapter, boolean>,
|
|
158
176
|
): Promise<TranscriptionResult> {
|
|
159
|
-
const { adapter, stream: _stream, ...rest } = options
|
|
177
|
+
const { adapter, stream: _stream, debug: _debug, ...rest } = options
|
|
160
178
|
const model = adapter.model
|
|
161
179
|
const requestId = createId('transcription')
|
|
162
180
|
const startTime = Date.now()
|
|
181
|
+
const logger: InternalLogger = resolveDebugOption(options.debug)
|
|
182
|
+
const providerName =
|
|
183
|
+
(adapter as { name?: string; provider?: string }).provider ??
|
|
184
|
+
(adapter as { name?: string }).name ??
|
|
185
|
+
'unknown'
|
|
163
186
|
|
|
164
187
|
aiEventClient.emit('transcription:request:started', {
|
|
165
188
|
requestId,
|
|
@@ -172,21 +195,50 @@ async function runGenerateTranscription<
|
|
|
172
195
|
timestamp: startTime,
|
|
173
196
|
})
|
|
174
197
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
aiEventClient.emit('transcription:request:completed', {
|
|
179
|
-
requestId,
|
|
180
|
-
provider: adapter.name,
|
|
198
|
+
logger.request(`activity=generateTranscription provider=${providerName}`, {
|
|
199
|
+
provider: providerName,
|
|
181
200
|
model,
|
|
182
|
-
text: result.text,
|
|
183
|
-
language: result.language,
|
|
184
|
-
duration,
|
|
185
|
-
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
|
|
186
|
-
timestamp: Date.now(),
|
|
187
201
|
})
|
|
188
202
|
|
|
189
|
-
|
|
203
|
+
try {
|
|
204
|
+
const result = await adapter.transcribe({ ...rest, model, logger })
|
|
205
|
+
const duration = Date.now() - startTime
|
|
206
|
+
|
|
207
|
+
aiEventClient.emit('transcription:request:completed', {
|
|
208
|
+
requestId,
|
|
209
|
+
provider: adapter.name,
|
|
210
|
+
model,
|
|
211
|
+
text: result.text,
|
|
212
|
+
language: result.language,
|
|
213
|
+
duration,
|
|
214
|
+
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
|
|
215
|
+
timestamp: Date.now(),
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
logger.output(
|
|
219
|
+
`activity=generateTranscription length=${result.text.length}`,
|
|
220
|
+
{ hasText: !!result.text },
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
return result
|
|
224
|
+
} catch (error) {
|
|
225
|
+
const duration = Date.now() - startTime
|
|
226
|
+
const err = error as Error
|
|
227
|
+
aiEventClient.emit('transcription:request:error', {
|
|
228
|
+
requestId,
|
|
229
|
+
provider: adapter.name,
|
|
230
|
+
model,
|
|
231
|
+
error: { message: err.message, name: err.name },
|
|
232
|
+
duration,
|
|
233
|
+
modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
|
|
234
|
+
timestamp: Date.now(),
|
|
235
|
+
})
|
|
236
|
+
logger.errors('generateTranscription activity failed', {
|
|
237
|
+
error,
|
|
238
|
+
source: 'generateTranscription',
|
|
239
|
+
})
|
|
240
|
+
throw error
|
|
241
|
+
}
|
|
190
242
|
}
|
|
191
243
|
|
|
192
244
|
// ===========================
|
|
@@ -197,7 +249,10 @@ async function runGenerateTranscription<
|
|
|
197
249
|
* Create typed options for the generateTranscription() function without executing.
|
|
198
250
|
*/
|
|
199
251
|
export function createTranscriptionOptions<
|
|
200
|
-
TAdapter extends TranscriptionAdapter<
|
|
252
|
+
TAdapter extends TranscriptionAdapter<
|
|
253
|
+
string,
|
|
254
|
+
TranscriptionProviderOptions<TAdapter>
|
|
255
|
+
>,
|
|
201
256
|
TStream extends boolean = false,
|
|
202
257
|
>(
|
|
203
258
|
options: TranscriptionActivityOptions<TAdapter, TStream>,
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { aiEventClient } from '@tanstack/ai-event-client'
|
|
11
|
+
import { toRunErrorPayload } from '../error-payload'
|
|
12
|
+
import { resolveDebugOption } from '../../logger/resolve'
|
|
13
|
+
import type { InternalLogger } from '../../logger/internal-logger'
|
|
14
|
+
import type { DebugOption } from '../../logger/types'
|
|
11
15
|
import type { VideoAdapter } from './adapter'
|
|
12
16
|
import type {
|
|
13
17
|
StreamChunk,
|
|
@@ -100,6 +104,12 @@ export type VideoCreateOptions<
|
|
|
100
104
|
maxDuration?: number
|
|
101
105
|
/** Custom run ID (stream mode only) */
|
|
102
106
|
runId?: string
|
|
107
|
+
/**
|
|
108
|
+
* Enable debug logging. Pass `true` to enable all categories, `false` to
|
|
109
|
+
* silence everything including errors, or a `DebugConfig` object for granular
|
|
110
|
+
* control and/or a custom `Logger`.
|
|
111
|
+
*/
|
|
112
|
+
debug?: DebugOption
|
|
103
113
|
} & ({} extends VideoProviderOptions<TAdapter>
|
|
104
114
|
? {
|
|
105
115
|
/** Provider-specific options for video generation */ modelOptions?: VideoProviderOptions<TAdapter>
|
|
@@ -241,14 +251,38 @@ async function runCreateVideoJob<
|
|
|
241
251
|
>(options: VideoCreateOptions<TAdapter, boolean>): Promise<VideoJobResult> {
|
|
242
252
|
const { adapter, prompt, size, duration, modelOptions } = options
|
|
243
253
|
const model = adapter.model
|
|
244
|
-
|
|
245
|
-
|
|
254
|
+
const logger: InternalLogger = resolveDebugOption(options.debug)
|
|
255
|
+
const providerName =
|
|
256
|
+
(adapter as { name?: string; provider?: string }).provider ??
|
|
257
|
+
(adapter as { name?: string }).name ??
|
|
258
|
+
'unknown'
|
|
259
|
+
|
|
260
|
+
logger.request(`activity=generateVideo provider=${providerName}`, {
|
|
261
|
+
provider: providerName,
|
|
246
262
|
model,
|
|
247
|
-
prompt,
|
|
248
|
-
size,
|
|
249
|
-
duration,
|
|
250
|
-
modelOptions,
|
|
251
263
|
})
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
const result = await adapter.createVideoJob({
|
|
267
|
+
model,
|
|
268
|
+
prompt,
|
|
269
|
+
size,
|
|
270
|
+
duration,
|
|
271
|
+
modelOptions,
|
|
272
|
+
logger,
|
|
273
|
+
})
|
|
274
|
+
logger.output(`activity=generateVideo jobId=${result.jobId}`, {
|
|
275
|
+
jobId: result.jobId,
|
|
276
|
+
model: result.model,
|
|
277
|
+
})
|
|
278
|
+
return result
|
|
279
|
+
} catch (error) {
|
|
280
|
+
logger.errors('generateVideo activity failed', {
|
|
281
|
+
error,
|
|
282
|
+
source: 'generateVideo',
|
|
283
|
+
})
|
|
284
|
+
throw error
|
|
285
|
+
}
|
|
252
286
|
}
|
|
253
287
|
|
|
254
288
|
function sleep(ms: number): Promise<void> {
|
|
@@ -267,6 +301,11 @@ async function* runStreamingVideoGeneration<
|
|
|
267
301
|
const runId = options.runId ?? createId('run')
|
|
268
302
|
const pollingInterval = options.pollingInterval ?? 2000
|
|
269
303
|
const maxDuration = options.maxDuration ?? 600_000
|
|
304
|
+
const logger: InternalLogger = resolveDebugOption(options.debug)
|
|
305
|
+
const providerName =
|
|
306
|
+
(adapter as { name?: string; provider?: string }).provider ??
|
|
307
|
+
(adapter as { name?: string }).name ??
|
|
308
|
+
'unknown'
|
|
270
309
|
|
|
271
310
|
const threadId = createId('thread')
|
|
272
311
|
|
|
@@ -277,6 +316,14 @@ async function* runStreamingVideoGeneration<
|
|
|
277
316
|
timestamp: Date.now(),
|
|
278
317
|
} as StreamChunk
|
|
279
318
|
|
|
319
|
+
logger.request(
|
|
320
|
+
`activity=generateVideo provider=${providerName} stream=true`,
|
|
321
|
+
{
|
|
322
|
+
provider: providerName,
|
|
323
|
+
model,
|
|
324
|
+
},
|
|
325
|
+
)
|
|
326
|
+
|
|
280
327
|
try {
|
|
281
328
|
// Create the video generation job
|
|
282
329
|
const jobResult = await adapter.createVideoJob({
|
|
@@ -285,6 +332,7 @@ async function* runStreamingVideoGeneration<
|
|
|
285
332
|
size,
|
|
286
333
|
duration,
|
|
287
334
|
modelOptions,
|
|
335
|
+
logger,
|
|
288
336
|
})
|
|
289
337
|
|
|
290
338
|
yield {
|
|
@@ -316,6 +364,14 @@ async function* runStreamingVideoGeneration<
|
|
|
316
364
|
if (statusResult.status === 'completed') {
|
|
317
365
|
const urlResult = await adapter.getVideoUrl(jobResult.jobId)
|
|
318
366
|
|
|
367
|
+
logger.output(
|
|
368
|
+
`activity=generateVideo jobId=${jobResult.jobId} status=completed`,
|
|
369
|
+
{
|
|
370
|
+
jobId: jobResult.jobId,
|
|
371
|
+
url: urlResult.url,
|
|
372
|
+
},
|
|
373
|
+
)
|
|
374
|
+
|
|
319
375
|
yield {
|
|
320
376
|
type: 'CUSTOM',
|
|
321
377
|
name: 'generation:result',
|
|
@@ -344,17 +400,20 @@ async function* runStreamingVideoGeneration<
|
|
|
344
400
|
}
|
|
345
401
|
|
|
346
402
|
throw new Error('Video generation timed out')
|
|
347
|
-
} catch (error:
|
|
403
|
+
} catch (error: unknown) {
|
|
404
|
+
const payload = toRunErrorPayload(error, 'Video generation failed')
|
|
405
|
+
logger.errors('generateVideo activity failed', {
|
|
406
|
+
message: payload.message,
|
|
407
|
+
code: payload.code,
|
|
408
|
+
source: 'generateVideo',
|
|
409
|
+
})
|
|
348
410
|
yield {
|
|
349
411
|
type: 'RUN_ERROR',
|
|
350
412
|
runId,
|
|
351
413
|
threadId,
|
|
352
|
-
message:
|
|
353
|
-
code:
|
|
354
|
-
error:
|
|
355
|
-
message: error.message || 'Video generation failed',
|
|
356
|
-
code: error.code,
|
|
357
|
-
},
|
|
414
|
+
message: payload.message,
|
|
415
|
+
code: payload.code,
|
|
416
|
+
error: payload,
|
|
358
417
|
timestamp: Date.now(),
|
|
359
418
|
} as StreamChunk
|
|
360
419
|
}
|
package/src/activities/index.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import type { AnyTextAdapter } from './chat/adapter'
|
|
18
18
|
import type { AnySummarizeAdapter } from './summarize/adapter'
|
|
19
19
|
import type { AnyImageAdapter } from './generateImage/adapter'
|
|
20
|
+
import type { AnyAudioAdapter } from './generateAudio/adapter'
|
|
20
21
|
import type { AnyVideoAdapter } from './generateVideo/adapter'
|
|
21
22
|
import type { AnyTTSAdapter } from './generateSpeech/adapter'
|
|
22
23
|
import type { AnyTranscriptionAdapter } from './generateTranscription/adapter'
|
|
@@ -80,6 +81,25 @@ export {
|
|
|
80
81
|
type AnyImageAdapter,
|
|
81
82
|
} from './generateImage/adapter'
|
|
82
83
|
|
|
84
|
+
// ===========================
|
|
85
|
+
// Audio Activity
|
|
86
|
+
// ===========================
|
|
87
|
+
|
|
88
|
+
export {
|
|
89
|
+
kind as audioKind,
|
|
90
|
+
generateAudio,
|
|
91
|
+
type AudioActivityOptions,
|
|
92
|
+
type AudioActivityResult,
|
|
93
|
+
type AudioProviderOptions,
|
|
94
|
+
} from './generateAudio/index'
|
|
95
|
+
|
|
96
|
+
export {
|
|
97
|
+
BaseAudioAdapter,
|
|
98
|
+
type AudioAdapter,
|
|
99
|
+
type AudioAdapterConfig,
|
|
100
|
+
type AnyAudioAdapter,
|
|
101
|
+
} from './generateAudio/adapter'
|
|
102
|
+
|
|
83
103
|
// ===========================
|
|
84
104
|
// Video Activity (Experimental)
|
|
85
105
|
// ===========================
|
|
@@ -150,6 +170,7 @@ export type AIAdapter =
|
|
|
150
170
|
| AnyTextAdapter
|
|
151
171
|
| AnySummarizeAdapter
|
|
152
172
|
| AnyImageAdapter
|
|
173
|
+
| AnyAudioAdapter
|
|
153
174
|
| AnyVideoAdapter
|
|
154
175
|
| AnyTTSAdapter
|
|
155
176
|
| AnyTranscriptionAdapter
|
|
@@ -159,6 +180,7 @@ export type AdapterKind =
|
|
|
159
180
|
| 'text'
|
|
160
181
|
| 'summarize'
|
|
161
182
|
| 'image'
|
|
183
|
+
| 'audio'
|
|
162
184
|
| 'video'
|
|
163
185
|
| 'tts'
|
|
164
186
|
| 'transcription'
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { EventType } from '@ag-ui/core'
|
|
8
|
+
import { toRunErrorPayload } from './error-payload'
|
|
8
9
|
import type { StreamChunk } from '../types'
|
|
9
10
|
|
|
10
11
|
function createId(prefix: string): string {
|
|
@@ -52,18 +53,16 @@ export async function* streamGenerationResult<TResult>(
|
|
|
52
53
|
finishReason: 'stop',
|
|
53
54
|
timestamp: Date.now(),
|
|
54
55
|
} as StreamChunk
|
|
55
|
-
} catch (error:
|
|
56
|
+
} catch (error: unknown) {
|
|
57
|
+
const payload = toRunErrorPayload(error, 'Generation failed')
|
|
56
58
|
yield {
|
|
57
59
|
type: EventType.RUN_ERROR,
|
|
58
60
|
runId,
|
|
59
61
|
threadId,
|
|
60
|
-
message:
|
|
61
|
-
code:
|
|
62
|
+
message: payload.message,
|
|
63
|
+
code: payload.code,
|
|
62
64
|
// Deprecated nested form for backward compatibility
|
|
63
|
-
error:
|
|
64
|
-
message: error.message || 'Generation failed',
|
|
65
|
-
code: error.code,
|
|
66
|
-
},
|
|
65
|
+
error: payload,
|
|
67
66
|
timestamp: Date.now(),
|
|
68
67
|
} as StreamChunk
|
|
69
68
|
}
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
import { aiEventClient } from '@tanstack/ai-event-client'
|
|
9
9
|
import { streamGenerationResult } from '../stream-generation-result.js'
|
|
10
|
+
import { resolveDebugOption } from '../../logger/resolve'
|
|
11
|
+
import type { InternalLogger } from '../../logger/internal-logger'
|
|
12
|
+
import type { DebugOption } from '../../logger/types'
|
|
10
13
|
import type { SummarizeAdapter } from './adapter'
|
|
11
14
|
import type {
|
|
12
15
|
StreamChunk,
|
|
@@ -66,6 +69,12 @@ export interface SummarizeActivityOptions<
|
|
|
66
69
|
* @default false
|
|
67
70
|
*/
|
|
68
71
|
stream?: TStream
|
|
72
|
+
/**
|
|
73
|
+
* Enable debug logging. Pass `true` to enable all categories, `false` to
|
|
74
|
+
* silence everything including errors, or a `DebugConfig` object for granular
|
|
75
|
+
* control and/or a custom `Logger`.
|
|
76
|
+
*/
|
|
77
|
+
debug?: DebugOption
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
// ===========================
|
|
@@ -180,6 +189,7 @@ async function runSummarize(
|
|
|
180
189
|
const requestId = createId('summarize')
|
|
181
190
|
const inputLength = text.length
|
|
182
191
|
const startTime = Date.now()
|
|
192
|
+
const logger: InternalLogger = resolveDebugOption(options.debug)
|
|
183
193
|
|
|
184
194
|
aiEventClient.emit('summarize:request:started', {
|
|
185
195
|
requestId,
|
|
@@ -189,30 +199,50 @@ async function runSummarize(
|
|
|
189
199
|
timestamp: startTime,
|
|
190
200
|
})
|
|
191
201
|
|
|
202
|
+
logger.request(`activity=summarize provider=${adapter.name}`, {
|
|
203
|
+
provider: adapter.name,
|
|
204
|
+
model,
|
|
205
|
+
inputLength,
|
|
206
|
+
})
|
|
207
|
+
|
|
192
208
|
const summarizeOptions: SummarizationOptions = {
|
|
193
209
|
model,
|
|
194
210
|
text,
|
|
195
211
|
maxLength,
|
|
196
212
|
style,
|
|
197
213
|
focus,
|
|
214
|
+
logger,
|
|
198
215
|
}
|
|
199
216
|
|
|
200
|
-
|
|
217
|
+
try {
|
|
218
|
+
const result = await adapter.summarize(summarizeOptions)
|
|
201
219
|
|
|
202
|
-
|
|
203
|
-
|
|
220
|
+
const duration = Date.now() - startTime
|
|
221
|
+
const outputLength = result.summary.length
|
|
204
222
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
223
|
+
aiEventClient.emit('summarize:request:completed', {
|
|
224
|
+
requestId,
|
|
225
|
+
provider: adapter.name,
|
|
226
|
+
model,
|
|
227
|
+
inputLength,
|
|
228
|
+
outputLength,
|
|
229
|
+
duration,
|
|
230
|
+
timestamp: Date.now(),
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
logger.output(`activity=summarize length=${outputLength}`, {
|
|
234
|
+
hasSummary: !!result.summary,
|
|
235
|
+
outputLength,
|
|
236
|
+
})
|
|
214
237
|
|
|
215
|
-
|
|
238
|
+
return result
|
|
239
|
+
} catch (error) {
|
|
240
|
+
logger.errors('summarize activity failed', {
|
|
241
|
+
error,
|
|
242
|
+
source: 'summarize',
|
|
243
|
+
})
|
|
244
|
+
throw error
|
|
245
|
+
}
|
|
216
246
|
}
|
|
217
247
|
|
|
218
248
|
/**
|
|
@@ -225,6 +255,13 @@ async function* runStreamingSummarize(
|
|
|
225
255
|
): AsyncIterable<StreamChunk> {
|
|
226
256
|
const { adapter, text, maxLength, style, focus } = options
|
|
227
257
|
const model = adapter.model
|
|
258
|
+
const logger: InternalLogger = resolveDebugOption(options.debug)
|
|
259
|
+
|
|
260
|
+
logger.request(`activity=summarize provider=${adapter.name}`, {
|
|
261
|
+
provider: adapter.name,
|
|
262
|
+
model,
|
|
263
|
+
stream: true,
|
|
264
|
+
})
|
|
228
265
|
|
|
229
266
|
const summarizeOptions: SummarizationOptions = {
|
|
230
267
|
model,
|
|
@@ -232,16 +269,25 @@ async function* runStreamingSummarize(
|
|
|
232
269
|
maxLength,
|
|
233
270
|
style,
|
|
234
271
|
focus,
|
|
272
|
+
logger,
|
|
235
273
|
}
|
|
236
274
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
275
|
+
try {
|
|
276
|
+
// Use real streaming if the adapter supports it
|
|
277
|
+
if (adapter.summarizeStream) {
|
|
278
|
+
yield* adapter.summarizeStream(summarizeOptions)
|
|
279
|
+
return
|
|
280
|
+
}
|
|
242
281
|
|
|
243
|
-
|
|
244
|
-
|
|
282
|
+
// Fall back to non-streaming — wrap result with streamGenerationResult
|
|
283
|
+
yield* streamGenerationResult(() => adapter.summarize(summarizeOptions))
|
|
284
|
+
} catch (error) {
|
|
285
|
+
logger.errors('summarize activity failed', {
|
|
286
|
+
error,
|
|
287
|
+
source: 'summarize',
|
|
288
|
+
})
|
|
289
|
+
throw error
|
|
290
|
+
}
|
|
245
291
|
}
|
|
246
292
|
|
|
247
293
|
// ===========================
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// NOTE: This module is exposed ONLY via the `@tanstack/ai/adapter-internals`
|
|
2
|
+
// subpath export. It gives provider adapter packages access to the internal
|
|
3
|
+
// logger plumbing without leaking those symbols to end users.
|
|
4
|
+
|
|
5
|
+
export type { ResolvedCategories } from './logger/internal-logger'
|
|
6
|
+
export { InternalLogger } from './logger/internal-logger'
|
|
7
|
+
export { resolveDebugOption } from './logger/resolve'
|
|
8
|
+
export { toRunErrorPayload } from './activities/error-payload'
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export {
|
|
|
3
3
|
chat,
|
|
4
4
|
summarize,
|
|
5
5
|
generateImage,
|
|
6
|
+
generateAudio,
|
|
6
7
|
generateVideo,
|
|
7
8
|
getVideoJobStatus,
|
|
8
9
|
generateSpeech,
|
|
@@ -13,6 +14,7 @@ export {
|
|
|
13
14
|
export { createChatOptions } from './activities/chat/index'
|
|
14
15
|
export { createSummarizeOptions } from './activities/summarize/index'
|
|
15
16
|
export { createImageOptions } from './activities/generateImage/index'
|
|
17
|
+
export { createAudioOptions } from './activities/generateAudio/index'
|
|
16
18
|
export { createVideoOptions } from './activities/generateVideo/index'
|
|
17
19
|
export { createSpeechOptions } from './activities/generateSpeech/index'
|
|
18
20
|
export { createTranscriptionOptions } from './activities/generateTranscription/index'
|
|
@@ -26,6 +28,8 @@ export type {
|
|
|
26
28
|
AnyTextAdapter,
|
|
27
29
|
AnySummarizeAdapter,
|
|
28
30
|
SummarizeAdapter,
|
|
31
|
+
AnyAudioAdapter,
|
|
32
|
+
AudioAdapter,
|
|
29
33
|
AnyTTSAdapter,
|
|
30
34
|
TTSAdapter,
|
|
31
35
|
AnyTranscriptionAdapter,
|
|
@@ -167,3 +171,12 @@ export type {
|
|
|
167
171
|
// Adapter extension utilities
|
|
168
172
|
export { createModel, extendAdapter } from './extend-adapter'
|
|
169
173
|
export type { ExtendedModelDef } from './extend-adapter'
|
|
174
|
+
|
|
175
|
+
// Logger
|
|
176
|
+
export type {
|
|
177
|
+
Logger,
|
|
178
|
+
DebugCategories,
|
|
179
|
+
DebugConfig,
|
|
180
|
+
DebugOption,
|
|
181
|
+
} from './logger/types'
|
|
182
|
+
export { ConsoleLogger } from './logger/console-logger'
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Logger } from './types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default `Logger` implementation that routes each level to the matching
|
|
5
|
+
* `console` method:
|
|
6
|
+
*
|
|
7
|
+
* - `debug` → `console.debug`
|
|
8
|
+
* - `info` → `console.info`
|
|
9
|
+
* - `warn` → `console.warn`
|
|
10
|
+
* - `error` → `console.error`
|
|
11
|
+
*
|
|
12
|
+
* When a `meta` object is supplied, the message is logged first and the meta
|
|
13
|
+
* object is then printed via `console.dir(meta, { depth: null, colors: true })`
|
|
14
|
+
* so deeply nested structures (e.g. provider chunk payloads with `usage`,
|
|
15
|
+
* `output`, `reasoning`, `tools`) render in full instead of truncating to
|
|
16
|
+
* `[Object]` / `[Array]`. On Node this produces a depth-unlimited inspect
|
|
17
|
+
* dump; browsers present the object as an interactive tree (extra options
|
|
18
|
+
* are ignored).
|
|
19
|
+
*
|
|
20
|
+
* This is the logger used when `debug` is enabled on any activity and no
|
|
21
|
+
* custom `logger` is supplied via `debug: { logger }`.
|
|
22
|
+
*/
|
|
23
|
+
const DIR_OPTIONS = { depth: null, colors: true } as const
|
|
24
|
+
|
|
25
|
+
export class ConsoleLogger implements Logger {
|
|
26
|
+
/** Log a debug-level message; forwards to `console.debug`. */
|
|
27
|
+
debug(message: string, meta?: Record<string, unknown>): void {
|
|
28
|
+
console.debug(message)
|
|
29
|
+
if (meta !== undefined) console.dir(meta, DIR_OPTIONS)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Log an info-level message; forwards to `console.info`. */
|
|
33
|
+
info(message: string, meta?: Record<string, unknown>): void {
|
|
34
|
+
console.info(message)
|
|
35
|
+
if (meta !== undefined) console.dir(meta, DIR_OPTIONS)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Log a warning-level message; forwards to `console.warn`. */
|
|
39
|
+
warn(message: string, meta?: Record<string, unknown>): void {
|
|
40
|
+
console.warn(message)
|
|
41
|
+
if (meta !== undefined) console.dir(meta, DIR_OPTIONS)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Log an error-level message; forwards to `console.error`. */
|
|
45
|
+
error(message: string, meta?: Record<string, unknown>): void {
|
|
46
|
+
console.error(message)
|
|
47
|
+
if (meta !== undefined) console.dir(meta, DIR_OPTIONS)
|
|
48
|
+
}
|
|
49
|
+
}
|