@pithy-sh/cloudflare 0.1.2 → 0.1.3

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.
Files changed (139) hide show
  1. package/dist/ai/aiManager.d.ts +99 -0
  2. package/dist/ai/aiManager.d.ts.map +1 -0
  3. package/dist/ai/aiManager.js +148 -0
  4. package/dist/ai/vectorizeManager.d.ts +67 -0
  5. package/dist/ai/vectorizeManager.d.ts.map +1 -0
  6. package/dist/ai/vectorizeManager.js +101 -0
  7. package/dist/ai/vectorizeProvisioner.d.ts +123 -0
  8. package/dist/ai/vectorizeProvisioner.d.ts.map +1 -0
  9. package/dist/ai/vectorizeProvisioner.js +195 -0
  10. package/dist/client/accounts.d.ts +48 -0
  11. package/dist/client/accounts.d.ts.map +1 -0
  12. package/dist/client/accounts.js +55 -0
  13. package/dist/client/clients.d.ts +122 -0
  14. package/dist/client/clients.d.ts.map +1 -0
  15. package/dist/client/clients.js +216 -0
  16. package/dist/client/errors.d.ts +73 -0
  17. package/dist/client/errors.d.ts.map +1 -0
  18. package/dist/client/errors.js +98 -0
  19. package/dist/client/manager.d.ts +45 -0
  20. package/dist/client/manager.d.ts.map +1 -0
  21. package/dist/client/manager.js +51 -0
  22. package/dist/d1/d1Manager.d.ts +74 -0
  23. package/dist/d1/d1Manager.d.ts.map +1 -0
  24. package/dist/d1/d1Manager.js +128 -0
  25. package/dist/d1/d1PreparedStatement.d.ts +24 -0
  26. package/dist/d1/d1PreparedStatement.d.ts.map +1 -0
  27. package/dist/d1/d1PreparedStatement.js +91 -0
  28. package/dist/d1/d1Provisioner.d.ts +28 -0
  29. package/dist/d1/d1Provisioner.d.ts.map +1 -0
  30. package/dist/d1/d1Provisioner.js +67 -0
  31. package/dist/email/emailRoutingManager.d.ts +36 -0
  32. package/dist/email/emailRoutingManager.d.ts.map +1 -0
  33. package/dist/email/emailRoutingManager.js +124 -0
  34. package/dist/email/emailSendManager.d.ts +45 -0
  35. package/dist/email/emailSendManager.d.ts.map +1 -0
  36. package/dist/email/emailSendManager.js +52 -0
  37. package/dist/env/devVars.d.ts +65 -0
  38. package/dist/env/devVars.d.ts.map +1 -0
  39. package/dist/env/devVars.js +84 -0
  40. package/dist/hostnames/customHostnamesManager.d.ts +51 -0
  41. package/dist/hostnames/customHostnamesManager.d.ts.map +1 -0
  42. package/dist/hostnames/customHostnamesManager.js +84 -0
  43. package/dist/kv/kvManager.d.ts +76 -0
  44. package/dist/kv/kvManager.d.ts.map +1 -0
  45. package/dist/kv/kvManager.js +135 -0
  46. package/dist/kv/kvProvisioner.d.ts +28 -0
  47. package/dist/kv/kvProvisioner.d.ts.map +1 -0
  48. package/dist/kv/kvProvisioner.js +71 -0
  49. package/dist/media/assetSeeder.d.ts +31 -0
  50. package/dist/media/assetSeeder.d.ts.map +1 -0
  51. package/dist/media/assetSeeder.js +70 -0
  52. package/dist/media/imageManager.d.ts +34 -0
  53. package/dist/media/imageManager.d.ts.map +1 -0
  54. package/dist/media/imageManager.js +103 -0
  55. package/dist/media/ownership.d.ts +40 -0
  56. package/dist/media/ownership.d.ts.map +1 -0
  57. package/dist/media/ownership.js +46 -0
  58. package/dist/media/streamManager.d.ts +83 -0
  59. package/dist/media/streamManager.d.ts.map +1 -0
  60. package/dist/media/streamManager.js +145 -0
  61. package/dist/queue/queueManager.d.ts +84 -0
  62. package/dist/queue/queueManager.d.ts.map +1 -0
  63. package/dist/queue/queueManager.js +114 -0
  64. package/dist/r2/r2Credentials.d.ts +12 -0
  65. package/dist/r2/r2Credentials.d.ts.map +1 -0
  66. package/dist/r2/r2Credentials.js +13 -0
  67. package/dist/r2/r2Manager.d.ts +226 -0
  68. package/dist/r2/r2Manager.d.ts.map +1 -0
  69. package/dist/r2/r2Manager.js +405 -0
  70. package/dist/r2/r2Provisioner.d.ts +39 -0
  71. package/dist/r2/r2Provisioner.d.ts.map +1 -0
  72. package/dist/r2/r2Provisioner.js +86 -0
  73. package/dist/secrets/secretsStoreManager.d.ts +82 -0
  74. package/dist/secrets/secretsStoreManager.d.ts.map +1 -0
  75. package/dist/secrets/secretsStoreManager.js +147 -0
  76. package/dist/secrets/secretsStores.d.ts +47 -0
  77. package/dist/secrets/secretsStores.d.ts.map +1 -0
  78. package/dist/secrets/secretsStores.js +65 -0
  79. package/dist/test-utils/emailRoutingRules.d.ts +39 -0
  80. package/dist/test-utils/emailRoutingRules.d.ts.map +1 -0
  81. package/dist/test-utils/emailRoutingRules.js +89 -0
  82. package/dist/test-utils/fixtureReportSetup.d.ts +25 -0
  83. package/dist/test-utils/fixtureReportSetup.d.ts.map +1 -0
  84. package/dist/test-utils/fixtureReportSetup.js +30 -0
  85. package/dist/test-utils/fixtures.d.ts +224 -0
  86. package/dist/test-utils/fixtures.d.ts.map +1 -0
  87. package/dist/test-utils/fixtures.js +277 -0
  88. package/dist/test-utils/harness.d.ts +192 -0
  89. package/dist/test-utils/harness.d.ts.map +1 -0
  90. package/dist/test-utils/harness.js +351 -0
  91. package/dist/test-utils/inboundRecorder.d.ts +91 -0
  92. package/dist/test-utils/inboundRecorder.d.ts.map +1 -0
  93. package/dist/test-utils/inboundRecorder.js +141 -0
  94. package/dist/test-utils/integrationSetup.d.ts +22 -0
  95. package/dist/test-utils/integrationSetup.d.ts.map +1 -0
  96. package/dist/test-utils/integrationSetup.js +37 -0
  97. package/dist/test-utils/reap.d.ts +112 -0
  98. package/dist/test-utils/reap.d.ts.map +1 -0
  99. package/dist/test-utils/reap.js +185 -0
  100. package/dist/tokens/accountTokensManager.d.ts +157 -0
  101. package/dist/tokens/accountTokensManager.d.ts.map +1 -0
  102. package/dist/tokens/accountTokensManager.js +280 -0
  103. package/dist/tokens/permissions.d.ts +36 -0
  104. package/dist/tokens/permissions.d.ts.map +1 -0
  105. package/dist/tokens/permissions.js +50 -0
  106. package/dist/tokens/profiles.d.ts +102 -0
  107. package/dist/tokens/profiles.d.ts.map +1 -0
  108. package/dist/tokens/profiles.js +137 -0
  109. package/dist/turnstile/turnstileManager.d.ts +75 -0
  110. package/dist/turnstile/turnstileManager.d.ts.map +1 -0
  111. package/dist/turnstile/turnstileManager.js +138 -0
  112. package/dist/user/userManager.d.ts +36 -0
  113. package/dist/user/userManager.d.ts.map +1 -0
  114. package/dist/user/userManager.js +58 -0
  115. package/dist/workers/buildsManager.d.ts +116 -0
  116. package/dist/workers/buildsManager.d.ts.map +1 -0
  117. package/dist/workers/buildsManager.js +237 -0
  118. package/dist/workers/buildsTypes.d.ts +102 -0
  119. package/dist/workers/buildsTypes.d.ts.map +1 -0
  120. package/dist/workers/buildsTypes.js +87 -0
  121. package/dist/workers/workersBuildEvent.d.ts +64 -0
  122. package/dist/workers/workersBuildEvent.d.ts.map +1 -0
  123. package/dist/workers/workersBuildEvent.js +47 -0
  124. package/dist/workers/workersManager.d.ts +136 -0
  125. package/dist/workers/workersManager.d.ts.map +1 -0
  126. package/dist/workers/workersManager.js +312 -0
  127. package/dist/workers/workersProvisioner.d.ts +80 -0
  128. package/dist/workers/workersProvisioner.d.ts.map +1 -0
  129. package/dist/workers/workersProvisioner.js +106 -0
  130. package/dist/workflows/stepFailure.d.ts +180 -0
  131. package/dist/workflows/stepFailure.d.ts.map +1 -0
  132. package/dist/workflows/stepFailure.js +227 -0
  133. package/dist/workflows/workflowsClient.d.ts +87 -0
  134. package/dist/workflows/workflowsClient.d.ts.map +1 -0
  135. package/dist/workflows/workflowsClient.js +156 -0
  136. package/dist/zones/zonesManager.d.ts +50 -0
  137. package/dist/zones/zonesManager.d.ts.map +1 -0
  138. package/dist/zones/zonesManager.js +74 -0
  139. package/package.json +18 -9
