@lunora/ai 1.0.0-alpha.20 → 1.0.0-alpha.22

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/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { L as LunoraAiOptions, a as LunoraAi } from "./packem_shared/types.d-BXCiRv1x.mjs";
2
- export type { A as AiBindingLike, b as AiGatewayOptions, E as EmbeddingModelInput, M as ModelInput, W as WorkersAiProviderLike } from "./packem_shared/types.d-BXCiRv1x.mjs";
1
+ import { L as LunoraAiOptions, a as LunoraAi } from "./packem_shared/types.d-DGmh5Hq4.mjs";
2
+ export type { A as AiBindingLike, b as AiGatewayOptions, E as EmbeddingModelInput, M as ModelInput, W as WorkersAiProviderLike } from "./packem_shared/types.d-DGmh5Hq4.mjs";
3
3
  export { type EmbeddingModel, type LanguageModel, embed, embedMany, generateObject, generateText, hasToolCall, jsonSchema, streamObject, streamText, tool } from 'ai';
4
4
  export { createWorkersAI } from 'workers-ai-provider';
5
5
  /**
@@ -25,4 +25,66 @@ export { createWorkersAI } from 'workers-ai-provider';
25
25
  * @experimental
26
26
  */
27
27
  declare const createAi: (options: LunoraAiOptions) => LunoraAi;
28
- export { type LunoraAi, type LunoraAiOptions, createAi };
28
+ /**
29
+ * Correlation metadata folded into the `cf-aig-metadata` request header so a
30
+ * gateway log entry can be tied back to the Lunora function + trace that made
31
+ * the call. Every field is optional — only defined ones are sent.
32
+ * @experimental
33
+ */
34
+ interface AiGatewayMetadata {
35
+ /** The Lunora function path that issued the model call (e.g. `messages:send`). */
36
+ functionPath?: string;
37
+ /** The 32-hex trace id the call belongs to, so the gateway log joins the trace. */
38
+ traceId?: string;
39
+ }
40
+ /**
41
+ * The resolved AI Gateway coordinates.
42
+ *
43
+ * `gatewayId`/`accountId` drive the Workers AI provider's native `gateway` option
44
+ * (Cloudflare routes the binding call internally). `baseURL` + `headers` are for
45
+ * bring-your-own AI SDK providers (`@ai-sdk/openai`, …): append the provider
46
+ * slug to `baseURL` and spread `headers` into the provider config, e.g.
47
+ *
48
+ * ```ts
49
+ * const gw = resolveAiGateway(env);
50
+ * const openai = createOpenAI(gw ? { baseURL: `${gw.baseURL}/openai`, headers: gw.headers } : {});
51
+ * ```
52
+ * @experimental
53
+ */
54
+ interface ResolvedAiGateway {
55
+ /** The Cloudflare account id owning the gateway. */
56
+ accountId: string;
57
+ /**
58
+ * The universal gateway base URL:
59
+ * `https://gateway.ai.cloudflare.com/v1/{account}/{gateway}`. Append the
60
+ * provider slug (`/openai`, `/anthropic`, `/workers-ai`, …) per provider.
61
+ */
62
+ baseURL: string;
63
+ /** The gateway id (slug). */
64
+ gatewayId: string;
65
+ /**
66
+ * Request headers for a gateway-routed call: `cf-aig-authorization` when the
67
+ * gateway is authenticated, and `cf-aig-metadata` when correlation metadata
68
+ * was supplied. Empty object when neither applies.
69
+ */
70
+ headers: Record<string, string>;
71
+ }
72
+ /** Env var naming the Cloudflare account that owns the gateway. */
73
+ declare const AI_GATEWAY_ACCOUNT_ID_ENV = "LUNORA_AI_GATEWAY_ACCOUNT_ID";
74
+ /** Env var naming the AI Gateway id (the gateway's slug). */
75
+ declare const AI_GATEWAY_ID_ENV = "LUNORA_AI_GATEWAY_ID";
76
+ /** Env var carrying the gateway's authentication token (only for authenticated gateways). */
77
+ declare const AI_GATEWAY_TOKEN_ENV = "LUNORA_AI_GATEWAY_TOKEN";
78
+ /**
79
+ * Resolve the Cloudflare AI Gateway coordinates from the Worker `env`, or
80
+ * `undefined` when the gateway is not configured (both `LUNORA_AI_GATEWAY_ACCOUNT_ID`
81
+ * and `LUNORA_AI_GATEWAY_ID` must be present). Opt-in and backward-compatible:
82
+ * an unconfigured app gets `undefined` and every caller keeps its direct-provider
83
+ * behavior.
84
+ *
85
+ * Pass optional {@link AiGatewayMetadata} to fold a `cf-aig-metadata` correlation
86
+ * header into `headers` — only its defined fields are sent.
87
+ * @experimental
88
+ */
89
+ declare const resolveAiGateway: (env: Record<string, unknown>, metadata?: AiGatewayMetadata) => ResolvedAiGateway | undefined;
90
+ export { AI_GATEWAY_ACCOUNT_ID_ENV, AI_GATEWAY_ID_ENV, AI_GATEWAY_TOKEN_ENV, type AiGatewayMetadata, type LunoraAi, type LunoraAiOptions, type ResolvedAiGateway, createAi, resolveAiGateway };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { L as LunoraAiOptions, a as LunoraAi } from "./packem_shared/types.d-BXCiRv1x.js";
2
- export type { A as AiBindingLike, b as AiGatewayOptions, E as EmbeddingModelInput, M as ModelInput, W as WorkersAiProviderLike } from "./packem_shared/types.d-BXCiRv1x.js";
1
+ import { L as LunoraAiOptions, a as LunoraAi } from "./packem_shared/types.d-DGmh5Hq4.js";
2
+ export type { A as AiBindingLike, b as AiGatewayOptions, E as EmbeddingModelInput, M as ModelInput, W as WorkersAiProviderLike } from "./packem_shared/types.d-DGmh5Hq4.js";
3
3
  export { type EmbeddingModel, type LanguageModel, embed, embedMany, generateObject, generateText, hasToolCall, jsonSchema, streamObject, streamText, tool } from 'ai';
