Skip to content
Hoody.com

Add // @ai true to any script (not the pre and post middleware files, .ts or .js, where magic comments have no effect and the helpers are not available) and hoody-exec injects the Vercel AI SDK helpers into the script context: generateText, streamText, and generateObject. There is nothing to import, no SDK to set up, and no API key to manage. The helpers reach 300+ models through Hoody AI.

Because a script file is already an HTTP endpoint, any script can serve AI responses over HTTP.


Add the @ai magic comment to any script:

// @mode serverless
// @ai true
const { text } = await generateText({
model,
prompt: 'Explain quantum computing in one sentence'
});
return { answer: text };

The script now has:

  • model: a pre-configured AI model, from @ai-model or the default
  • openai: the Vercel AI SDK provider factory (createOpenAI), called as openai(modelId)
  • ai: the helper namespace, with ai.generate, ai.stream, and ai.object
  • generateText(): returns a complete text response
  • streamText(): streams a text response
  • generateObject(): returns a structured JSON object

Control AI behavior with these magic comments:

CommentValuesDefaultDescription
@aitrue | falsetrueEnable AI helpers
@ai-modelmodel nameServer default (hoody-ai/hoody-free)Which model to use
@ai-temperature0 - 2Provider defaultCreativity level (0 = deterministic, 2 = very creative)
@ai-max-tokenspositive integerProvider defaultMaximum response length. Other values are ignored
@ai-keystringgenerated default keyAPI key override (the server-wide default can be set with --ai-key)

The @ai-model value uses Hoody AI model identifiers in provider/model format:

// Hoody Free (default)
// @ai-model hoody-ai/hoody-free
// xAI Grok 4.5
// @ai-model x-ai/grok-4.5
// Moonshot Kimi K3
// @ai-model moonshotai/kimi-k3
// Meta Llama 4
// @ai-model meta-llama/llama-4-maverick
// DeepSeek V4
// @ai-model deepseek/deepseek-v4-pro

When @ai true is set, these are available in your script:

