Skip to content
Releases1270 releases

Changelog

Every release across the Lunora packages, newest first. Lunora is alpha: the API still moves, and this is where it is written down.

Sep 30, 2026

Dependency updates only, across 36 packages.

@lunora/aichore

1.0.0-alpha.104

diff

⚠ BREAKING CHANGES

  • ai: ctx.ai is no longer present on query and mutation contexts at runtime. Code reaching it through a cast from a query or mutation now gets undefined; move the inference into an action. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • docs(platform): state ai gateway routing in the capability matrix The ai rating now covers the <provider>/<model> and dynamic/<route> ids ctx.ai.model() routes through AI Gateway: native on Cloudflare over the same AI binding, and part of the existing unsupported rating on node and celld, which have no gateway (or env.AI binding) to route through. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • feat(cli): add ai gateway provisioning and doctor checks Add lunora ai gateway, which creates (or reuses) a Cloudflare AI Gateway over the REST API (POST/GET /accounts/{account_id}/ai-gateway/gateways) and writes LUNORA_AI_GATEWAY_ID + LUNORA_AI_GATEWAY_ACCOUNT_ID into the wrangler vars, preserving comments. The id defaults to the worker name (--id overrides); log collection is on by default (--no-logs turns it off); --dry-run makes no API call and edits nothing. Credentials come from CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (falling back to wrangler account_id). lunora doctor gains three codes: ai-binding-missing (warn), ai-gateway-token-unused (warn) and ai-gateway-default (info). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(studio): add ai usage panel New Observability page (tab aiUsage) showing what ctx.ai.model(...) calls cost: total spend, input/output tokens and call count, a per-minute cost sparkline, breakdowns by function path and by model, and the recent ai.generate / ai.stream calls linking through to their trace. Totals read the durable gen_ai.usage.{input_tokens,output_tokens,cost} counter series from getMetricHistory: bucket sum is the tokens/USD spent, bucket count the calls (one ctx.metrics.count per call). Calls = max(input count, output count) so a call reporting both is not counted twice. Cost stays split by lunora.usage.cost.source; estimated (or unlabelled) cost is always marked "Estimated" and never shown as provider-reported. With no history yet, totals fall back to the live trace ring and the page says they reset on hibernation. The pure fold lives in features/ai-usage/ai-usage.ts with unit tests in the node unit project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(ai): route provider slugs to a self-hosted proxy off cloudflare LUNORA_AI_PROXY_URL (+ LUNORA_AI_PROXY_TOKEN) points ctx.ai at any OpenAI-compatible proxy (LiteLLM, OpenRouter, your own). "<provider>/<model>" slugs go there unchanged instead of AI Gateway, and no AI binding is needed, so ctx.ai works on celld. @cf/... ids and ctx.ai.run still need the binding. celld's ai capability moves from unsupported to emulated, so codegen emits ctx.ai there again. lunora doctor skips the binding and default-gateway checks when the proxy var is set. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): settle stream spans on cancel and share usage accounting - Stream telemetry re-emits parts through a ReadableStream, so an ai.stream span closes on consumer cancel and fails on an upstream error; a TransformStream's flush never ran on either, leaving the span and its gen_ai.usage counters pending forever. - recordUsage/modelIdOf live in usage.ts and are shared with defineRag, whose embeds now also count into ctx.metrics (RagContext.metrics), so RAG spend reaches the durable history. The duplicate EmbedSpan/EmbedTracer types are gone in favour of AiSpan/AiTracer. - The binding path selects the gateway by LUNORA_AI_GATEWAY_ID alone; the account id is only needed for a bring-your-own provider's baseURL. - No per-call slug metadata on top of an explicit gateway's own, which could exceed AI Gateway's 5-key limit and get the whole object rejected. - createAi no longer throws without a binding, provider or proxy: it returns a facade whose calls throw one directed error (embeddings and ai.run included), so codegen always emits createAi and drops its aiStub. - node rates ai as emulated through LUNORA_AI_PROXY_URL, like celld. - Docs: unified-catalog providers are paid through Unified Billing on the run path; keys stored on the gateway apply only to gateway-path providers.
  • ai: createAi({}) returns a throwing facade instead of throwing at construction. Every ctx.ai app now bundles @ai-sdk/openai and @ai-sdk/anthropic. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(cli): align ai doctor checks with the runtime - ai-gateway-token-unused now fires whenever ctx.ai is used with LUNORA_AI_GATEWAY_TOKEN set: the Workers AI binding cannot send it, with or without a gateway id. - The checks read top-level vars, env.<name>.vars and .dev.vars, so a proxy or gateway id set outside top-level vars no longer triggers a spurious finding. - Binding inference runs once in runDoctor and feeds both the export and AI checks. - WranglerConfig types the ai binding; the env var names live in one CLI module. - lunora ai gateway reuses @lunora/config's applyModify (now exported from @lunora/config/cloudflare) and returns one failure shape from its resolvers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(studio): count cost-only ai calls and fold usage per model - The history call count takes the largest series count per (function, model) pair and sums across pairs, so a call that reported only a cost is counted and two models' counts are never merged by max. - One slice-based flow serves both the history and live halves. - ai.embed spans (defineRag) show up in recent calls. - formatUsd/formatTokens move to reports/metrics-format and use the renderer's locale. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • docs(platform-node): match the ai row to the emulated rating Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): refuse a proxy token over plain http - LUNORA_AI_PROXY_TOKEN is never sent to a non-HTTPS LUNORA_AI_PROXY_URL off loopback; the proxy provider throws a directed error on use instead, as it does for an unparsable URL. - lunora ai gateway --dry-run warns when the account id a real run needs is missing. - doctor reads an unreadable .dev.vars as unset instead of aborting the run. - The node agents note no longer claims ai is unsupported there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): record stream usage that arrived before an upstream error A stream that emitted its finish part and then errored lost that usage: the span failed before recordUsage ran. The instrumented stream now settles once with its outcome and the error, so usage is recorded first and the error is then rethrown to fail the span. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Added

  • ai: AI Gateway model routing, per-function AI spend, and ctx.ai action-only (#910) (f0e8623)
@lunora/clichore

1.0.0-alpha.327

diff

⚠ BREAKING CHANGES

  • ai: ctx.ai is no longer present on query and mutation contexts at runtime. Code reaching it through a cast from a query or mutation now gets undefined; move the inference into an action. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • docs(platform): state ai gateway routing in the capability matrix The ai rating now covers the <provider>/<model> and dynamic/<route> ids ctx.ai.model() routes through AI Gateway: native on Cloudflare over the same AI binding, and part of the existing unsupported rating on node and celld, which have no gateway (or env.AI binding) to route through. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • feat(cli): add ai gateway provisioning and doctor checks Add lunora ai gateway, which creates (or reuses) a Cloudflare AI Gateway over the REST API (POST/GET /accounts/{account_id}/ai-gateway/gateways) and writes LUNORA_AI_GATEWAY_ID + LUNORA_AI_GATEWAY_ACCOUNT_ID into the wrangler vars, preserving comments. The id defaults to the worker name (--id overrides); log collection is on by default (--no-logs turns it off); --dry-run makes no API call and edits nothing. Credentials come from CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (falling back to wrangler account_id). lunora doctor gains three codes: ai-binding-missing (warn), ai-gateway-token-unused (warn) and ai-gateway-default (info). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(studio): add ai usage panel New Observability page (tab aiUsage) showing what ctx.ai.model(...) calls cost: total spend, input/output tokens and call count, a per-minute cost sparkline, breakdowns by function path and by model, and the recent ai.generate / ai.stream calls linking through to their trace. Totals read the durable gen_ai.usage.{input_tokens,output_tokens,cost} counter series from getMetricHistory: bucket sum is the tokens/USD spent, bucket count the calls (one ctx.metrics.count per call). Calls = max(input count, output count) so a call reporting both is not counted twice. Cost stays split by lunora.usage.cost.source; estimated (or unlabelled) cost is always marked "Estimated" and never shown as provider-reported. With no history yet, totals fall back to the live trace ring and the page says they reset on hibernation. The pure fold lives in features/ai-usage/ai-usage.ts with unit tests in the node unit project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(ai): route provider slugs to a self-hosted proxy off cloudflare LUNORA_AI_PROXY_URL (+ LUNORA_AI_PROXY_TOKEN) points ctx.ai at any OpenAI-compatible proxy (LiteLLM, OpenRouter, your own). "<provider>/<model>" slugs go there unchanged instead of AI Gateway, and no AI binding is needed, so ctx.ai works on celld. @cf/... ids and ctx.ai.run still need the binding. celld's ai capability moves from unsupported to emulated, so codegen emits ctx.ai there again. lunora doctor skips the binding and default-gateway checks when the proxy var is set. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): settle stream spans on cancel and share usage accounting - Stream telemetry re-emits parts through a ReadableStream, so an ai.stream span closes on consumer cancel and fails on an upstream error; a TransformStream's flush never ran on either, leaving the span and its gen_ai.usage counters pending forever. - recordUsage/modelIdOf live in usage.ts and are shared with defineRag, whose embeds now also count into ctx.metrics (RagContext.metrics), so RAG spend reaches the durable history. The duplicate EmbedSpan/EmbedTracer types are gone in favour of AiSpan/AiTracer. - The binding path selects the gateway by LUNORA_AI_GATEWAY_ID alone; the account id is only needed for a bring-your-own provider's baseURL. - No per-call slug metadata on top of an explicit gateway's own, which could exceed AI Gateway's 5-key limit and get the whole object rejected. - createAi no longer throws without a binding, provider or proxy: it returns a facade whose calls throw one directed error (embeddings and ai.run included), so codegen always emits createAi and drops its aiStub. - node rates ai as emulated through LUNORA_AI_PROXY_URL, like celld. - Docs: unified-catalog providers are paid through Unified Billing on the run path; keys stored on the gateway apply only to gateway-path providers.
  • ai: createAi({}) returns a throwing facade instead of throwing at construction. Every ctx.ai app now bundles @ai-sdk/openai and @ai-sdk/anthropic. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(cli): align ai doctor checks with the runtime - ai-gateway-token-unused now fires whenever ctx.ai is used with LUNORA_AI_GATEWAY_TOKEN set: the Workers AI binding cannot send it, with or without a gateway id. - The checks read top-level vars, env.<name>.vars and .dev.vars, so a proxy or gateway id set outside top-level vars no longer triggers a spurious finding. - Binding inference runs once in runDoctor and feeds both the export and AI checks. - WranglerConfig types the ai binding; the env var names live in one CLI module. - lunora ai gateway reuses @lunora/config's applyModify (now exported from @lunora/config/cloudflare) and returns one failure shape from its resolvers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(studio): count cost-only ai calls and fold usage per model - The history call count takes the largest series count per (function, model) pair and sums across pairs, so a call that reported only a cost is counted and two models' counts are never merged by max. - One slice-based flow serves both the history and live halves. - ai.embed spans (defineRag) show up in recent calls. - formatUsd/formatTokens move to reports/metrics-format and use the renderer's locale. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • docs(platform-node): match the ai row to the emulated rating Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): refuse a proxy token over plain http - LUNORA_AI_PROXY_TOKEN is never sent to a non-HTTPS LUNORA_AI_PROXY_URL off loopback; the proxy provider throws a directed error on use instead, as it does for an unparsable URL. - lunora ai gateway --dry-run warns when the account id a real run needs is missing. - doctor reads an unreadable .dev.vars as unset instead of aborting the run. - The node agents note no longer claims ai is unsupported there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): record stream usage that arrived before an upstream error A stream that emitted its finish part and then errored lost that usage: the span failed before recordUsage ran. The instrumented stream now settles once with its outcome and the error, so usage is recorded first and the error is then rethrown to fail the span. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Added

  • ai: AI Gateway model routing, per-function AI spend, and ctx.ai action-only (#910) (f0e8623)

Dependencies

  • @lunora/advisor: upgraded to 1.0.0-alpha.172
  • @lunora/bindings: upgraded to 1.0.0-alpha.85
  • @lunora/codegen: upgraded to 1.0.0-alpha.240
  • @lunora/config: upgraded to 1.0.0-alpha.285
  • @lunora/d1: upgraded to 1.0.0-alpha.152
  • @lunora/mcp: upgraded to 1.0.0-alpha.198
  • @lunora/runtime: upgraded to 1.0.0-alpha.164
  • @lunora/seed: upgraded to 1.0.0-alpha.170
  • @lunora/testing: upgraded to 1.0.0-alpha.211
@lunora/clifeature

1.0.0-alpha.326

diff

Added

  • Rsbuild templates (React SPA + TanStack Start) with Studio under @lunora/rspack (#909) (2d8b101)

Dependencies

  • @lunora/config: upgraded to 1.0.0-alpha.284
@lunora/codegenchore

1.0.0-alpha.240

diff

⚠ BREAKING CHANGES

  • ai: ctx.ai is no longer present on query and mutation contexts at runtime. Code reaching it through a cast from a query or mutation now gets undefined; move the inference into an action. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • docs(platform): state ai gateway routing in the capability matrix The ai rating now covers the <provider>/<model> and dynamic/<route> ids ctx.ai.model() routes through AI Gateway: native on Cloudflare over the same AI binding, and part of the existing unsupported rating on node and celld, which have no gateway (or env.AI binding) to route through. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • feat(cli): add ai gateway provisioning and doctor checks Add lunora ai gateway, which creates (or reuses) a Cloudflare AI Gateway over the REST API (POST/GET /accounts/{account_id}/ai-gateway/gateways) and writes LUNORA_AI_GATEWAY_ID + LUNORA_AI_GATEWAY_ACCOUNT_ID into the wrangler vars, preserving comments. The id defaults to the worker name (--id overrides); log collection is on by default (--no-logs turns it off); --dry-run makes no API call and edits nothing. Credentials come from CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (falling back to wrangler account_id). lunora doctor gains three codes: ai-binding-missing (warn), ai-gateway-token-unused (warn) and ai-gateway-default (info). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(studio): add ai usage panel New Observability page (tab aiUsage) showing what ctx.ai.model(...) calls cost: total spend, input/output tokens and call count, a per-minute cost sparkline, breakdowns by function path and by model, and the recent ai.generate / ai.stream calls linking through to their trace. Totals read the durable gen_ai.usage.{input_tokens,output_tokens,cost} counter series from getMetricHistory: bucket sum is the tokens/USD spent, bucket count the calls (one ctx.metrics.count per call). Calls = max(input count, output count) so a call reporting both is not counted twice. Cost stays split by lunora.usage.cost.source; estimated (or unlabelled) cost is always marked "Estimated" and never shown as provider-reported. With no history yet, totals fall back to the live trace ring and the page says they reset on hibernation. The pure fold lives in features/ai-usage/ai-usage.ts with unit tests in the node unit project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(ai): route provider slugs to a self-hosted proxy off cloudflare LUNORA_AI_PROXY_URL (+ LUNORA_AI_PROXY_TOKEN) points ctx.ai at any OpenAI-compatible proxy (LiteLLM, OpenRouter, your own). "<provider>/<model>" slugs go there unchanged instead of AI Gateway, and no AI binding is needed, so ctx.ai works on celld. @cf/... ids and ctx.ai.run still need the binding. celld's ai capability moves from unsupported to emulated, so codegen emits ctx.ai there again. lunora doctor skips the binding and default-gateway checks when the proxy var is set. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): settle stream spans on cancel and share usage accounting - Stream telemetry re-emits parts through a ReadableStream, so an ai.stream span closes on consumer cancel and fails on an upstream error; a TransformStream's flush never ran on either, leaving the span and its gen_ai.usage counters pending forever. - recordUsage/modelIdOf live in usage.ts and are shared with defineRag, whose embeds now also count into ctx.metrics (RagContext.metrics), so RAG spend reaches the durable history. The duplicate EmbedSpan/EmbedTracer types are gone in favour of AiSpan/AiTracer. - The binding path selects the gateway by LUNORA_AI_GATEWAY_ID alone; the account id is only needed for a bring-your-own provider's baseURL. - No per-call slug metadata on top of an explicit gateway's own, which could exceed AI Gateway's 5-key limit and get the whole object rejected. - createAi no longer throws without a binding, provider or proxy: it returns a facade whose calls throw one directed error (embeddings and ai.run included), so codegen always emits createAi and drops its aiStub. - node rates ai as emulated through LUNORA_AI_PROXY_URL, like celld. - Docs: unified-catalog providers are paid through Unified Billing on the run path; keys stored on the gateway apply only to gateway-path providers.
  • ai: createAi({}) returns a throwing facade instead of throwing at construction. Every ctx.ai app now bundles @ai-sdk/openai and @ai-sdk/anthropic. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(cli): align ai doctor checks with the runtime - ai-gateway-token-unused now fires whenever ctx.ai is used with LUNORA_AI_GATEWAY_TOKEN set: the Workers AI binding cannot send it, with or without a gateway id. - The checks read top-level vars, env.<name>.vars and .dev.vars, so a proxy or gateway id set outside top-level vars no longer triggers a spurious finding. - Binding inference runs once in runDoctor and feeds both the export and AI checks. - WranglerConfig types the ai binding; the env var names live in one CLI module. - lunora ai gateway reuses @lunora/config's applyModify (now exported from @lunora/config/cloudflare) and returns one failure shape from its resolvers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(studio): count cost-only ai calls and fold usage per model - The history call count takes the largest series count per (function, model) pair and sums across pairs, so a call that reported only a cost is counted and two models' counts are never merged by max. - One slice-based flow serves both the history and live halves. - ai.embed spans (defineRag) show up in recent calls. - formatUsd/formatTokens move to reports/metrics-format and use the renderer's locale. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • docs(platform-node): match the ai row to the emulated rating Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): refuse a proxy token over plain http - LUNORA_AI_PROXY_TOKEN is never sent to a non-HTTPS LUNORA_AI_PROXY_URL off loopback; the proxy provider throws a directed error on use instead, as it does for an unparsable URL. - lunora ai gateway --dry-run warns when the account id a real run needs is missing. - doctor reads an unreadable .dev.vars as unset instead of aborting the run. - The node agents note no longer claims ai is unsupported there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): record stream usage that arrived before an upstream error A stream that emitted its finish part and then errored lost that usage: the span failed before recordUsage ran. The instrumented stream now settles once with its outcome and the error, so usage is recorded first and the error is then rethrown to fail the span. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Added

  • ai: AI Gateway model routing, per-function AI spend, and ctx.ai action-only (#910) (f0e8623)

Dependencies

  • @lunora/advisor: upgraded to 1.0.0-alpha.172
  • @lunora/agent: upgraded to 1.0.0-alpha.154
  • @lunora/platform: upgraded to 1.0.0-alpha.44
  • @lunora/queue: upgraded to 1.0.0-alpha.79
  • @lunora/scheduler: upgraded to 1.0.0-alpha.98
  • @lunora/do: upgraded to 1.0.0-alpha.182
  • @lunora/server: upgraded to 1.0.0-alpha.161
  • @lunora/shard-engine: upgraded to 1.0.0-alpha.100
@lunora/configchore

1.0.0-alpha.285

diff

⚠ BREAKING CHANGES

  • ai: ctx.ai is no longer present on query and mutation contexts at runtime. Code reaching it through a cast from a query or mutation now gets undefined; move the inference into an action. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • docs(platform): state ai gateway routing in the capability matrix The ai rating now covers the <provider>/<model> and dynamic/<route> ids ctx.ai.model() routes through AI Gateway: native on Cloudflare over the same AI binding, and part of the existing unsupported rating on node and celld, which have no gateway (or env.AI binding) to route through. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • feat(cli): add ai gateway provisioning and doctor checks Add lunora ai gateway, which creates (or reuses) a Cloudflare AI Gateway over the REST API (POST/GET /accounts/{account_id}/ai-gateway/gateways) and writes LUNORA_AI_GATEWAY_ID + LUNORA_AI_GATEWAY_ACCOUNT_ID into the wrangler vars, preserving comments. The id defaults to the worker name (--id overrides); log collection is on by default (--no-logs turns it off); --dry-run makes no API call and edits nothing. Credentials come from CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (falling back to wrangler account_id). lunora doctor gains three codes: ai-binding-missing (warn), ai-gateway-token-unused (warn) and ai-gateway-default (info). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(studio): add ai usage panel New Observability page (tab aiUsage) showing what ctx.ai.model(...) calls cost: total spend, input/output tokens and call count, a per-minute cost sparkline, breakdowns by function path and by model, and the recent ai.generate / ai.stream calls linking through to their trace. Totals read the durable gen_ai.usage.{input_tokens,output_tokens,cost} counter series from getMetricHistory: bucket sum is the tokens/USD spent, bucket count the calls (one ctx.metrics.count per call). Calls = max(input count, output count) so a call reporting both is not counted twice. Cost stays split by lunora.usage.cost.source; estimated (or unlabelled) cost is always marked "Estimated" and never shown as provider-reported. With no history yet, totals fall back to the live trace ring and the page says they reset on hibernation. The pure fold lives in features/ai-usage/ai-usage.ts with unit tests in the node unit project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(ai): route provider slugs to a self-hosted proxy off cloudflare LUNORA_AI_PROXY_URL (+ LUNORA_AI_PROXY_TOKEN) points ctx.ai at any OpenAI-compatible proxy (LiteLLM, OpenRouter, your own). "<provider>/<model>" slugs go there unchanged instead of AI Gateway, and no AI binding is needed, so ctx.ai works on celld. @cf/... ids and ctx.ai.run still need the binding. celld's ai capability moves from unsupported to emulated, so codegen emits ctx.ai there again. lunora doctor skips the binding and default-gateway checks when the proxy var is set. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): settle stream spans on cancel and share usage accounting - Stream telemetry re-emits parts through a ReadableStream, so an ai.stream span closes on consumer cancel and fails on an upstream error; a TransformStream's flush never ran on either, leaving the span and its gen_ai.usage counters pending forever. - recordUsage/modelIdOf live in usage.ts and are shared with defineRag, whose embeds now also count into ctx.metrics (RagContext.metrics), so RAG spend reaches the durable history. The duplicate EmbedSpan/EmbedTracer types are gone in favour of AiSpan/AiTracer. - The binding path selects the gateway by LUNORA_AI_GATEWAY_ID alone; the account id is only needed for a bring-your-own provider's baseURL. - No per-call slug metadata on top of an explicit gateway's own, which could exceed AI Gateway's 5-key limit and get the whole object rejected. - createAi no longer throws without a binding, provider or proxy: it returns a facade whose calls throw one directed error (embeddings and ai.run included), so codegen always emits createAi and drops its aiStub. - node rates ai as emulated through LUNORA_AI_PROXY_URL, like celld. - Docs: unified-catalog providers are paid through Unified Billing on the run path; keys stored on the gateway apply only to gateway-path providers.
  • ai: createAi({}) returns a throwing facade instead of throwing at construction. Every ctx.ai app now bundles @ai-sdk/openai and @ai-sdk/anthropic. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(cli): align ai doctor checks with the runtime - ai-gateway-token-unused now fires whenever ctx.ai is used with LUNORA_AI_GATEWAY_TOKEN set: the Workers AI binding cannot send it, with or without a gateway id. - The checks read top-level vars, env.<name>.vars and .dev.vars, so a proxy or gateway id set outside top-level vars no longer triggers a spurious finding. - Binding inference runs once in runDoctor and feeds both the export and AI checks. - WranglerConfig types the ai binding; the env var names live in one CLI module. - lunora ai gateway reuses @lunora/config's applyModify (now exported from @lunora/config/cloudflare) and returns one failure shape from its resolvers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(studio): count cost-only ai calls and fold usage per model - The history call count takes the largest series count per (function, model) pair and sums across pairs, so a call that reported only a cost is counted and two models' counts are never merged by max. - One slice-based flow serves both the history and live halves. - ai.embed spans (defineRag) show up in recent calls. - formatUsd/formatTokens move to reports/metrics-format and use the renderer's locale. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • docs(platform-node): match the ai row to the emulated rating Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): refuse a proxy token over plain http - LUNORA_AI_PROXY_TOKEN is never sent to a non-HTTPS LUNORA_AI_PROXY_URL off loopback; the proxy provider throws a directed error on use instead, as it does for an unparsable URL. - lunora ai gateway --dry-run warns when the account id a real run needs is missing. - doctor reads an unreadable .dev.vars as unset instead of aborting the run. - The node agents note no longer claims ai is unsupported there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): record stream usage that arrived before an upstream error A stream that emitted its finish part and then errored lost that usage: the span failed before recordUsage ran. The instrumented stream now settles once with its outcome and the error, so usage is recorded first and the error is then rethrown to fail the span. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Added

  • ai: AI Gateway model routing, per-function AI spend, and ctx.ai action-only (#910) (f0e8623)

Dependencies

  • @lunora/codegen: upgraded to 1.0.0-alpha.240
  • @lunora/seed: upgraded to 1.0.0-alpha.170
  • @lunora/studio: upgraded to 1.0.0-alpha.242
@lunora/configfeature

1.0.0-alpha.284

diff

Added

  • Rsbuild templates (React SPA + TanStack Start) with Studio under @lunora/rspack (#909) (2d8b101)
@lunora/platformchore

1.0.0-alpha.44

diff

⚠ BREAKING CHANGES

  • ai: ctx.ai is no longer present on query and mutation contexts at runtime. Code reaching it through a cast from a query or mutation now gets undefined; move the inference into an action. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • docs(platform): state ai gateway routing in the capability matrix The ai rating now covers the <provider>/<model> and dynamic/<route> ids ctx.ai.model() routes through AI Gateway: native on Cloudflare over the same AI binding, and part of the existing unsupported rating on node and celld, which have no gateway (or env.AI binding) to route through. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • feat(cli): add ai gateway provisioning and doctor checks Add lunora ai gateway, which creates (or reuses) a Cloudflare AI Gateway over the REST API (POST/GET /accounts/{account_id}/ai-gateway/gateways) and writes LUNORA_AI_GATEWAY_ID + LUNORA_AI_GATEWAY_ACCOUNT_ID into the wrangler vars, preserving comments. The id defaults to the worker name (--id overrides); log collection is on by default (--no-logs turns it off); --dry-run makes no API call and edits nothing. Credentials come from CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (falling back to wrangler account_id). lunora doctor gains three codes: ai-binding-missing (warn), ai-gateway-token-unused (warn) and ai-gateway-default (info). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(studio): add ai usage panel New Observability page (tab aiUsage) showing what ctx.ai.model(...) calls cost: total spend, input/output tokens and call count, a per-minute cost sparkline, breakdowns by function path and by model, and the recent ai.generate / ai.stream calls linking through to their trace. Totals read the durable gen_ai.usage.{input_tokens,output_tokens,cost} counter series from getMetricHistory: bucket sum is the tokens/USD spent, bucket count the calls (one ctx.metrics.count per call). Calls = max(input count, output count) so a call reporting both is not counted twice. Cost stays split by lunora.usage.cost.source; estimated (or unlabelled) cost is always marked "Estimated" and never shown as provider-reported. With no history yet, totals fall back to the live trace ring and the page says they reset on hibernation. The pure fold lives in features/ai-usage/ai-usage.ts with unit tests in the node unit project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(ai): route provider slugs to a self-hosted proxy off cloudflare LUNORA_AI_PROXY_URL (+ LUNORA_AI_PROXY_TOKEN) points ctx.ai at any OpenAI-compatible proxy (LiteLLM, OpenRouter, your own). "<provider>/<model>" slugs go there unchanged instead of AI Gateway, and no AI binding is needed, so ctx.ai works on celld. @cf/... ids and ctx.ai.run still need the binding. celld's ai capability moves from unsupported to emulated, so codegen emits ctx.ai there again. lunora doctor skips the binding and default-gateway checks when the proxy var is set. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): settle stream spans on cancel and share usage accounting - Stream telemetry re-emits parts through a ReadableStream, so an ai.stream span closes on consumer cancel and fails on an upstream error; a TransformStream's flush never ran on either, leaving the span and its gen_ai.usage counters pending forever. - recordUsage/modelIdOf live in usage.ts and are shared with defineRag, whose embeds now also count into ctx.metrics (RagContext.metrics), so RAG spend reaches the durable history. The duplicate EmbedSpan/EmbedTracer types are gone in favour of AiSpan/AiTracer. - The binding path selects the gateway by LUNORA_AI_GATEWAY_ID alone; the account id is only needed for a bring-your-own provider's baseURL. - No per-call slug metadata on top of an explicit gateway's own, which could exceed AI Gateway's 5-key limit and get the whole object rejected. - createAi no longer throws without a binding, provider or proxy: it returns a facade whose calls throw one directed error (embeddings and ai.run included), so codegen always emits createAi and drops its aiStub. - node rates ai as emulated through LUNORA_AI_PROXY_URL, like celld. - Docs: unified-catalog providers are paid through Unified Billing on the run path; keys stored on the gateway apply only to gateway-path providers.
  • ai: createAi({}) returns a throwing facade instead of throwing at construction. Every ctx.ai app now bundles @ai-sdk/openai and @ai-sdk/anthropic. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(cli): align ai doctor checks with the runtime - ai-gateway-token-unused now fires whenever ctx.ai is used with LUNORA_AI_GATEWAY_TOKEN set: the Workers AI binding cannot send it, with or without a gateway id. - The checks read top-level vars, env.<name>.vars and .dev.vars, so a proxy or gateway id set outside top-level vars no longer triggers a spurious finding. - Binding inference runs once in runDoctor and feeds both the export and AI checks. - WranglerConfig types the ai binding; the env var names live in one CLI module. - lunora ai gateway reuses @lunora/config's applyModify (now exported from @lunora/config/cloudflare) and returns one failure shape from its resolvers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(studio): count cost-only ai calls and fold usage per model - The history call count takes the largest series count per (function, model) pair and sums across pairs, so a call that reported only a cost is counted and two models' counts are never merged by max. - One slice-based flow serves both the history and live halves. - ai.embed spans (defineRag) show up in recent calls. - formatUsd/formatTokens move to reports/metrics-format and use the renderer's locale. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • docs(platform-node): match the ai row to the emulated rating Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): refuse a proxy token over plain http - LUNORA_AI_PROXY_TOKEN is never sent to a non-HTTPS LUNORA_AI_PROXY_URL off loopback; the proxy provider throws a directed error on use instead, as it does for an unparsable URL. - lunora ai gateway --dry-run warns when the account id a real run needs is missing. - doctor reads an unreadable .dev.vars as unset instead of aborting the run. - The node agents note no longer claims ai is unsupported there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): record stream usage that arrived before an upstream error A stream that emitted its finish part and then errored lost that usage: the span failed before recordUsage ran. The instrumented stream now settles once with its outcome and the error, so usage is recorded first and the error is then rethrown to fail the span. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Added

  • ai: AI Gateway model routing, per-function AI spend, and ctx.ai action-only (#910) (f0e8623)
@lunora/platform-nodechore

1.0.0-alpha.107

diff

⚠ BREAKING CHANGES

  • ai: ctx.ai is no longer present on query and mutation contexts at runtime. Code reaching it through a cast from a query or mutation now gets undefined; move the inference into an action. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • docs(platform): state ai gateway routing in the capability matrix The ai rating now covers the <provider>/<model> and dynamic/<route> ids ctx.ai.model() routes through AI Gateway: native on Cloudflare over the same AI binding, and part of the existing unsupported rating on node and celld, which have no gateway (or env.AI binding) to route through. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • feat(cli): add ai gateway provisioning and doctor checks Add lunora ai gateway, which creates (or reuses) a Cloudflare AI Gateway over the REST API (POST/GET /accounts/{account_id}/ai-gateway/gateways) and writes LUNORA_AI_GATEWAY_ID + LUNORA_AI_GATEWAY_ACCOUNT_ID into the wrangler vars, preserving comments. The id defaults to the worker name (--id overrides); log collection is on by default (--no-logs turns it off); --dry-run makes no API call and edits nothing. Credentials come from CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (falling back to wrangler account_id). lunora doctor gains three codes: ai-binding-missing (warn), ai-gateway-token-unused (warn) and ai-gateway-default (info). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(studio): add ai usage panel New Observability page (tab aiUsage) showing what ctx.ai.model(...) calls cost: total spend, input/output tokens and call count, a per-minute cost sparkline, breakdowns by function path and by model, and the recent ai.generate / ai.stream calls linking through to their trace. Totals read the durable gen_ai.usage.{input_tokens,output_tokens,cost} counter series from getMetricHistory: bucket sum is the tokens/USD spent, bucket count the calls (one ctx.metrics.count per call). Calls = max(input count, output count) so a call reporting both is not counted twice. Cost stays split by lunora.usage.cost.source; estimated (or unlabelled) cost is always marked "Estimated" and never shown as provider-reported. With no history yet, totals fall back to the live trace ring and the page says they reset on hibernation. The pure fold lives in features/ai-usage/ai-usage.ts with unit tests in the node unit project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(ai): route provider slugs to a self-hosted proxy off cloudflare LUNORA_AI_PROXY_URL (+ LUNORA_AI_PROXY_TOKEN) points ctx.ai at any OpenAI-compatible proxy (LiteLLM, OpenRouter, your own). "<provider>/<model>" slugs go there unchanged instead of AI Gateway, and no AI binding is needed, so ctx.ai works on celld. @cf/... ids and ctx.ai.run still need the binding. celld's ai capability moves from unsupported to emulated, so codegen emits ctx.ai there again. lunora doctor skips the binding and default-gateway checks when the proxy var is set. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): settle stream spans on cancel and share usage accounting - Stream telemetry re-emits parts through a ReadableStream, so an ai.stream span closes on consumer cancel and fails on an upstream error; a TransformStream's flush never ran on either, leaving the span and its gen_ai.usage counters pending forever. - recordUsage/modelIdOf live in usage.ts and are shared with defineRag, whose embeds now also count into ctx.metrics (RagContext.metrics), so RAG spend reaches the durable history. The duplicate EmbedSpan/EmbedTracer types are gone in favour of AiSpan/AiTracer. - The binding path selects the gateway by LUNORA_AI_GATEWAY_ID alone; the account id is only needed for a bring-your-own provider's baseURL. - No per-call slug metadata on top of an explicit gateway's own, which could exceed AI Gateway's 5-key limit and get the whole object rejected. - createAi no longer throws without a binding, provider or proxy: it returns a facade whose calls throw one directed error (embeddings and ai.run included), so codegen always emits createAi and drops its aiStub. - node rates ai as emulated through LUNORA_AI_PROXY_URL, like celld. - Docs: unified-catalog providers are paid through Unified Billing on the run path; keys stored on the gateway apply only to gateway-path providers.
  • ai: createAi({}) returns a throwing facade instead of throwing at construction. Every ctx.ai app now bundles @ai-sdk/openai and @ai-sdk/anthropic. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(cli): align ai doctor checks with the runtime - ai-gateway-token-unused now fires whenever ctx.ai is used with LUNORA_AI_GATEWAY_TOKEN set: the Workers AI binding cannot send it, with or without a gateway id. - The checks read top-level vars, env.<name>.vars and .dev.vars, so a proxy or gateway id set outside top-level vars no longer triggers a spurious finding. - Binding inference runs once in runDoctor and feeds both the export and AI checks. - WranglerConfig types the ai binding; the env var names live in one CLI module. - lunora ai gateway reuses @lunora/config's applyModify (now exported from @lunora/config/cloudflare) and returns one failure shape from its resolvers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(studio): count cost-only ai calls and fold usage per model - The history call count takes the largest series count per (function, model) pair and sums across pairs, so a call that reported only a cost is counted and two models' counts are never merged by max. - One slice-based flow serves both the history and live halves. - ai.embed spans (defineRag) show up in recent calls. - formatUsd/formatTokens move to reports/metrics-format and use the renderer's locale. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • docs(platform-node): match the ai row to the emulated rating Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): refuse a proxy token over plain http - LUNORA_AI_PROXY_TOKEN is never sent to a non-HTTPS LUNORA_AI_PROXY_URL off loopback; the proxy provider throws a directed error on use instead, as it does for an unparsable URL. - lunora ai gateway --dry-run warns when the account id a real run needs is missing. - doctor reads an unreadable .dev.vars as unset instead of aborting the run. - The node agents note no longer claims ai is unsupported there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): record stream usage that arrived before an upstream error A stream that emitted its finish part and then errored lost that usage: the span failed before recordUsage ran. The instrumented stream now settles once with its outcome and the error, so usage is recorded first and the error is then rethrown to fail the span. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Added

  • ai: AI Gateway model routing, per-function AI spend, and ctx.ai action-only (#910) (f0e8623)

Dependencies

  • @lunora/d1: upgraded to 1.0.0-alpha.152
  • @lunora/platform: upgraded to 1.0.0-alpha.44
  • @lunora/queue: upgraded to 1.0.0-alpha.79
  • @lunora/sql-store: upgraded to 1.0.0-alpha.153
  • @lunora/do: upgraded to 1.0.0-alpha.182
  • @lunora/platform-cloudflare: upgraded to 1.0.0-alpha.63
  • @lunora/runtime: upgraded to 1.0.0-alpha.164
  • @lunora/shard-engine: upgraded to 1.0.0-alpha.100
  • @lunora/storage: upgraded to 1.0.0-alpha.92
@lunora/rspackfeature

1.0.0-alpha.5

diff

Added

  • Rsbuild templates (React SPA + TanStack Start) with Studio under @lunora/rspack (#909) (2d8b101)

Dependencies

  • @lunora/config: upgraded to 1.0.0-alpha.284
@lunora/studiochore

1.0.0-alpha.242

diff

⚠ BREAKING CHANGES

  • ai: ctx.ai is no longer present on query and mutation contexts at runtime. Code reaching it through a cast from a query or mutation now gets undefined; move the inference into an action. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • docs(platform): state ai gateway routing in the capability matrix The ai rating now covers the <provider>/<model> and dynamic/<route> ids ctx.ai.model() routes through AI Gateway: native on Cloudflare over the same AI binding, and part of the existing unsupported rating on node and celld, which have no gateway (or env.AI binding) to route through. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • feat(cli): add ai gateway provisioning and doctor checks Add lunora ai gateway, which creates (or reuses) a Cloudflare AI Gateway over the REST API (POST/GET /accounts/{account_id}/ai-gateway/gateways) and writes LUNORA_AI_GATEWAY_ID + LUNORA_AI_GATEWAY_ACCOUNT_ID into the wrangler vars, preserving comments. The id defaults to the worker name (--id overrides); log collection is on by default (--no-logs turns it off); --dry-run makes no API call and edits nothing. Credentials come from CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (falling back to wrangler account_id). lunora doctor gains three codes: ai-binding-missing (warn), ai-gateway-token-unused (warn) and ai-gateway-default (info). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(studio): add ai usage panel New Observability page (tab aiUsage) showing what ctx.ai.model(...) calls cost: total spend, input/output tokens and call count, a per-minute cost sparkline, breakdowns by function path and by model, and the recent ai.generate / ai.stream calls linking through to their trace. Totals read the durable gen_ai.usage.{input_tokens,output_tokens,cost} counter series from getMetricHistory: bucket sum is the tokens/USD spent, bucket count the calls (one ctx.metrics.count per call). Calls = max(input count, output count) so a call reporting both is not counted twice. Cost stays split by lunora.usage.cost.source; estimated (or unlabelled) cost is always marked "Estimated" and never shown as provider-reported. With no history yet, totals fall back to the live trace ring and the page says they reset on hibernation. The pure fold lives in features/ai-usage/ai-usage.ts with unit tests in the node unit project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
  • feat(ai): route provider slugs to a self-hosted proxy off cloudflare LUNORA_AI_PROXY_URL (+ LUNORA_AI_PROXY_TOKEN) points ctx.ai at any OpenAI-compatible proxy (LiteLLM, OpenRouter, your own). "<provider>/<model>" slugs go there unchanged instead of AI Gateway, and no AI binding is needed, so ctx.ai works on celld. @cf/... ids and ctx.ai.run still need the binding. celld's ai capability moves from unsupported to emulated, so codegen emits ctx.ai there again. lunora doctor skips the binding and default-gateway checks when the proxy var is set. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): settle stream spans on cancel and share usage accounting - Stream telemetry re-emits parts through a ReadableStream, so an ai.stream span closes on consumer cancel and fails on an upstream error; a TransformStream's flush never ran on either, leaving the span and its gen_ai.usage counters pending forever. - recordUsage/modelIdOf live in usage.ts and are shared with defineRag, whose embeds now also count into ctx.metrics (RagContext.metrics), so RAG spend reaches the durable history. The duplicate EmbedSpan/EmbedTracer types are gone in favour of AiSpan/AiTracer. - The binding path selects the gateway by LUNORA_AI_GATEWAY_ID alone; the account id is only needed for a bring-your-own provider's baseURL. - No per-call slug metadata on top of an explicit gateway's own, which could exceed AI Gateway's 5-key limit and get the whole object rejected. - createAi no longer throws without a binding, provider or proxy: it returns a facade whose calls throw one directed error (embeddings and ai.run included), so codegen always emits createAi and drops its aiStub. - node rates ai as emulated through LUNORA_AI_PROXY_URL, like celld. - Docs: unified-catalog providers are paid through Unified Billing on the run path; keys stored on the gateway apply only to gateway-path providers.
  • ai: createAi({}) returns a throwing facade instead of throwing at construction. Every ctx.ai app now bundles @ai-sdk/openai and @ai-sdk/anthropic. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(cli): align ai doctor checks with the runtime - ai-gateway-token-unused now fires whenever ctx.ai is used with LUNORA_AI_GATEWAY_TOKEN set: the Workers AI binding cannot send it, with or without a gateway id. - The checks read top-level vars, env.<name>.vars and .dev.vars, so a proxy or gateway id set outside top-level vars no longer triggers a spurious finding. - Binding inference runs once in runDoctor and feeds both the export and AI checks. - WranglerConfig types the ai binding; the env var names live in one CLI module. - lunora ai gateway reuses @lunora/config's applyModify (now exported from @lunora/config/cloudflare) and returns one failure shape from its resolvers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(studio): count cost-only ai calls and fold usage per model - The history call count takes the largest series count per (function, model) pair and sums across pairs, so a call that reported only a cost is counted and two models' counts are never merged by max. - One slice-based flow serves both the history and live halves. - ai.embed spans (defineRag) show up in recent calls. - formatUsd/formatTokens move to reports/metrics-format and use the renderer's locale. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • docs(platform-node): match the ai row to the emulated rating Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): refuse a proxy token over plain http - LUNORA_AI_PROXY_TOKEN is never sent to a non-HTTPS LUNORA_AI_PROXY_URL off loopback; the proxy provider throws a directed error on use instead, as it does for an unparsable URL. - lunora ai gateway --dry-run warns when the account id a real run needs is missing. - doctor reads an unreadable .dev.vars as unset instead of aborting the run. - The node agents note no longer claims ai is unsupported there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • fix(ai): record stream usage that arrived before an upstream error A stream that emitted its finish part and then errored lost that usage: the span failed before recordUsage ran. The instrumented stream now settles once with its outcome and the error, so usage is recorded first and the error is then rethrown to fail the span. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Added

  • ai: AI Gateway model routing, per-function AI spend, and ctx.ai action-only (#910) (f0e8623)

Dependencies

  • @lunora/advisor: upgraded to 1.0.0-alpha.172
  • @lunora/bindings: upgraded to 1.0.0-alpha.85
  • @lunora/client: upgraded to 1.0.0-alpha.162
  • @lunora/react: upgraded to 1.0.0-alpha.169
  • @lunora/platform: upgraded to 1.0.0-alpha.44
  • @lunora/runtime: upgraded to 1.0.0-alpha.164
  • @lunora/shard-engine: upgraded to 1.0.0-alpha.100
@lunora/vitefeature

1.0.0-alpha.282

diff

Added

  • Rsbuild templates (React SPA + TanStack Start) with Studio under @lunora/rspack (#909) (2d8b101)

Dependencies

  • @lunora/config: upgraded to 1.0.0-alpha.284
Sep 29, 2026

Dependency updates only, across 39 packages.

@lunora/agentfeature

1.0.0-alpha.153

diff

Added

  • platform-celld: add celld as a platform host (#359) (6391cbc)

Dependencies

  • @lunora/ai: upgraded to 1.0.0-alpha.103
  • @lunora/server: upgraded to 1.0.0-alpha.160
@lunora/agentchore

1.0.0-alpha.152

diff

⚠ BREAKING CHANGES

  • codegen: a query reached from a mutation or action (runQuery, tracked or untracked, or createCaller) now has run* guarded as a query's, so runMutation/runAction from it throws RUN_KIND_FORBIDDEN, and an untracked sub-query from an action no longer carries action-only helpers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • chore(examples): regenerate generated files for the composed-query view Re-run codegen in every example so the committed _generated/functions.ts and shard.ts match the emitter (lint:generated). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • refactor(codegen): split emit.ts into per-emitter modules The 7k-line emit.ts becomes src/emit/, one module per emitter plus shared helpers; src/emit/index.ts keeps every existing ./emit import working. emitShard's static and feature-gated sections move out of its 2.2k-line template into shard-context (buildCtx), shard-dispatch (dispatchRun, RPC and subscription methods), shard-admin, shard-shapes, shard-sources and shard-vectors. Every module is now under 1k lines. Emitted output is byte-identical: the golden fixtures are unchanged and the public API snapshot still matches. Comments elsewhere that pointed at emit.ts now name the module that owns the code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Fixed

  • codegen: give a composed ctx.runQuery its own query context (#907) (3291182), closes #905

Dependencies

  • @lunora/server: upgraded to 1.0.0-alpha.159
@lunora/aifeature

1.0.0-alpha.103

diff

Added

  • platform-celld: add celld as a platform host (#359) (6391cbc)
@lunora/bindingschore

1.0.0-alpha.83

diff

⚠ BREAKING CHANGES

  • codegen: a query reached from a mutation or action (runQuery, tracked or untracked, or createCaller) now has run* guarded as a query's, so runMutation/runAction from it throws RUN_KIND_FORBIDDEN, and an untracked sub-query from an action no longer carries action-only helpers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • chore(examples): regenerate generated files for the composed-query view Re-run codegen in every example so the committed _generated/functions.ts and shard.ts match the emitter (lint:generated). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • refactor(codegen): split emit.ts into per-emitter modules The 7k-line emit.ts becomes src/emit/, one module per emitter plus shared helpers; src/emit/index.ts keeps every existing ./emit import working. emitShard's static and feature-gated sections move out of its 2.2k-line template into shard-context (buildCtx), shard-dispatch (dispatchRun, RPC and subscription methods), shard-admin, shard-shapes, shard-sources and shard-vectors. Every module is now under 1k lines. Emitted output is byte-identical: the golden fixtures are unchanged and the public API snapshot still matches. Comments elsewhere that pointed at emit.ts now name the module that owns the code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Fixed

  • codegen: give a composed ctx.runQuery its own query context (#907) (3291182), closes #905
@lunora/clifeature

1.0.0-alpha.325

diff

Added

  • platform-celld: add celld as a platform host (#359) (6391cbc)

Dependencies

  • @lunora/advisor: upgraded to 1.0.0-alpha.171
  • @lunora/bindings: upgraded to 1.0.0-alpha.84
  • @lunora/codegen: upgraded to 1.0.0-alpha.238
  • @lunora/config: upgraded to 1.0.0-alpha.283
  • @lunora/d1: upgraded to 1.0.0-alpha.151
  • @lunora/mcp: upgraded to 1.0.0-alpha.197
  • @lunora/runtime: upgraded to 1.0.0-alpha.163
  • @lunora/seed: upgraded to 1.0.0-alpha.169
  • @lunora/testing: upgraded to 1.0.0-alpha.210
@lunora/codegenfeature

1.0.0-alpha.239

diff

Added

  • Rsbuild templates (React SPA + TanStack Start) with Studio under @lunora/rspack (#909) (2d8b101)
@lunora/codegenfeature

1.0.0-alpha.238

diff

Added

  • platform-celld: add celld as a platform host (#359) (6391cbc)

Dependencies

  • @lunora/advisor: upgraded to 1.0.0-alpha.171
  • @lunora/agent: upgraded to 1.0.0-alpha.153
  • @lunora/platform: upgraded to 1.0.0-alpha.43
  • @lunora/queue: upgraded to 1.0.0-alpha.78
  • @lunora/scheduler: upgraded to 1.0.0-alpha.97
  • @lunora/do: upgraded to 1.0.0-alpha.181
  • @lunora/server: upgraded to 1.0.0-alpha.160
  • @lunora/shard-engine: upgraded to 1.0.0-alpha.99
@lunora/codegenchore

1.0.0-alpha.237

diff

⚠ BREAKING CHANGES

  • codegen: a query reached from a mutation or action (runQuery, tracked or untracked, or createCaller) now has run* guarded as a query's, so runMutation/runAction from it throws RUN_KIND_FORBIDDEN, and an untracked sub-query from an action no longer carries action-only helpers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • chore(examples): regenerate generated files for the composed-query view Re-run codegen in every example so the committed _generated/functions.ts and shard.ts match the emitter (lint:generated). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • refactor(codegen): split emit.ts into per-emitter modules The 7k-line emit.ts becomes src/emit/, one module per emitter plus shared helpers; src/emit/index.ts keeps every existing ./emit import working. emitShard's static and feature-gated sections move out of its 2.2k-line template into shard-context (buildCtx), shard-dispatch (dispatchRun, RPC and subscription methods), shard-admin, shard-shapes, shard-sources and shard-vectors. Every module is now under 1k lines. Emitted output is byte-identical: the golden fixtures are unchanged and the public API snapshot still matches. Comments elsewhere that pointed at emit.ts now name the module that owns the code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Fixed

  • codegen: give a composed ctx.runQuery its own query context (#907) (3291182), closes #905

Dependencies

  • @lunora/advisor: upgraded to 1.0.0-alpha.170
  • @lunora/agent: upgraded to 1.0.0-alpha.152
  • @lunora/do: upgraded to 1.0.0-alpha.180
  • @lunora/server: upgraded to 1.0.0-alpha.159
  • @lunora/shard-engine: upgraded to 1.0.0-alpha.98
@lunora/configfeature

1.0.0-alpha.283

diff

Added

  • platform-celld: add celld as a platform host (#359) (6391cbc)

Dependencies

  • @lunora/codegen: upgraded to 1.0.0-alpha.238
  • @lunora/seed: upgraded to 1.0.0-alpha.169
  • @lunora/studio: upgraded to 1.0.0-alpha.241
@lunora/dochore

1.0.0-alpha.180

diff

⚠ BREAKING CHANGES

  • codegen: a query reached from a mutation or action (runQuery, tracked or untracked, or createCaller) now has run* guarded as a query's, so runMutation/runAction from it throws RUN_KIND_FORBIDDEN, and an untracked sub-query from an action no longer carries action-only helpers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • chore(examples): regenerate generated files for the composed-query view Re-run codegen in every example so the committed _generated/functions.ts and shard.ts match the emitter (lint:generated). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • refactor(codegen): split emit.ts into per-emitter modules The 7k-line emit.ts becomes src/emit/, one module per emitter plus shared helpers; src/emit/index.ts keeps every existing ./emit import working. emitShard's static and feature-gated sections move out of its 2.2k-line template into shard-context (buildCtx), shard-dispatch (dispatchRun, RPC and subscription methods), shard-admin, shard-shapes, shard-sources and shard-vectors. Every module is now under 1k lines. Emitted output is byte-identical: the golden fixtures are unchanged and the public API snapshot still matches. Comments elsewhere that pointed at emit.ts now name the module that owns the code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Fixed

  • codegen: give a composed ctx.runQuery its own query context (#907) (3291182), closes #905

Dependencies

  • @lunora/observability: upgraded to 1.0.0-alpha.107
  • @lunora/shard-engine: upgraded to 1.0.0-alpha.98
  • @lunora/bindings: upgraded to 1.0.0-alpha.83
@lunora/dofeature

1.0.0-alpha.179

diff

Added

  • studio: inline AI rewrite for the SQL console (#508) (c50eebb)
@lunora/observabilitychore

1.0.0-alpha.107

diff

⚠ BREAKING CHANGES

  • codegen: a query reached from a mutation or action (runQuery, tracked or untracked, or createCaller) now has run* guarded as a query's, so runMutation/runAction from it throws RUN_KIND_FORBIDDEN, and an untracked sub-query from an action no longer carries action-only helpers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • chore(examples): regenerate generated files for the composed-query view Re-run codegen in every example so the committed _generated/functions.ts and shard.ts match the emitter (lint:generated). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • refactor(codegen): split emit.ts into per-emitter modules The 7k-line emit.ts becomes src/emit/, one module per emitter plus shared helpers; src/emit/index.ts keeps every existing ./emit import working. emitShard's static and feature-gated sections move out of its 2.2k-line template into shard-context (buildCtx), shard-dispatch (dispatchRun, RPC and subscription methods), shard-admin, shard-shapes, shard-sources and shard-vectors. Every module is now under 1k lines. Emitted output is byte-identical: the golden fixtures are unchanged and the public API snapshot still matches. Comments elsewhere that pointed at emit.ts now name the module that owns the code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Fixed

  • codegen: give a composed ctx.runQuery its own query context (#907) (3291182), closes #905

Dependencies

  • @lunora/shard-engine: upgraded to 1.0.0-alpha.98
@lunora/platformfeature

1.0.0-alpha.43

diff

Added

  • platform-celld: add celld as a platform host (#359) (6391cbc)
@lunora/platform-nodefeature

1.0.0-alpha.106

diff

Added

  • platform-celld: add celld as a platform host (#359) (6391cbc)

Dependencies

  • @lunora/d1: upgraded to 1.0.0-alpha.151
  • @lunora/platform: upgraded to 1.0.0-alpha.43
  • @lunora/queue: upgraded to 1.0.0-alpha.78
  • @lunora/sql-store: upgraded to 1.0.0-alpha.152
  • @lunora/do: upgraded to 1.0.0-alpha.181
  • @lunora/platform-cloudflare: upgraded to 1.0.0-alpha.62
  • @lunora/runtime: upgraded to 1.0.0-alpha.163
  • @lunora/shard-engine: upgraded to 1.0.0-alpha.99
  • @lunora/storage: upgraded to 1.0.0-alpha.91
@lunora/serverchore

1.0.0-alpha.159

diff

⚠ BREAKING CHANGES

  • codegen: a query reached from a mutation or action (runQuery, tracked or untracked, or createCaller) now has run* guarded as a query's, so runMutation/runAction from it throws RUN_KIND_FORBIDDEN, and an untracked sub-query from an action no longer carries action-only helpers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • chore(examples): regenerate generated files for the composed-query view Re-run codegen in every example so the committed _generated/functions.ts and shard.ts match the emitter (lint:generated). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • refactor(codegen): split emit.ts into per-emitter modules The 7k-line emit.ts becomes src/emit/, one module per emitter plus shared helpers; src/emit/index.ts keeps every existing ./emit import working. emitShard's static and feature-gated sections move out of its 2.2k-line template into shard-context (buildCtx), shard-dispatch (dispatchRun, RPC and subscription methods), shard-admin, shard-shapes, shard-sources and shard-vectors. Every module is now under 1k lines. Emitted output is byte-identical: the golden fixtures are unchanged and the public API snapshot still matches. Comments elsewhere that pointed at emit.ts now name the module that owns the code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Fixed

  • codegen: give a composed ctx.runQuery its own query context (#907) (3291182), closes #905

Dependencies

  • @lunora/shard-engine: upgraded to 1.0.0-alpha.98
  • @lunora/observability: upgraded to 1.0.0-alpha.107
@lunora/shard-enginechore

1.0.0-alpha.98

diff

⚠ BREAKING CHANGES

  • codegen: a query reached from a mutation or action (runQuery, tracked or untracked, or createCaller) now has run* guarded as a query's, so runMutation/runAction from it throws RUN_KIND_FORBIDDEN, and an untracked sub-query from an action no longer carries action-only helpers. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • chore(examples): regenerate generated files for the composed-query view Re-run codegen in every example so the committed _generated/functions.ts and shard.ts match the emitter (lint:generated). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
  • refactor(codegen): split emit.ts into per-emitter modules The 7k-line emit.ts becomes src/emit/, one module per emitter plus shared helpers; src/emit/index.ts keeps every existing ./emit import working. emitShard's static and feature-gated sections move out of its 2.2k-line template into shard-context (buildCtx), shard-dispatch (dispatchRun, RPC and subscription methods), shard-admin, shard-shapes, shard-sources and shard-vectors. Every module is now under 1k lines. Emitted output is byte-identical: the golden fixtures are unchanged and the public API snapshot still matches. Comments elsewhere that pointed at emit.ts now name the module that owns the code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Fixed

  • codegen: give a composed ctx.runQuery its own query context (#907) (3291182), closes #905

Dependencies

  • @lunora/bindings: upgraded to 1.0.0-alpha.83
@lunora/studiofeature

1.0.0-alpha.239

diff

Added

  • studio: inline AI rewrite for the SQL console (#508) (c50eebb)
Open source

Built in the open, on purpose.

Nothing about Lunora is a black box. Read it, fork it, or send the fix yourself.