4
4
  export { createWorkersAI } from 'workers-ai-provider';
5
5
  /**
@@ -25,4 +25,66 @@ export { createWorkersAI } from 'workers-ai-provider';
25
25
  * @experimental
26
26
  */
27
27
  declare const createAi: (options: LunoraAiOptions) => LunoraAi;
28
- export { type LunoraAi, type LunoraAiOptions, createAi };
28
+ /**
29
+ * Correlation metadata folded into the `cf-aig-metadata` request header so a
30
+ * gateway log entry can be tied back to the Lunora function + trace that made
31
+ * the call. Every field is optional — only defined ones are sent.
32
+ * @experimental
33
+ */
34
+ interface AiGatewayMetadata {
35
+ /** The Lunora function path that issued the model call (e.g. `messages:send`). */
36
+ functionPath?: string;
37
+ /** The 32-hex trace id the call belongs to, so the gateway log joins the trace. */
38
+ traceId?: string;
39
+ }
40
+ /**
41
+ * The resolved AI Gateway coordinates.
42
+ *
43
+ * `gatewayId`/`accountId` drive the Workers AI provider's native `gateway` option
44
+ * (Cloudflare routes the binding call internally). `baseURL` + `headers` are for
45
+ * bring-your-own AI SDK providers (`@ai-sdk/openai`, …): append the provider
46
+ * slug to `baseURL` and spread `headers` into the provider config, e.g.
47
+ *
48
+ * ```ts
49
+ * const gw = resolveAiGateway(env);
50
+ * const openai = createOpenAI(gw ? { baseURL: `${gw.baseURL}/openai`, headers: gw.headers } : {});
51
+ * ```
52
+ * @experimental
53
+ */
54
+ interface ResolvedAiGateway {
55
+ /** The Cloudflare account id owning the gateway. */
56
+ accountId: string;
57
+ /**
58
+ * The universal gateway base URL:
59
+ * `https://gateway.ai.cloudflare.com/v1/{account}/{gateway}`. Append the
60
+ * provider slug (`/openai`, `/anthropic`, `/workers-ai`, …) per provider.
61
+ */
62
+ baseURL: string;
63
+ /** The gateway id (slug). */
64
+ gatewayId: string;
65
+ /**
66
+ * Request headers for a gateway-routed call: `cf-aig-authorization` when the
67
+ * gateway is authenticated, and `cf-aig-metadata` when correlation metadata
68
+ * was supplied. Empty object when neither applies.
69
+ */
70
+ headers: Record<string, string>;
71
+ }
72
+ /** Env var naming the Cloudflare account that owns the gateway. */
73
+ declare const AI_GATEWAY_ACCOUNT_ID_ENV = "LUNORA_AI_GATEWAY_ACCOUNT_ID";
74
+ /** Env var naming the AI Gateway id (the gateway's slug). */
75
+ declare const AI_GATEWAY_ID_ENV = "LUNORA_AI_GATEWAY_ID";
76
+ /** Env var carrying the gateway's authentication token (only for authenticated gateways). */
77
+ declare const AI_GATEWAY_TOKEN_ENV = "LUNORA_AI_GATEWAY_TOKEN";
78
+ /**
79
+ * Resolve the Cloudflare AI Gateway coordinates from the Worker `env`, or
80
+ * `undefined` when the gateway is not configured (both `LUNORA_AI_GATEWAY_ACCOUNT_ID`
81
+ * and `LUNORA_AI_GATEWAY_ID` must be present). Opt-in and backward-compatible:
82
+ * an unconfigured app gets `undefined` and every caller keeps its direct-provider
83
+ * behavior.
84
+ *
85
+ * Pass optional {@link AiGatewayMetadata} to fold a `cf-aig-metadata` correlation
86
+ * header into `headers` — only its defined fields are sent.
87
+ * @experimental
88
+ */
89
+ declare const resolveAiGateway: (env: Record<string, unknown>, metadata?: AiGatewayMetadata) => ResolvedAiGateway | undefined;
90
+ export { AI_GATEWAY_ACCOUNT_ID_ENV, AI_GATEWAY_ID_ENV, AI_GATEWAY_TOKEN_ENV, type AiGatewayMetadata, type LunoraAi, type LunoraAiOptions, type ResolvedAiGateway, createAi, resolveAiGateway };
package/dist/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
- export { default as createAi } from './packem_shared/createAi-CYxQuvEL.mjs';
1
+ export { default as createAi } from './packem_shared/createAi-Dx7n-UJm.mjs';
2
+ export { AI_GATEWAY_ACCOUNT_ID_ENV, AI_GATEWAY_ID_ENV, AI_GATEWAY_TOKEN_ENV, resolveAiGateway } from './packem_shared/AI_GATEWAY_ACCOUNT_ID_ENV-2CS2QFH7.mjs';
2
3
  export { embed, embedMany, generateObject, generateText, hasToolCall, jsonSchema, streamObject, streamText, tool } from 'ai';
