UNPKG

@tanstack/ai

Version:

Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.

162 lines (161 loc) 5.26 kB
import { resolveDebugOption } from "../../logger/resolve.js"; import { streamGenerationResult } from "../stream-generation-result.js"; import { applyGenerationResultTransforms, createGenerationContext, runGenerationAbort, runGenerationError, runGenerationFinish, runGenerationStart, runGenerationUsage } from "../middleware/run.js"; import { abortReasonMessage, createActivityAbortControls, isActivityAbortError, raceWithAbort } from "../../utilities/activity-abort.js"; import "./adapter.js"; import { aiEventClient } from "@tanstack/ai-event-client"; //#region src/activities/generateWorld/index.ts /** * World Activity (Experimental) * * Mints a session token for a live, prompt-steerable world. Unlike * generateVideo (a job that finishes with a URL), the browser then connects * with the token, sets the prompt, and streams until pause/reset/close. * * @experimental World generation is an experimental feature and may change. */ /** The adapter kind this activity handles */ var kind = "world"; function createId(prefix) { return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`; } /** * World generation activity - opens a live, prompt-steerable world session. * * @example Mint a session token on the server * ```ts * import { generateWorld } from '@tanstack/ai' * import { reactorWorld } from '@tanstack/ai-reactor' * * const world = await generateWorld({ * adapter: reactorWorld('visko-orbis-stable'), * prompt: 'A neon cyberpunk city at night, slow aerial drift', * }) * * // Hand world.token, world.model, and world.prompt to the browser. * ``` * * @experimental World generation is an experimental feature and may change. */ function generateWorld(options) { if (options.stream) return streamGenerationResult((resolved) => runGenerateWorld({ ...options, runId: resolved.runId }), options); return runGenerateWorld(options); } /** * Run the core world generation logic (non-streaming). */ async function runGenerateWorld(options) { const { adapter, stream: _stream, debug: _debug, middleware, threadId, runId, timeout, abortSignal: callerAbortSignal, ...rest } = options; const model = adapter.model; const requestId = createId("world"); const startTime = Date.now(); const logger = resolveDebugOption(options.debug); const abortControls = createActivityAbortControls({ timeout, abortSignal: callerAbortSignal }); const providerName = adapter.provider ?? adapter.name ?? "unknown"; const mwCtx = createGenerationContext({ requestId, activity: "world", provider: adapter.name, model, modelOptions: rest.modelOptions, threadId, runId, artifactInputs: { prompt: rest.prompt }, createId }); await runGenerationStart(middleware, mwCtx); aiEventClient.emit("world:request:started", { requestId, provider: adapter.name, model, prompt: rest.prompt, timestamp: startTime, ...rest.modelOptions !== void 0 && { modelOptions: rest.modelOptions } }); logger.request(`activity=generateWorld provider=${providerName}`, { provider: providerName, model }); try { const rawResult = await raceWithAbort(adapter.createWorld({ ...rest, model, logger, ...abortControls.signal ? { abortSignal: abortControls.signal } : {} }), abortControls.signal); abortControls.clear(); const result = await applyGenerationResultTransforms(mwCtx, rawResult); const elapsedMs = Date.now() - startTime; aiEventClient.emit("world:request:completed", { requestId, provider: adapter.name, model: result.model, prompt: result.prompt, status: result.status, duration: elapsedMs, timestamp: Date.now(), ...rest.modelOptions !== void 0 && { modelOptions: rest.modelOptions } }); if (result.usage) aiEventClient.emit("world:usage", { requestId, model: result.model, usage: result.usage, timestamp: Date.now(), ...rest.modelOptions !== void 0 && { modelOptions: rest.modelOptions } }); logger.output(`activity=generateWorld provider=${providerName}`, { model: result.model, status: result.status }); if (result.usage) await runGenerationUsage(middleware, mwCtx, result.usage); await runGenerationFinish(middleware, mwCtx, { duration: elapsedMs, usage: result.usage }); return result; } catch (error) { abortControls.clear(); const elapsedMs = Date.now() - startTime; const err = error; aiEventClient.emit("world:request:error", { requestId, provider: adapter.name, model, error: { message: err.message, name: err.name }, duration: elapsedMs, timestamp: Date.now(), ...rest.modelOptions !== void 0 && { modelOptions: rest.modelOptions } }); if (isActivityAbortError(error, abortControls.signal)) await runGenerationAbort(middleware, mwCtx, { reason: abortReasonMessage(error, abortControls.signal), duration: elapsedMs }); else await runGenerationError(middleware, mwCtx, { error, duration: elapsedMs }); logger.errors("generateWorld activity failed", { error, source: "generateWorld" }); throw error; } } /** * Create typed options for the generateWorld() function without executing. */ function createWorldOptions(options) { return options; } //#endregion export { createWorldOptions, generateWorld, kind }; //# sourceMappingURL=index.js.map