ctx.ai(alias) returns an AI SDK provider bound to an authentication alias declared in helix.config.ts. Calling it (or .languageModel(id)) resolves a model; calling one of its methods with a string model id sends the request through the platform, which injects the provider’s credential.
Signature
ai(alias: string): HelixAIProvider
interface HelixAIProvider {
// Callable shorthand for languageModel().
(modelId: string): LanguageModel;
languageModel(modelId: string): LanguageModel;
embeddingModel(modelId: string): EmbeddingModel;
textEmbeddingModel(modelId: string): EmbeddingModel; // same models as embeddingModel
imageModel(modelId: string): ImageModel;
transcriptionModel(modelId: string): TranscriptionModel;
speechModel(modelId: string): SpeechModel;
generateText(options): Promise<GenerateTextResult & HelixResultMeta>;
streamText(options): StreamTextResult;
generateObject(options): Promise<GenerateObjectResult & HelixResultMeta>;
streamObject(options): StreamObjectResult;
embed(options): Promise<EmbedResult>;
embedMany(options): Promise<EmbedManyResult>;
generateImage(options): Promise<GenerateImageResult & HelixResultMeta>;
transcribe(options): Promise<TranscribeResult>;
generateSpeech(options): Promise<GenerateSpeechResult>;
}
Every method’s options and result types are the AI SDK’s own for that call (generateText’s options are the AI SDK’s generateText options, and so on), with model as a string id instead of a model instance.
| Method | Returns | Notes |
|---|---|---|
generateText(options) | Promise<GenerateTextResult & HelixResultMeta> | One completed turn |
streamText(options) | StreamTextResult | Token stream; call .toUIMessageStreamResponse() or read .textStream |
generateObject(options) | Promise<GenerateObjectResult & HelixResultMeta> | options.schema is a Zod schema; result.object is typed from it |
streamObject(options) | StreamObjectResult | Streaming counterpart to generateObject |
embed(options) | Promise<EmbedResult> | One vector for options.value |
embedMany(options) | Promise<EmbedManyResult> | One vector per entry in options.values |
generateImage(options) | Promise<GenerateImageResult & HelixResultMeta> | |
transcribe(options) | Promise<TranscribeResult> | options.audio is the audio to transcribe |
generateSpeech(options) | Promise<GenerateSpeechResult> |
HelixResultMeta
generateText, generateObject, and generateImage results carry a helix field alongside the AI SDK’s own fields:
interface HelixResultMeta {
helix: {
cost: { amount: number; currency: 'USD' };
requestId: string;
};
}
cost is estimated client-side from the provider’s reported token usage against public list prices; an unrecognized model, or an image model that bills per image rather than by token, estimates to 0.
Top-level ctx.ai.* functions
interface HelixAI {
(alias: string): HelixAIProvider;
generateText(options): Promise<GenerateTextResult & HelixResultMeta>;
streamText(options): StreamTextResult;
generateObject(options): Promise<GenerateObjectResult & HelixResultMeta>;
streamObject(options): StreamObjectResult;
embed(options): Promise<EmbedResult>;
embedMany(options): Promise<EmbedManyResult>;
generateImage(options): Promise<GenerateImageResult & HelixResultMeta>;
transcribe(options): Promise<TranscribeResult>;
generateSpeech(options): Promise<GenerateSpeechResult>;
}
Same method names as HelixAIProvider, but options.model must be a model instance obtained from ctx.ai(alias) (for example ctx.ai(alias).languageModel(id)), not a string. Use these when a model needs to be handed to code that expects an AI SDK model instance, such as a custom agent loop.
Config: aiProviders
ctx.ai(alias) resolves alias against helix.config.ts’s aiProviders map, which declares the AI SDK service backing each authentication alias:
aiProviders?: Record<string, AiService | { service: 'openai-compatible'; baseUrl: string }>
type AiService = 'openai' | 'anthropic' | 'google' | 'mistral' | 'cohere' | 'openai-compatible';
The shorthand string form works for the five first-party services; openai-compatible needs the object form with baseUrl, which must be https: (checked when the config loads). Full field documentation is in the configuration reference.
Errors
| Error | SdkError.kind | When it happens |
|---|---|---|
SdkError.aiProviderNotConfigured | ai_provider_not_configured | The alias has no matching aiProviders entry |
SdkError.aiUnsupportedService | ai_unsupported_service | The alias resolves to a service ctx.ai doesn’t support |
SdkError.aiModelIdRequired | ai_model_id_required | ctx.ai(alias).<method> was called without a string model |
SdkError.aiModelInstanceRequired | ai_model_instance_required | A top-level ctx.ai.* function was called with a string instead of a model instance |
SdkError.aiForeignModelRejected | ai_foreign_model_rejected | A top-level ctx.ai.* function was called with a model instance built outside ctx.ai(alias) |
Example
// functions/api/v1/summarize.post.ts
import { z } from 'zod';
import { defineFunction } from '@trayai/helix-sdk';
export const input = z.object({
text: z.string().min(1),
});
export default defineFunction<typeof input>(async (ctx) => {
const result = await ctx.ai('anthropicKey').generateText({
model: 'claude-sonnet-4-5',
prompt: `Summarize in two sentences: ${ctx.input.text}`,
});
ctx.log.info('Summarized', { cost: result.helix.cost.amount, requestId: result.helix.requestId });
return { summary: result.text };
});
Config shape, every method’s usage, structured output, and the AI SDK re-exports are covered in the AI guide.