@@ -0,0 +1,99 @@
1
+ import type { AIRunResponse } from "cloudflare/resources/ai/ai";
2
+ import type { ModelListResponse } from "cloudflare/resources/ai/models/models";
3
+ import { z } from "zod";
4
+ import { CloudflareManager } from "../client/manager";
5
+ /**
6
+ * The embeddings payload Cloudflare's text-embedding models return: a `shape` describing the
7
+ * `[count, dimensions]` of the result and a `data` array of one vector per input. Generic — this
8
+ * is the raw CF shape, carrying no application meaning, so callers can store or query it directly.
9
+ */
10
+ export declare const VectorEmbeddings: z.ZodObject<{
11
+ shape: z.ZodArray<z.ZodNumber>;
12
+ data: z.ZodArray<z.ZodArray<z.ZodNumber>>;
13
+ }, z.core.$strip>;
14
+ export type VectorEmbeddings = z.infer<typeof VectorEmbeddings>;
15
+ export declare const TextGeneration: z.ZodPipe<z.ZodUnion<readonly [z.ZodObject<{
16
+ response: z.ZodString;
17
+ }, z.core.$strip>, z.ZodObject<{
18
+ choices: z.ZodArray<z.ZodObject<{
19
+ message: z.ZodObject<{
20
+ content: z.ZodString;
21
+ }, z.core.$strip>;
22
+ }, z.core.$strip>>;
23
+ }, z.core.$strip>]>, z.ZodTransform<{
24
+ response: string;
25
+ }, {
26
+ response: string;
27
+ } | {
28
+ choices: {
29
+ message: {
30
+ content: string;
31
+ };
32
+ }[];
33
+ }>>;
34
+ export type TextGeneration = z.output<typeof TextGeneration>;
35
+ /**
36
+ * The image-to-text payload Cloudflare's vision models return: a textual description of the image.
37
+ */
38
+ export declare const ImageToText: z.ZodObject<{
39
+ description: z.ZodString;
40
+ }, z.core.$strip>;
41
+ export type ImageToText = z.infer<typeof ImageToText>;
42
+ /** Options for `generateText`. */
43
+ export interface GenerateTextOptions {
44
+ /** The model to run. Defaults to a generic instruct model. */
45
+ model?: string;
46
+ /** Upper bound on generated tokens. Omit for the model default. */
47
+ maxTokens?: number;
48
+ }
49
+ /** A single chat message passed to a text-generation model. */
50
+ export interface ChatMessage {
51
+ /** The role of the speaker. */
52
+ role: "system" | "user" | "assistant";
53
+ /** The message content. */
54
+ content: string;
55
+ }
56
+ /** Options for `analyzeImage`. */
57
+ export interface AnalyzeImageOptions {
58
+ /** The model to run. Defaults to a generic vision model. */
59
+ model?: string;
60
+ /** The instruction guiding the description. Defaults to a generic alt-text prompt. */
61
+ prompt?: string;
62
+ /** Upper bound on generated tokens. */
63
+ maxTokens?: number;
64
+ }
65
+ /**
66
+ * Out-of-Worker Workers AI access over the REST API: run any model, generate text, generate
67
+ * embeddings, analyze an image, and list models from a CLI/CI/provisioning context. Inside a
68
+ * Worker you use the `Ai` binding directly — this manager is the REST counterpart, addressed by
69
+ * account id. Every model call carries no application logic; the caller chooses the model and
70
+ * interprets the result.
71
+ */
72
+ export declare class CloudflareAIManager extends CloudflareManager {
73
+ /**
74
+ * Run a Cloudflare AI model by name with an arbitrary JSON input. The single seam every typed
75
+ * helper builds on. The account id is injected for you; the rest of `input` is the model's body.
76
+ */
77
+ runModel(model: string, input: Record<string, unknown>): Promise<AIRunResponse>;
78
+ /**
79
+ * Generate text from a chat prompt. Returns the validated `{ response }` payload. A response that
80
+ * does not carry a string `response` field fails Zod and throws `cloudflare/invalid_response`.
81
+ */
82
+ generateText(messages: ChatMessage[], options?: GenerateTextOptions): Promise<TextGeneration>;
83
+ /**
84
+ * Generate embeddings for one or more texts. Returns the validated `{ shape, data }` payload. A
85
+ * response that does not match fails Zod and throws `cloudflare/invalid_response`.
86
+ */
87
+ generateEmbeddings(texts: string | string[], model?: string): Promise<VectorEmbeddings>;
88
+ /**
89
+ * Describe an image with a vision model. The image is raw bytes, base64-encoded for the model
90
+ * input. Returns the validated `{ description }` payload.
91
+ */
92
+ analyzeImage(image: Uint8Array, options?: AnalyzeImageOptions): Promise<ImageToText>;
93
+ /** List the AI models available to this account. Returns an empty array when none are present. */
94
+ listModels(): Promise<ModelListResponse[]>;
95
+ getServiceType(): string;
96
+ /** Prove access by listing models. Never throws. */
97
+ validateServiceAccess(): Promise<boolean>;
98
+ }
99
+ //# sourceMappingURL=aiManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aiManager.d.ts","sourceRoot":"","sources":["../../src/ai/aiManager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE/E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAiBtD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;iBAKgE,CAAC;AAC9F,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAuChE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;GAckE,CAAC;AAC9F,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,WAAW;;iBAI8D,CAAC;AACvF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,kCAAkC;AAClC,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,+BAA+B;IAC/B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,kCAAkC;AAClC,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,iBAAiB;IACxD;;;OAGG;IACG,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAIpF;IAED;;;OAGG;IACG,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CAclG;IAED;;;OAGG;IACG,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAU5F;IAED;;;OAGG;IACG,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAAC,CAezF;IAED,kGAAkG;IAC5F,UAAU,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAK/C;IAED,cAAc,IAAI,MAAM,CAEvB;IAED,oDAAoD;IAC9C,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;CACF"}
@@ -0,0 +1,148 @@
1
+ import { CloudflareInvalidResponseError, cloudflareRequest } from "../client/errors.js";
2
+ import { CloudflareManager } from "../client/manager.js";
3
+ import { fromUint8Array } from "js-base64";
4
+ import { z } from "zod";
5
+ //#region src/ai/aiManager.ts
6
+ /**
7
+ * The default text-generation model. A generic, well-supported instruct model — callers can
8
+ * override per call via `runModel`. Not Leed-specific.
9
+ */
10
+ const DEFAULT_TEXT_MODEL = "@cf/meta/llama-4-scout-17b-16e-instruct";
11
+ /**
12
+ * The default text-embedding model. `bge-m3` returns a `{ shape, data }` payload matching
13
+ * `VectorEmbeddings`. Override per call via `runModel` for a different embedding model.
14
+ */
15
+ const DEFAULT_EMBEDDING_MODEL = "@cf/baai/bge-m3";
16
+ /** The default image-to-text (vision) model used by `analyzeImage`. */
17
+ const DEFAULT_IMAGE_TO_TEXT_MODEL = "@cf/llava-hf/llava-1.5-7b-hf";
18
+ /**
19
+ * The embeddings payload Cloudflare's text-embedding models return: a `shape` describing the
20
+ * `[count, dimensions]` of the result and a `data` array of one vector per input. Generic — this
21
+ * is the raw CF shape, carrying no application meaning, so callers can store or query it directly.
22
+ */
23
+ const VectorEmbeddings = z.object({
24
+ shape: z.array(z.number()).describe("The result shape as [count, dimensions]."),
25
+ data: z.array(z.array(z.number())).describe("One embedding vector per input text.")
26
+ }).describe("A Cloudflare text-embedding result: vector shape plus one embedding per input.");
27
+ /**
28
+ * The text-generation payload Cloudflare's instruct models return over the REST API: the generated
29
+ * text plus optional usage. Generic — no application-specific post-processing.
30
+ */
31
+ /**
32
+ * A text-generation result, normalized to `{ response }` whichever envelope the model returned.
33
+ *
34
+ * Workers AI answers in two shapes and which one you get depends on the model, not on the request.
35
+ * Older models (`@cf/meta/llama-3.1-8b-instruct`) return a flat `{ response }`. Newer ones — including
36
+ * the default `@cf/meta/llama-4-scout-17b-16e-instruct` — return the OpenAI chat-completion envelope
37
+ * with the text at `choices[0].message.content` and **no** top-level `response` at all. Verified live
38
+ * on 2026-07-29; llama-3.1 currently returns both, so the flat arm is matched first.
39
+ *
40
+ * Accepting both and normalizing keeps `generateText`'s contract stable across a model swap, which is
41
+ * a per-call option — a caller overriding `model` should not have to know which era it belongs to.
42
+ */
43
+ const FlatTextGeneration = z.object({ response: z.string().describe("The generated text, on the flat legacy envelope.") }).describe("The flat text-generation envelope older Workers AI models return.");
44
+ const ChatCompletionText = z.object({ choices: z.array(z.object({ message: z.object({ content: z.string().describe("The generated text for this choice.") }).describe("The assistant message this choice carries.") }).describe("One completion choice.")).min(1).describe("The completions the model returned; the first is the answer.") }).describe("The OpenAI-compatible chat-completion envelope newer Workers AI models return.");
45
+ const TextGeneration = z.union([FlatTextGeneration, ChatCompletionText]).describe("Either envelope, before normalization: the flat legacy one, or the OpenAI-compatible one.").transform((value, ctx) => {
46
+ if ("response" in value) return { response: value.response };
47
+ const first = value.choices[0];
48
+ if (!first) {
49
+ ctx.addIssue({
50
+ code: "custom",
51
+ message: "The chat-completion envelope carried no choices."
52
+ });
53
+ return z.NEVER;
54
+ }
55
+ return { response: first.message.content };
56
+ }).describe("A Cloudflare text-generation result, normalized to the model's generated text.");
57
+ /**
58
+ * The image-to-text payload Cloudflare's vision models return: a textual description of the image.
59
+ */
60
+ const ImageToText = z.object({ description: z.string().describe("The model's textual description of the image.") }).describe("A Cloudflare image-to-text result: a description of the supplied image.");
61
+ const DEFAULT_IMAGE_PROMPT = "Describe this image in a concise sentence suitable for alt text.";
62
+ /**
63
+ * Out-of-Worker Workers AI access over the REST API: run any model, generate text, generate
64
+ * embeddings, analyze an image, and list models from a CLI/CI/provisioning context. Inside a
65
+ * Worker you use the `Ai` binding directly — this manager is the REST counterpart, addressed by
66
+ * account id. Every model call carries no application logic; the caller chooses the model and
67
+ * interprets the result.
68
+ */
69
+ var CloudflareAIManager = class extends CloudflareManager {
70
+ /**
71
+ * Run a Cloudflare AI model by name with an arbitrary JSON input. The single seam every typed
72
+ * helper builds on. The account id is injected for you; the rest of `input` is the model's body.
73
+ */
74
+ async runModel(model, input) {
75
+ return cloudflareRequest(`AI run model '${model}'`, () => this.getClient().ai.run(model, {
76
+ account_id: this.accountId,
77
+ ...input
78
+ }));
79
+ }
80
+ /**
81
+ * Generate text from a chat prompt. Returns the validated `{ response }` payload. A response that
82
+ * does not carry a string `response` field fails Zod and throws `cloudflare/invalid_response`.
83
+ */
84
+ async generateText(messages, options) {
85
+ const model = options?.model ?? DEFAULT_TEXT_MODEL;
86
+ const raw = await this.runModel(model, {
87
+ messages,
88
+ ...options?.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {}
89
+ });
90
+ const parsed = TextGeneration.safeParse(raw);
91
+ if (!parsed.success) throw new CloudflareInvalidResponseError({
92
+ message: "The AI text-generation response had an unexpected shape.",
93
+ detail: parsed.error.message
94
+ });
95
+ return parsed.data;
96
+ }
97
+ /**
98
+ * Generate embeddings for one or more texts. Returns the validated `{ shape, data }` payload. A
99
+ * response that does not match fails Zod and throws `cloudflare/invalid_response`.
100
+ */
101
+ async generateEmbeddings(texts, model) {
102
+ const raw = await this.runModel(model ?? DEFAULT_EMBEDDING_MODEL, { text: texts });
103
+ const parsed = VectorEmbeddings.safeParse(raw);
104
+ if (!parsed.success) throw new CloudflareInvalidResponseError({
105
+ message: "The AI embeddings response had an unexpected shape.",
106
+ detail: parsed.error.message
107
+ });
108
+ return parsed.data;
109
+ }
110
+ /**
111
+ * Describe an image with a vision model. The image is raw bytes, base64-encoded for the model
112
+ * input. Returns the validated `{ description }` payload.
113
+ */
114
+ async analyzeImage(image, options) {
115
+ const model = options?.model ?? DEFAULT_IMAGE_TO_TEXT_MODEL;
116
+ const raw = await this.runModel(model, {
117
+ image: fromUint8Array(image),
118
+ prompt: options?.prompt ?? DEFAULT_IMAGE_PROMPT,
119
+ ...options?.maxTokens !== void 0 ? { max_tokens: options.maxTokens } : {}
120
+ });
121
+ const parsed = ImageToText.safeParse(raw);
122
+ if (!parsed.success) throw new CloudflareInvalidResponseError({
123
+ message: "The AI image-to-text response had an unexpected shape.",
124
+ detail: parsed.error.message
125
+ });
126
+ return parsed.data;
127
+ }
128
+ /** List the AI models available to this account. Returns an empty array when none are present. */
129
+ async listModels() {
130
+ return cloudflareRequest("AI list models", async () => {
131
+ const page = await this.getClient().ai.models.list({ account_id: this.accountId });
132
+ return Array.isArray(page.result) ? page.result : [];
133
+ });
134
+ }
135
+ getServiceType() {
136
+ return "Workers AI";
137
+ }
138
+ /** Prove access by listing models. Never throws. */
139
+ async validateServiceAccess() {
140
+ try {
141
+ return (await this.listModels()).length > 0;
142
+ } catch {
143
+ return false;
144
+ }
145
+ }
146
+ };
147
+ //#endregion
148
+ export { CloudflareAIManager, ImageToText, TextGeneration, VectorEmbeddings };
@@ -0,0 +1,67 @@
1
+ import type { IndexDeleteByIDsResponse, IndexInfoResponse, IndexInsertResponse, IndexQueryResponse, IndexUpsertResponse } from "cloudflare/resources/vectorize/indexes/indexes";
2
+ import { CloudflareManager, type CloudflareManagerConfig } from "../client/manager";
3
+ /** Config for the Vectorize manager: the shared client config plus the index it targets. */
4
+ export interface VectorizeManagerConfig extends CloudflareManagerConfig {
5
+ /** The Vectorize index name (the REST API addresses indexes by name, not binding). */
6
+ indexName: string;
7
+ }
8
+ /** A vector to insert or upsert: an id, its float values, and optional metadata/namespace. */
9
+ export interface VectorizeVector {
10
+ /** The unique identifier for the vector. */
11
+ id: string;
12
+ /** The vector's float components. */
13
+ values: number[];
14
+ /** Arbitrary metadata stored alongside the vector. */
15
+ metadata?: Record<string, unknown>;
16
+ /** An optional namespace partitioning the index. */
17
+ namespace?: string;
18
+ }
19
+ /** Options narrowing a nearest-neighbor query. */
20
+ export interface VectorizeQueryOptions {
21
+ /** The number of nearest neighbors to return. */
22
+ topK?: number;
23
+ /** Whether to return the matched vectors' values. */
24
+ returnValues?: boolean;
25
+ /** Whether to return no, indexed, or all metadata for matches. */
26
+ returnMetadata?: "none" | "indexed" | "all";
27
+ /** A metadata filter expression limiting results. */
28
+ filter?: unknown;
29
+ }
30
+ /**
31
+ * Out-of-Worker Vectorize access over the REST API: insert/upsert vectors, query nearest
32
+ * neighbors, fetch and delete by id, and describe the index from a CLI/CI/provisioning context.
33
+ * Inside a Worker you use the `Vectorize` binding directly — this manager is the REST counterpart,
34
+ * addressed by index name.
35
+ */
36
+ export declare class CloudflareVectorizeManager extends CloudflareManager {
37
+ private readonly indexName;
38
+ constructor(config: VectorizeManagerConfig);
39
+ /** Serialize vectors as an NDJSON file, the body shape the REST insert/upsert endpoints expect. */
40
+ private vectorsToNdjsonFile;
41
+ /** Insert vectors. Returns the async-mutation id for the enqueued change. */
42
+ insert(vectors: VectorizeVector[]): Promise<IndexInsertResponse | null>;
43
+ /** Upsert vectors, overwriting any with matching ids. Returns the async-mutation id. */
44
+ upsert(vectors: VectorizeVector[]): Promise<IndexUpsertResponse | null>;
45
+ /** Query the index for the nearest neighbors of a vector. */
46
+ query(vector: number[], options?: VectorizeQueryOptions): Promise<IndexQueryResponse | null>;
47
+ /**
48
+ * Query by an existing vector's id: fetch its values, then run a nearest-neighbor query with
49
+ * them. Returns an empty result when the id is absent or has no values.
50
+ */
51
+ queryById(vectorId: string, options?: VectorizeQueryOptions): Promise<IndexQueryResponse | null>;
52
+ /** Fetch vectors by id. Returns an array (possibly empty); each element carries its values. */
53
+ getByIds(ids: string[]): Promise<VectorizeVector[]>;
54
+ /** Delete vectors by id. Returns the async-mutation id for the enqueued change. */
55
+ deleteByIds(ids: string[]): Promise<IndexDeleteByIDsResponse | null>;
56
+ /** Describe the index: dimensions, vector count, and processing watermarks. */
57
+ describe(): Promise<IndexInfoResponse | null>;
58
+ /** The index this manager targets and the account it lives in. */
59
+ getVectorizeInfo(): {
60
+ indexName: string;
61
+ accountId: string;
62
+ };
63
+ getServiceType(): string;
64
+ /** Prove access by reading the index record. Never throws. */
65
+ validateServiceAccess(): Promise<boolean>;
66
+ }
67
+ //# sourceMappingURL=vectorizeManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vectorizeManager.d.ts","sourceRoot":"","sources":["../../src/ai/vectorizeManager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,wBAAwB,EAExB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,gDAAgD,CAAC;AAExD,OAAO,EAAE,iBAAiB,EAAE,KAAK,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEpF,4FAA4F;AAC5F,MAAM,WAAW,sBAAuB,SAAQ,uBAAuB;IACrE,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8FAA8F;AAC9F,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,qCAAqC;IACrC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,kDAAkD;AAClD,MAAM,WAAW,qBAAqB;IACpC,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC;IAC5C,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,qBAAa,0BAA2B,SAAQ,iBAAiB;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,YAAY,MAAM,EAAE,sBAAsB,EAMzC;IAED,mGAAmG;IACnG,OAAO,CAAC,mBAAmB;IAK3B,6EAA6E;IACvE,MAAM,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAO5E;IAED,wFAAwF;IAClF,MAAM,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAO5E;IAED,6DAA6D;IACvD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAWjG;IAED;;;OAGG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAOrG;IAED,+FAA+F;IACzF,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAQxD;IAED,mFAAmF;IAC7E,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAOzE;IAED,+EAA+E;IACzE,QAAQ,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAIlD;IAED,kEAAkE;IAClE,gBAAgB,IAAI;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAE3D;IAED,cAAc,IAAI,MAAM,CAEvB;IAED,8DAA8D;IACxD,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;CACF"}
@@ -0,0 +1,101 @@
1
+ import { CloudflareNotConfiguredError, cloudflareRequest } from "../client/errors.js";
2
+ import { CloudflareManager } from "../client/manager.js";
3
+ //#region src/ai/vectorizeManager.ts
4
+ /**
5
+ * Out-of-Worker Vectorize access over the REST API: insert/upsert vectors, query nearest
6
+ * neighbors, fetch and delete by id, and describe the index from a CLI/CI/provisioning context.
7
+ * Inside a Worker you use the `Vectorize` binding directly — this manager is the REST counterpart,
8
+ * addressed by index name.
9
+ */
10
+ var CloudflareVectorizeManager = class extends CloudflareManager {
11
+ indexName;
12
+ constructor(config) {
13
+ super(config);
14
+ if (!config.indexName) throw new CloudflareNotConfiguredError({ detail: "Missing indexName for Vectorize REST access." });
15
+ this.indexName = config.indexName;
16
+ }
17
+ /** Serialize vectors as an NDJSON file, the body shape the REST insert/upsert endpoints expect. */
18
+ vectorsToNdjsonFile(vectors) {
19
+ const ndjson = vectors.map((vector) => JSON.stringify(vector)).join("\n");
20
+ return new File([ndjson], "vectors.ndjson", { type: "application/x-ndjson" });
21
+ }
22
+ /** Insert vectors. Returns the async-mutation id for the enqueued change. */
23
+ async insert(vectors) {
24
+ return cloudflareRequest("Vectorize insert", () => this.getClient().vectorize.indexes.insert(this.indexName, {
25
+ account_id: this.accountId,
26
+ body: this.vectorsToNdjsonFile(vectors)
27
+ }));
28
+ }
29
+ /** Upsert vectors, overwriting any with matching ids. Returns the async-mutation id. */
30
+ async upsert(vectors) {
31
+ return cloudflareRequest("Vectorize upsert", () => this.getClient().vectorize.indexes.upsert(this.indexName, {
32
+ account_id: this.accountId,
33
+ body: this.vectorsToNdjsonFile(vectors)
34
+ }));
35
+ }
36
+ /** Query the index for the nearest neighbors of a vector. */
37
+ async query(vector, options) {
38
+ return cloudflareRequest("Vectorize query", () => this.getClient().vectorize.indexes.query(this.indexName, {
39
+ account_id: this.accountId,
40
+ vector,
41
+ ...options?.topK !== void 0 ? { topK: options.topK } : {},
42
+ ...options?.returnValues !== void 0 ? { returnValues: options.returnValues } : {},
43
+ ...options?.returnMetadata !== void 0 ? { returnMetadata: options.returnMetadata } : {},
44
+ ...options?.filter !== void 0 ? { filter: options.filter } : {}
45
+ }));
46
+ }
47
+ /**
48
+ * Query by an existing vector's id: fetch its values, then run a nearest-neighbor query with
49
+ * them. Returns an empty result when the id is absent or has no values.
50
+ */
51
+ async queryById(vectorId, options) {
52
+ const first = (await this.getByIds([vectorId]))[0];
53
+ if (!first || !Array.isArray(first.values) || first.values.length === 0) return {
54
+ count: 0,
55
+ matches: []
56
+ };
57
+ return this.query(first.values, options);
58
+ }
59
+ /** Fetch vectors by id. Returns an array (possibly empty); each element carries its values. */
60
+ async getByIds(ids) {
61
+ return cloudflareRequest("Vectorize getByIds", async () => {
62
+ const response = await this.getClient().vectorize.indexes.getByIDs(this.indexName, {
63
+ account_id: this.accountId,
64
+ ids
65
+ });
66
+ return Array.isArray(response) ? response : [];
67
+ });
68
+ }
69
+ /** Delete vectors by id. Returns the async-mutation id for the enqueued change. */
70
+ async deleteByIds(ids) {
71
+ return cloudflareRequest("Vectorize deleteByIds", () => this.getClient().vectorize.indexes.deleteByIDs(this.indexName, {
72
+ account_id: this.accountId,
73
+ ids
74
+ }));
75
+ }
76
+ /** Describe the index: dimensions, vector count, and processing watermarks. */
77
+ async describe() {
78
+ return cloudflareRequest("Vectorize describe", () => this.getClient().vectorize.indexes.info(this.indexName, { account_id: this.accountId }));
79
+ }
80
+ /** The index this manager targets and the account it lives in. */
81
+ getVectorizeInfo() {
82
+ return {
83
+ indexName: this.indexName,
84
+ accountId: this.accountId
85
+ };
86
+ }
87
+ getServiceType() {
88
+ return "Vectorize";
89
+ }
90
+ /** Prove access by reading the index record. Never throws. */
91
+ async validateServiceAccess() {
92
+ try {
93
+ await this.getClient().vectorize.indexes.get(this.indexName, { account_id: this.accountId });
94
+ return true;
95
+ } catch {
96
+ return false;
97
+ }
98
+ }
99
+ };
100
+ //#endregion
101
+ export { CloudflareVectorizeManager };
@@ -0,0 +1,123 @@
1
+ import { z } from "zod";
2
+ import { CloudflareManager } from "../client/manager";
3
+ /** The distance metric an index scores nearest neighbors with. Fixed at creation — it cannot be changed later. */
4
+ export declare const VectorizeMetric: z.ZodEnum<{
5
+ cosine: "cosine";
6
+ "dot-product": "dot-product";
7
+ euclidean: "euclidean";
8
+ }>;
9
+ export type VectorizeMetric = z.infer<typeof VectorizeMetric>;
10
+ /**
11
+ * A Cloudflare-managed embedding preset. Naming one lets Cloudflare pick the dimensions and metric that
12
+ * match the model, so an index and the model that fills it cannot drift apart.
13
+ */
14
+ export declare const VectorizePreset: z.ZodEnum<{
15
+ "@cf/baai/bge-base-en-v1.5": "@cf/baai/bge-base-en-v1.5";
16
+ "@cf/baai/bge-large-en-v1.5": "@cf/baai/bge-large-en-v1.5";
17
+ "@cf/baai/bge-small-en-v1.5": "@cf/baai/bge-small-en-v1.5";
18
+ "cohere/embed-multilingual-v2.0": "cohere/embed-multilingual-v2.0";
19
+ "openai/text-embedding-ada-002": "openai/text-embedding-ada-002";
20
+ }>;
21
+ export type VectorizePreset = z.infer<typeof VectorizePreset>;
22
+ /** The shape of the vectors an index holds: how many components each carries, and how they are compared. */
23
+ export declare const VectorizeIndexConfig: z.ZodObject<{
24
+ dimensions: z.ZodNumber;
25
+ metric: z.ZodEnum<{
26
+ cosine: "cosine";
27
+ "dot-product": "dot-product";
28
+ euclidean: "euclidean";
29
+ }>;
30
+ }, z.core.$strip>;
31
+ export type VectorizeIndexConfig = z.output<typeof VectorizeIndexConfig>;
32
+ /** A Vectorize index's identity and shape, decoded from the create/get/list responses. */
33
+ export declare const VectorizeIndexInfo: z.ZodObject<{
34
+ name: z.ZodString;
35
+ config: z.ZodObject<{
36
+ dimensions: z.ZodNumber;
37
+ metric: z.ZodEnum<{
38
+ cosine: "cosine";
39
+ "dot-product": "dot-product";
40
+ euclidean: "euclidean";
41
+ }>;
42
+ }, z.core.$strip>;
43
+ description: z.ZodOptional<z.ZodString>;
44
+ }, z.core.$strip>;
45
+ export type VectorizeIndexInfo = z.output<typeof VectorizeIndexInfo>;
46
+ /** The type of a metadata property an index can filter on. Chosen per property when the metadata index is created. */
47
+ export declare const VectorizeMetadataIndexType: z.ZodEnum<{
48
+ boolean: "boolean";
49
+ number: "number";
50
+ string: "string";
51
+ }>;
52
+ export type VectorizeMetadataIndexType = z.infer<typeof VectorizeMetadataIndexType>;
53
+ /** One indexed metadata property on a Vectorize index — the unit that makes a metadata filter possible. */
54
+ export declare const VectorizeMetadataIndex: z.ZodObject<{
55
+ propertyName: z.ZodString;
56
+ indexType: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodEnum<{
57
+ boolean: "boolean";
58
+ number: "number";
59
+ string: "string";
60
+ }>>;
61
+ }, z.core.$strip>;
62
+ export type VectorizeMetadataIndex = z.output<typeof VectorizeMetadataIndex>;
63
+ /**
64
+ * How a new index is shaped: either an explicit dimensions/metric pair, or a Cloudflare embedding preset
65
+ * that resolves to one. Both are modeled because a caller that owns its embedding model wants the explicit
66
+ * pair, while a caller using a stock Cloudflare model is better served by the preset — naming the model once
67
+ * instead of restating its dimensions and risking a mismatch.
68
+ */
69
+ export type VectorizeIndexSpec = {
70
+ dimensions: number;
71
+ metric: VectorizeMetric;
72
+ } | {
73
+ preset: VectorizePreset;
74
+ };
75
+ /** Options a new index accepts beyond its name and shape. */
76
+ export interface CreateVectorizeIndexOptions {
77
+ /** A human description stored on the index, surfaced in the Cloudflare dashboard. */
78
+ description?: string;
79
+ }
80
+ /**
81
+ * Account-level Vectorize control plane: **create and delete indexes, and manage their metadata indexes**.
82
+ * `pithy vector provision` uses this to stand up a per-environment index and declare which metadata
83
+ * properties are filterable; teardown uses it to remove them. Unlike {@link CloudflareVectorizeManager},
84
+ * which operates *within* one already-provisioned index (insert/query/delete vectors), this manager is
85
+ * account-scoped and addresses indexes **by name** — Vectorize indexes carry no separate uuid id.
86
+ *
87
+ * Every mutation here is enqueued: Vectorize applies index and metadata-index changes asynchronously, so a
88
+ * successful call means "accepted", not "visible". Poll {@link listMetadataIndexes} or the data-plane
89
+ * `describe()` watermarks rather than writing and immediately reading back.
90
+ */
91
+ export declare class CloudflareVectorizeProvisioner extends CloudflareManager {
92
+ getServiceType(): string;
93
+ /** Prove access by listing indexes — a read, never a destructive create/delete. Never throws. */
94
+ validateServiceAccess(): Promise<boolean>;
95
+ /** Create a Vectorize index by name with an explicit dimensions/metric pair or a Cloudflare preset. */
96
+ createIndex(name: string, config: VectorizeIndexSpec, options?: CreateVectorizeIndexOptions): Promise<VectorizeIndexInfo>;
97
+ /** Delete a Vectorize index by name. Idempotent — a missing index is not an error, so teardown can re-run safely. */
98
+ deleteIndex(name: string): Promise<void>;
99
+ /** List every Vectorize index in the account — for prefix-scan reconcile teardown and drift checks. */
100
+ listIndexes(): Promise<VectorizeIndexInfo[]>;
101
+ /**
102
+ * Find an index by exact name, or `null` — for idempotent provisioning. Reads the one index rather than
103
+ * draining the account list, because a Vectorize index's name *is* its address (unlike a KV namespace,
104
+ * whose title is not addressable). A 404 — or a 410 for a deleted one — means absent, which is an answer,
105
+ * not a failure.
106
+ */
107
+ findIndexByName(name: string): Promise<VectorizeIndexInfo | null>;
108
+ /**
109
+ * Make a metadata property filterable. Cloudflare caps an index at 10 indexed properties, and only vectors
110
+ * written **after** the metadata index exists are covered — so declare these before the first insert.
111
+ * The change is enqueued asynchronously; the returned promise resolving means accepted, not live.
112
+ */
113
+ createMetadataIndex(indexName: string, propertyName: string, indexType: VectorizeMetadataIndexType): Promise<void>;
114
+ /** List an index's indexed metadata properties — the read that proves a `createMetadataIndex` has landed. */
115
+ listMetadataIndexes(indexName: string): Promise<VectorizeMetadataIndex[]>;
116
+ /**
117
+ * Stop filtering on a metadata property. Idempotent — a missing metadata index is not an error, matching
118
+ * {@link deleteIndex} so teardown can re-run safely. Absence here is `400`/40005, not `404`, which is why
119
+ * this uses {@link isAbsentMetadataIndexError} rather than the plain not-found check.
120
+ */
121
+ deleteMetadataIndex(indexName: string, propertyName: string): Promise<void>;
122
+ }
123
+ //# sourceMappingURL=vectorizeProvisioner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vectorizeProvisioner.d.ts","sourceRoot":"","sources":["../../src/ai/vectorizeProvisioner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,kHAAkH;AAClH,eAAO,MAAM,eAAe;;;;EAEgF,CAAC;AAC7G,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;EAQiF,CAAC;AAC9G,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,4GAA4G;AAC5G,eAAO,MAAM,oBAAoB;;;;;;;iBAS2E,CAAC;AAC7G,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEzE,0FAA0F;AAC1F,eAAO,MAAM,kBAAkB;;;;;;;;;;;iBAMqF,CAAC;AACrH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAErE,sHAAsH;AACtH,eAAO,MAAM,0BAA0B;;;;EAEqE,CAAC;AAC7G,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAiBpF,2GAA2G;AAC3G,eAAO,MAAM,sBAAsB;;;;;;;iBAK+E,CAAC;AACnH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC;AAuC/G,6DAA6D;AAC7D,MAAM,WAAW,2BAA2B;IAC1C,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,8BAA+B,SAAQ,iBAAiB;IACnE,cAAc,IAAI,MAAM,CAEvB;IAED,iGAAiG;IAC3F,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;IAED,uGAAuG;IACjG,WAAW,CACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,kBAAkB,CAAC,CAU7B;IAED,qHAAqH;IAC/G,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS7C;IAED,uGAAuG;IACjG,WAAW,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAQjD;IAED;;;;;OAKG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAUtE;IAED;;;;OAIG;IACG,mBAAmB,CACvB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,0BAA0B,GACpC,OAAO,CAAC,IAAI,CAAC,CAQf;IAED,6GAA6G;IACvG,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAS9E;IAED;;;;OAIG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhF;CACF"}