A Vercel AI SDK provider factory (createOpenAI), pre-connected to the Hoody AI gateway (default https://ai.hoody.com/api/v1) with a server-configured API key, so there is no endpoint or key to set up on your side. Call openai('<model-id>') to build a model instance for a model other than the default, then pass it to generateText, streamText, or generateObject. openai('<model-id>') and the injected model use the chat completions endpoint, which serves every model on the gateway, the free models included. openai.responses('<model-id>') builds a model on the Responses API instead, for a paid model that supports it.

// @ai true
// Build a model from the provider factory and call the AI SDK
const { text } = await generateText({
model: openai('deepseek/deepseek-v4-pro'),
prompt: 'Hello!'
});
return { reply: text };

A pre-configured Vercel AI SDK model instance from the @ai-sdk/openai package. Uses the model name from @ai-model, or the server default (hoody-ai/hoody-free unless the server sets --ai-default-model). Pass this to generateText, streamText, or generateObject.

// @ai true
// @ai-model deepseek/deepseek-v4-pro
// `model` is already configured with the above model
const { text } = await generateText({ model, prompt: 'Hello!' });

A namespace of three convenience methods over the Vercel AI SDK:

  • ai.generate(options) returns a complete text response and wraps generateText
  • ai.stream(options) streams text chunks as they are produced and wraps streamText
  • ai.object(options) returns structured JSON validated against a schema and wraps generateObject
// @ai true
const { text } = await ai.generate({ prompt: 'Hello!' });
const { textStream } = await ai.stream({ prompt: 'Write a poem' });
const { z } = require('zod');
const schema = z.object({ label: z.string() });
const { object } = await ai.object({ schema, prompt: 'Classify this' });

Generate a complete text response. Returns when the full response is ready.

Options: { prompt?, messages?, model, system?, temperature?, maxOutputTokens? } (model is required here: pass the injected model, or openai('<model-id>'))

// @ai true
// @ai-model deepseek/deepseek-v4-pro
const { text } = await generateText({
model,
prompt: 'Write a haiku about HTTP'
});
return { haiku: text };

Stream response chunks as they are generated. Use it for long responses or real-time UIs.

Options: { prompt?, messages?, model, system?, temperature?, maxOutputTokens? } (model is required here: pass the injected model, or openai('<model-id>'))

// @ai true
// @ai-model deepseek/deepseek-v4-pro
// @timeout 60000
const { textStream } = await streamText({
model,
prompt: req.body.question
});
// Stream back to client
res.writeHead(200, { 'Content-Type': 'text/plain' });
for await (const chunk of textStream) {
res.write(chunk);
}
res.end();

generateObject(options), structured JSON output

Section titled “generateObject(options), structured JSON output”

Generate structured JSON that matches a provided schema. A Zod schema validates the AI response automatically. A jsonSchema(...) schema, as in the example below, is only sent to the model: the result is not checked unless you pass an options object with a validate function as its second argument: jsonSchema(schema, { validate }).

Options: { prompt?, messages?, model, schema, system?, temperature?, maxOutputTokens? } (pass the injected model as above)

// @ai true
// @ai-model deepseek/deepseek-v4-pro
const { jsonSchema } = require('ai');
const { object } = await generateObject({
model,
schema: jsonSchema({
type: 'object',
properties: {
sentiment: { type: 'string', enum: ['positive', 'negative', 'neutral'] },
confidence: { type: 'number' },
keywords: { type: 'array', items: { type: 'string' } }
}
}),
prompt: `Analyze the sentiment of: "${req.body.text}"`
});
return object;
// → { sentiment: 'positive', confidence: 0.92, keywords: ['great', 'love'] }

When @ai true is set, these defaults apply:

SettingDefaultOverride
AI URLhttps://ai.hoody.com/api/v1Server-launch --ai-url flag
Modelhoody-ai/hoody-freeServer-launch --ai-default-model flag, or @ai-model magic comment per script
API KeyA generated default key (container- plus a short hash of the scripts folder path, so containers using the same path get the same key), unless the server sets --ai-keyServer-launch --ai-key flag, or @ai-key magic comment per script
TemperatureProvider default@ai-temperature magic comment (applies to ai.* only)
Max TokensProvider default@ai-max-tokens magic comment (applies to ai.* only)

Override the model, API key, temperature, and max tokens per script with the matching magic comment. The AI URL is set server-wide with --ai-url only.

For example:

// @ai true
// @ai-model meta-llama/llama-4-maverick
// @ai-key sk-custom-key-here
// @ai-temperature 0.3
// @ai-max-tokens 2048

@ai-key configures the injected openai provider, and @ai-model picks the injected model and the default model of the ai.* helpers. A model you name yourself, such as openai('<model-id>'), overrides @ai-model for that call. @ai-temperature and @ai-max-tokens are applied by the ai.* helpers alone: pass temperature and maxOutputTokens at the call site when you use generateText, streamText, or generateObject directly.


@timeout bounds how long the caller waits, not how long the AI provider runs. If the deadline passes before your script has sent anything, the client gets a 504; if the response has already started streaming, the timeout does not interrupt it. Either way a provider call that has started is left to finish, so a slow model still consumes its tokens and its concurrency slot. The deadline also counts loading the script and waiting for a @concurrent slot; a script that has not started by then never runs, unless pre.ts or pre.js had already sent headers, left the response open and returned nothing, in which case the main script still starts after the deadline. Requests from a proxy hook use the hook’s own deadline instead, which can cut off a stream already under way.

// @ai true
// Client gives up after 30 seconds
// @timeout 30000
const { text } = await generateText({
model,
prompt: req.body.question
});
return { answer: text };

The AI SDK retries a failed call twice on its own before the error reaches your script, for failures it classifies as retryable (a network error, a 5xx, a rate limit). Nothing in Hoody Exec turns that off. Count it when you wrap a call in your own retry loop: three script-level attempts around a call that already retries twice is nine requests to the provider, not three. Retries cover starting a call only: once a stream has started, an error is not retried, and textStream just ends, so a streamed reply can stop partway with no error. Read fullStream to see error events.

To change how often a call is retried, set maxRetries on a raw generateText, streamText or generateObject call instead of writing your own loop (the ai.* helpers ignore it). maxRetries: 1 allows at most two attempts, and a failure that is not retryable fails at once:

// @ai true
// @timeout 60000
const { text } = await generateText({
model,
prompt: req.body.question,
maxRetries: 1
});
return { answer: text };

To validate AI-related magic comments without executing a script, use the magic comments validation endpoint:

Terminal window
curl -s -X POST "https://PROJECT-CONTAINER-exec-1.SERVER.containers.hoody.com/api/v1/exec/validate/magic-comments" \
-H "Content-Type: application/json" \
-d '{
"code": "// @ai true\n// @ai-model meta-llama/llama-4-maverick\n// @ai-temperature 0.5\nreturn {};"
}'