3
4
  export { createWorkersAI } from 'workers-ai-provider';
@@ -0,0 +1,44 @@
1
+ const readEnv = (env, key) => {
2
+ const value = env[key];
3
+ return typeof value === "string" && value.length > 0 ? value : void 0;
4
+ };
5
+ const encodeMetadata = (metadata) => {
6
+ if (metadata === void 0) {
7
+ return void 0;
8
+ }
9
+ const fields = {};
10
+ if (typeof metadata.functionPath === "string" && metadata.functionPath.length > 0) {
11
+ fields["functionPath"] = metadata.functionPath;
12
+ }
13
+ if (typeof metadata.traceId === "string" && metadata.traceId.length > 0) {
14
+ fields["traceId"] = metadata.traceId;
15
+ }
16
+ return Object.keys(fields).length > 0 ? JSON.stringify(fields) : void 0;
17
+ };
18
+ const AI_GATEWAY_ACCOUNT_ID_ENV = "LUNORA_AI_GATEWAY_ACCOUNT_ID";
19
+ const AI_GATEWAY_ID_ENV = "LUNORA_AI_GATEWAY_ID";
20
+ const AI_GATEWAY_TOKEN_ENV = "LUNORA_AI_GATEWAY_TOKEN";
21
+ const resolveAiGateway = (env, metadata) => {
22
+ const accountId = readEnv(env, AI_GATEWAY_ACCOUNT_ID_ENV);
23
+ const gatewayId = readEnv(env, AI_GATEWAY_ID_ENV);
24
+ if (accountId === void 0 || gatewayId === void 0) {
25
+ return void 0;
26
+ }
27
+ const token = readEnv(env, AI_GATEWAY_TOKEN_ENV);
28
+ const headers = {};
29
+ if (token !== void 0) {
30
+ headers["cf-aig-authorization"] = `Bearer ${token}`;
31
+ }
32
+ const metadataHeader = encodeMetadata(metadata);
33
+ if (metadataHeader !== void 0) {
34
+ headers["cf-aig-metadata"] = metadataHeader;
35
+ }
36
+ return {
37
+ accountId,
38
+ baseURL: `https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}`,
39
+ gatewayId,
40
+ headers
41
+ };
42
+ };
43
+
44
+ export { AI_GATEWAY_ACCOUNT_ID_ENV, AI_GATEWAY_ID_ENV, AI_GATEWAY_TOKEN_ENV, resolveAiGateway };
@@ -1,13 +1,25 @@
1
1
  import { LunoraError } from '@lunora/errors';