Retrieve the full magic comments schema, including every @ai-* directive, with:

Terminal window
curl "https://PROJECT-CONTAINER-exec-1.SERVER.containers.hoody.com/api/v1/exec/magic-comments/schema"

api/summarize.ts
// @mode serverless
// @ai true
// @ai-model deepseek/deepseek-v4-pro
// @ai-temperature 0.3
// @cors reflective
// @timeout 30000
if (!req.body?.content) {
res.statusCode = 400;
return { error: 'Missing content field' };
}
// ai.generate applies @ai-temperature above (and @ai-max-tokens, if set);
// raw generateText({ model, ... }) uses @ai-model but not the temperature
const { text } = await ai.generate({
prompt: `Summarize the following text in 2-3 sentences:\n\n${req.body.content}`
});
return {
summary: text,
originalLength: req.body.content.length,
summaryLength: text.length
};
api/classify.ts
// @mode serverless
// @ai true
// @ai-model hoody-ai/hoody-free
// @ai-temperature 0
// @cors reflective
const { z } = require('zod');
// ai.object applies the @ai-temperature 0 above
const { object } = await ai.object({
schema: z.object({
category: z.enum(['bug', 'feature', 'question', 'docs', 'other']),
priority: z.enum(['low', 'medium', 'high', 'critical']),
summary: z.string()
}),
prompt: `Classify this support ticket:\n\n${req.body.ticket}`
});
return object;
api/chat.ts
// @mode serverless
// @ai true
// @ai-model deepseek/deepseek-v4-pro
// @ai-temperature 0.7
// @ai-max-tokens 2048
// @cors reflective
// @timeout 60000
const messages = req.body.messages || [];
// The system prompt goes in `system`, not in `messages`
const { textStream } = await ai.stream({
system: 'You are a helpful assistant. Be concise.',
messages
});
// Stream Server-Sent Events
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
for await (const chunk of textStream) {
res.write(`data: ${JSON.stringify({ text: chunk })}\n\n`);
}
res.write('data: [DONE]\n\n');
res.end();

A hoody-exec worker script can act as a MITM (Man-In-The-Middle) proxy for AI requests. Any client pointed at it sends every request through your script, which can intercept, analyze, modify, block, or enhance the interaction.

Deploy the MITM script once, then change one URL in your AI client:

Without MITM: https://ai.hoody.com/api/v1
With MITM: https://PROJECT_ID-CONTAINER_ID-exec-1.node-us.containers.hoody.com/api/v1

Patterns this enables:

  • Tool call tampering: redirect file writes, block dangerous commands
  • Human-in-the-loop: pause the AI for approval on high-stakes operations
  • Cost optimization: compress prompts, cache responses, route to cheaper models
  • Context injection: enhance prompts from your knowledge base automatically
  • Observability: log every prompt, response, and decision

Hoody AI Intercept & Control has the complete MITM guide with full examples.