2
2
  import { createWorkersAI } from 'workers-ai-provider';
3
+ import { resolveAiGateway } from './AI_GATEWAY_ACCOUNT_ID_ENV-2CS2QFH7.mjs';
3
4
 
5
+ const resolveGatewayOption = (gateway, env) => {
6
+ if (gateway !== void 0) {
7
+ return gateway;
8
+ }
9
+ if (env === void 0) {
10
+ return void 0;
11
+ }
12
+ const resolved = resolveAiGateway(env);
13
+ return resolved === void 0 ? void 0 : { id: resolved.gatewayId };
14
+ };
4
15
  const buildProvider = (binding, gateway) => createWorkersAI({ binding, gateway });
5
16
  const createAi = (options) => {
6
- const { binding, defaultEmbeddingModel, defaultModel, gateway, provider } = options;
17
+ const { binding, defaultEmbeddingModel, defaultModel, env, gateway, provider } = options;
7
18
  if (!provider && !binding) {
8
19
  throw new LunoraError("INTERNAL", "@lunora/ai: createAi requires a `binding` (env.AI) or a pre-built `provider`");
9
20
  }
10
- const workersai = provider ?? buildProvider(binding, gateway);
21
+ const resolvedGateway = resolveGatewayOption(gateway, env);
22
+ const workersai = provider ?? buildProvider(binding, resolvedGateway);
11
23
  const model = (input) => {
12
24
  if (input === void 0) {
13
25
  if (!defaultModel) {
@@ -47,7 +59,8 @@ const createAi = (options) => {
47
59
  "@lunora/ai: ai.run requires the `binding` (env.AI) — it is unavailable when only a custom `provider` was supplied"
48
60
  );
49
61
  }
50
- return binding.run(modelId, inputs, runOptions);
62
+ const mergedOptions = resolvedGateway !== void 0 && runOptions?.gateway === void 0 ? { ...runOptions, gateway: resolvedGateway } : runOptions;
63
+ return binding.run(modelId, inputs, mergedOptions);
51
64
  };
52
65
  return { embeddingModel, model, run, workersai };
53
66
  };
@@ -113,6 +113,20 @@ const modelIdOf = (model) => {
113
113
  const id = model.modelId;
114
114
  return typeof id === "string" && id.length > 0 ? id : void 0;
115
115
  };
116
+ const embedCostOf = (providerMetadata) => {
117
+ if (typeof providerMetadata !== "object" || providerMetadata === null) {
118
+ return void 0;
119
+ }
120
+ for (const bag of Object.values(providerMetadata)) {
121
+ if (typeof bag === "object" && bag !== null) {
122
+ const { cost } = bag;
123
+ if (typeof cost === "number" && Number.isFinite(cost)) {
124
+ return cost;
125
+ }
126
+ }
127
+ }
128
+ return void 0;
129
+ };
116
130
  const defineRag = (config) => {
117
131
  if (typeof config.index !== "string" || config.index.length === 0) {
118
132
  throw new LunoraError("BAD_REQUEST", "@lunora/ai/rag: `index` must be a non-empty Vectorize index name");
@@ -151,15 +165,25 @@ const defineRag = (config) => {
151
165
  const embedText = async (text) => {
152
166
  model ??= resolveEmbeddingModel(config.embeddingModel, context.ai);
153
167
  const resolvedModel = model;
154
- const run = async () => {
155
- const { embedding } = await embed({ model: resolvedModel, value: text });
168
+ const run = async (span) => {
169
+ const { embedding, providerMetadata, usage } = await embed({ model: resolvedModel, value: text });
170
+ if (span !== void 0) {
171
+ const inputTokens = usage.tokens;
172
+ if (typeof inputTokens === "number" && Number.isFinite(inputTokens)) {
173
+ span.setAttribute("gen_ai.usage.input_tokens", inputTokens);
174
+ }
175
+ const cost = embedCostOf(providerMetadata);
176
+ if (cost !== void 0) {
177
+ span.setAttribute("gen_ai.usage.cost", cost);
178
+ }
179
+ }
156
180
  return embedding;
157
181
  };
158
182
  if (tracer === void 0) {
159
183
  return run();
160
184
  }
161
185
  const modelId = modelIdOf(resolvedModel);
162
- return tracer("ai.embed", run, {
186
+ return tracer("ai.embed", (_trace, span) => run(span), {
163
187
  "gen_ai.operation.name": "embeddings",
164
188
  ...modelId === void 0 ? {} : { "gen_ai.request.model": modelId }
165
189
  });
@@ -57,7 +57,19 @@ interface LunoraAiOptions {
57
57
  * Has no effect on bring-your-own providers.
58
58
  */
59
59
  defaultModel?: string;
60
- /** Route Workers AI inference through a Cloudflare AI Gateway. */
60
+ /**
61
+ * The Worker `env`, read for opt-in Cloudflare AI Gateway routing (the
62
+ * `LUNORA_AI_GATEWAY_*` vars, via `resolveAiGateway`). When it configures a
63
+ * gateway and no explicit {@link LunoraAiOptions.gateway} is given, the
64
+ * Workers AI provider is routed through that gateway so token + dollar-cost
65
+ * telemetry is computed on the app's behalf. Unset, or with no gateway vars,
66
+ * behavior is unchanged (calls go straight to Workers AI).
67
+ */
68
+ env?: Record<string, unknown>;
69
+ /**
70
+ * Route Workers AI inference through a Cloudflare AI Gateway. An explicit
71
+ * value wins over anything derived from {@link LunoraAiOptions.env}.
72
+ */
61
73
  gateway?: AiGatewayOptions;
62
74
  /**
63
75
  * Pre-built Workers AI provider. When omitted, one is constructed from
@@ -57,7 +57,19 @@ interface LunoraAiOptions {
57
57
  * Has no effect on bring-your-own providers.
58
58
  */
59
59
  defaultModel?: string;
60
- /** Route Workers AI inference through a Cloudflare AI Gateway. */
60
+ /**
61
+ * The Worker `env`, read for opt-in Cloudflare AI Gateway routing (the
62
+ * `LUNORA_AI_GATEWAY_*` vars, via `resolveAiGateway`). When it configures a
63
+ * gateway and no explicit {@link LunoraAiOptions.gateway} is given, the
64
+ * Workers AI provider is routed through that gateway so token + dollar-cost
65
+ * telemetry is computed on the app's behalf. Unset, or with no gateway vars,
66
+ * behavior is unchanged (calls go straight to Workers AI).
67
+ */
68
+ env?: Record<string, unknown>;
69
+ /**
70
+ * Route Workers AI inference through a Cloudflare AI Gateway. An explicit
71
+ * value wins over anything derived from {@link LunoraAiOptions.env}.
72
+ */
61
73
  gateway?: AiGatewayOptions;
62
74
  /**
63
75
  * Pre-built Workers AI provider. When omitted, one is constructed from
@@ -1,5 +1,5 @@
1
1
  import { Tool } from 'ai';
2
- import { E as EmbeddingModelInput, a as LunoraAi } from "../packem_shared/types.d-BXCiRv1x.mjs";
2
+ import { E as EmbeddingModelInput, a as LunoraAi } from "../packem_shared/types.d-DGmh5Hq4.mjs";
3
3
  /**
4
4
  * Built-in fixed-window chunker: split into `size`-char windows overlapping by
5
5
  * `overlap` chars. Deliberately simple and deterministic — the zero-config
@@ -112,11 +112,15 @@ interface RagContext {
112
112
  /**
113
113
  * Optional `ctx.trace` span factory — an `ActionCtx`'s `ctx.trace` satisfies
114
114
  * it structurally. When present, `defineRag` wraps each embedding-model
115
- * call in a `generation` span (`gen_ai.operation.name: "embeddings"` +
116
- * `gen_ai.request.model`), so the embed shows up on the trace waterfall like
117
- * any other instrumented sub-operation. `unknown` on purposethe same
118
- * decoupling rationale as `auth`: `defineRag` narrows it to a callable and
119
- * runs embeds untraced when it is absent (a hand-built context / test).
115
+ * call in a `generation` span carrying `gen_ai.operation.name: "embeddings"`
116
+ * and `gen_ai.request.model` up front, plus attached post-hoc through the
117
+ * span handle the tracer hands the body`gen_ai.usage.input_tokens` (from
118
+ * the embed result's token usage) and `gen_ai.usage.cost` (probed from the
119
+ * embed result's provider metadata, e.g. AI Gateway) when those are present.
120
+ * So the embed shows up on the trace waterfall with its usage like any other
121
+ * instrumented model call. `unknown` on purpose — the same decoupling
122
+ * rationale as `auth`: `defineRag` narrows it to a callable and runs embeds
123
+ * untraced when it is absent (a hand-built context / test).
120
124
  */
121
125
  trace?: unknown;
122
126
  vectors: RagVectors;
@@ -1,5 +1,5 @@
1
1
  import { Tool } from 'ai';
2
- import { E as EmbeddingModelInput, a as LunoraAi } from "../packem_shared/types.d-BXCiRv1x.js";
2
+ import { E as EmbeddingModelInput, a as LunoraAi } from "../packem_shared/types.d-DGmh5Hq4.js";
3
3
  /**
4
4
  * Built-in fixed-window chunker: split into `size`-char windows overlapping by
5
5
  * `overlap` chars. Deliberately simple and deterministic — the zero-config
@@ -112,11 +112,15 @@ interface RagContext {
112
112
  /**
113
113
  * Optional `ctx.trace` span factory — an `ActionCtx`'s `ctx.trace` satisfies
114
114
  * it structurally. When present, `defineRag` wraps each embedding-model
115
- * call in a `generation` span (`gen_ai.operation.name: "embeddings"` +
116
- * `gen_ai.request.model`), so the embed shows up on the trace waterfall like
117
- * any other instrumented sub-operation. `unknown` on purposethe same
118
- * decoupling rationale as `auth`: `defineRag` narrows it to a callable and
119
- * runs embeds untraced when it is absent (a hand-built context / test).
115
+ * call in a `generation` span carrying `gen_ai.operation.name: "embeddings"`
116
+ * and `gen_ai.request.model` up front, plus attached post-hoc through the
117
+ * span handle the tracer hands the body`gen_ai.usage.input_tokens` (from
118
+ * the embed result's token usage) and `gen_ai.usage.cost` (probed from the
119
+ * embed result's provider metadata, e.g. AI Gateway) when those are present.
120
+ * So the embed shows up on the trace waterfall with its usage like any other
121
+ * instrumented model call. `unknown` on purpose — the same decoupling
122
+ * rationale as `auth`: `defineRag` narrows it to a callable and runs embeds
123
+ * untraced when it is absent (a hand-built context / test).
120
124
  */
121
125
  trace?: unknown;
122
126
  vectors: RagVectors;
@@ -1,5 +1,5 @@
1
1
  export { default as fixedWindowChunks } from '../packem_shared/fixedWindowChunks-J-WfQDw9.mjs';
2
- export { default as defineRag } from '../packem_shared/defineRag-DgVXmNGw.mjs';
2
+ export { default as defineRag } from '../packem_shared/defineRag-CQ3pnKUh.mjs';
3
3
  export { contentHash, guessMimeTypeFromExtension } from '../packem_shared/contentHash-Cgz5KRGD.mjs';
4
4
  export { default as hybridRank } from '../packem_shared/hybridRank-DPC9c2ON.mjs';
5
5
  export { default as bm25LexicalStore } from '../packem_shared/bm25LexicalStore-BQzWLMqX.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/ai",
3
- "version": "1.0.0-alpha.20",
3
+ "version": "1.0.0-alpha.22",
4
4
  "description": "Workers AI helper for Lunora: provider-agnostic AI SDK access from functions, Workers AI by default",
5
5
  "keywords": [
6
6
  "ai",