@use-lattice/litmus 0.121.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 (199) hide show
  1. package/LICENSE +19 -0
  2. package/dist/src/accounts-Bt1oJb1Z.cjs +219 -0
  3. package/dist/src/accounts-DjOU8Rm3.js +178 -0
  4. package/dist/src/agentic-utils-D03IiXQc.js +153 -0
  5. package/dist/src/agentic-utils-Dh7xaMQM.cjs +180 -0
  6. package/dist/src/agents-C6BIMlZa.js +231 -0
  7. package/dist/src/agents-DvIpNX1L.cjs +666 -0
  8. package/dist/src/agents-ZP0RP9vV.cjs +231 -0
  9. package/dist/src/agents-maJXdjbR.js +665 -0
  10. package/dist/src/aimlapi-BTbQjG2E.cjs +30 -0
  11. package/dist/src/aimlapi-CwMxqfXP.js +30 -0
  12. package/dist/src/audio-BBUdvsde.cjs +97 -0
  13. package/dist/src/audio-D5DPZ7I-.js +97 -0
  14. package/dist/src/base-BEysXrkq.cjs +222 -0
  15. package/dist/src/base-C451JQfq.js +193 -0
  16. package/dist/src/blobs-BY8MDmpo.js +230 -0
  17. package/dist/src/blobs-BgcNn97m.cjs +256 -0
  18. package/dist/src/cache-BBE_lsTA.cjs +4 -0
  19. package/dist/src/cache-BkrqU5Ba.js +237 -0
  20. package/dist/src/cache-DsCxFlsZ.cjs +297 -0
  21. package/dist/src/chat-CPJWDP6a.cjs +289 -0
  22. package/dist/src/chat-CXX3xzkk.cjs +811 -0
  23. package/dist/src/chat-CcDgZFJ4.js +787 -0
  24. package/dist/src/chat-Dz5ZeGO2.js +289 -0
  25. package/dist/src/chatkit-Dw0mKkML.cjs +1158 -0
  26. package/dist/src/chatkit-swAIVuea.js +1157 -0
  27. package/dist/src/chunk-DEq-mXcV.js +15 -0
  28. package/dist/src/claude-agent-sdk-BXZJtOg6.js +379 -0
  29. package/dist/src/claude-agent-sdk-CkfyjDoG.cjs +383 -0
  30. package/dist/src/cloudflare-ai-BzpJcqUH.js +161 -0
  31. package/dist/src/cloudflare-ai-Cmy_R1y2.cjs +161 -0
  32. package/dist/src/cloudflare-gateway-B9tVQKok.cjs +272 -0
  33. package/dist/src/cloudflare-gateway-DrD3ew3H.js +272 -0
  34. package/dist/src/codex-sdk-Dezj9Nwm.js +1056 -0
  35. package/dist/src/codex-sdk-Dl9D4k5B.cjs +1060 -0
  36. package/dist/src/cometapi-C-9YvCHC.js +54 -0
  37. package/dist/src/cometapi-DHgDKoO2.cjs +54 -0
  38. package/dist/src/completion-B8Ctyxpr.js +120 -0
  39. package/dist/src/completion-Cxrt08sj.cjs +131 -0
  40. package/dist/src/createHash-BwgE13yv.cjs +27 -0
  41. package/dist/src/createHash-DmPQkvBh.js +15 -0
  42. package/dist/src/docker-BiqcTwLv.js +80 -0
  43. package/dist/src/docker-C7tEJnP-.cjs +80 -0
  44. package/dist/src/esm-C62Zofr1.cjs +409 -0
  45. package/dist/src/esm-DMVc93eh.js +379 -0
  46. package/dist/src/evalResult-C3NJPQOo.cjs +301 -0
  47. package/dist/src/evalResult-C7JJAPBb.js +295 -0
  48. package/dist/src/evalResult-DoVTZZWI.cjs +2 -0
  49. package/dist/src/extractor-DnMD3fwt.cjs +391 -0
  50. package/dist/src/extractor-DtlL28vL.js +374 -0
  51. package/dist/src/fetch-BTxakTSg.cjs +1133 -0
  52. package/dist/src/fetch-DQckpUFz.js +928 -0
  53. package/dist/src/fileExtensions-DnqA1y9x.js +85 -0
  54. package/dist/src/fileExtensions-bYh77CN8.cjs +114 -0
  55. package/dist/src/genaiTracer-CyZrmaK0.cjs +268 -0
  56. package/dist/src/genaiTracer-D3fD9dNV.js +256 -0
  57. package/dist/src/graders-BNscxFrU.js +13644 -0
  58. package/dist/src/graders-D2oE9Msq.js +2 -0
  59. package/dist/src/graders-c0Ez_w-9.cjs +2 -0
  60. package/dist/src/graders-d0F2M3e9.cjs +14056 -0
  61. package/dist/src/image-0ZhE0VlR.cjs +280 -0
  62. package/dist/src/image-CWE1pdNv.js +257 -0
  63. package/dist/src/image-D9ZK6hwL.js +163 -0
  64. package/dist/src/image-DKZgZITg.cjs +163 -0
  65. package/dist/src/index.cjs +11366 -0
  66. package/dist/src/index.d.cts +19640 -0
  67. package/dist/src/index.d.ts +19641 -0
  68. package/dist/src/index.js +11306 -0
  69. package/dist/src/invariant-Ddh24eXh.js +25 -0
  70. package/dist/src/invariant-kfQ8Bu82.cjs +30 -0
  71. package/dist/src/knowledgeBase-BgPyGFUd.cjs +122 -0
  72. package/dist/src/knowledgeBase-DyHilYaP.js +122 -0
  73. package/dist/src/litellm-CyMeneHS.js +135 -0
  74. package/dist/src/litellm-DWDF73yF.cjs +135 -0
  75. package/dist/src/logger-C40ZGil9.js +717 -0
  76. package/dist/src/logger-DyfK9PBt.cjs +917 -0
  77. package/dist/src/luma-ray-BAU9X_ep.cjs +315 -0
  78. package/dist/src/luma-ray-nwVseBbv.js +313 -0
  79. package/dist/src/messages-B5ADWTTv.js +245 -0
  80. package/dist/src/messages-BCnZfqrS.cjs +257 -0
  81. package/dist/src/meteor-DLZZ3osF.cjs +134 -0
  82. package/dist/src/meteor-DUiCJRC-.js +134 -0
  83. package/dist/src/modelslab-00cveB8L.cjs +163 -0
  84. package/dist/src/modelslab-D9sCU_L7.js +163 -0
  85. package/dist/src/nova-reel-CTapvqYH.js +276 -0
  86. package/dist/src/nova-reel-DlWuuroF.cjs +278 -0
  87. package/dist/src/nova-sonic-5UPWfeMv.cjs +363 -0
  88. package/dist/src/nova-sonic-BhSwQNym.js +363 -0
  89. package/dist/src/openai-BWrJK9d8.cjs +52 -0
  90. package/dist/src/openai-DumO8WQn.js +47 -0
  91. package/dist/src/openclaw-B8brrjC_.cjs +577 -0
  92. package/dist/src/openclaw-Bkayww9q.js +571 -0
  93. package/dist/src/opencode-sdk-7xjoDNiM.cjs +562 -0
  94. package/dist/src/opencode-sdk-SGwAPxht.js +558 -0
  95. package/dist/src/otlpReceiver-CoAHfAN9.cjs +15 -0
  96. package/dist/src/otlpReceiver-oO3EQwI9.js +14 -0
  97. package/dist/src/providerRegistry-4yjhaEM8.js +45 -0
  98. package/dist/src/providerRegistry-DhV4rJIc.cjs +50 -0
  99. package/dist/src/providers-B5RJVG-7.cjs +33609 -0
  100. package/dist/src/providers-BdmZCLzV.js +33262 -0
  101. package/dist/src/providers-CxtRxn8e.js +2 -0
  102. package/dist/src/providers-DnQLNbx1.cjs +3 -0
  103. package/dist/src/pythonUtils-BD0druiM.cjs +275 -0
  104. package/dist/src/pythonUtils-IBhn5YGR.js +249 -0
  105. package/dist/src/quiverai-BDOwZBsM.cjs +213 -0
  106. package/dist/src/quiverai-D3JTF5lD.js +213 -0
  107. package/dist/src/responses-B2LCDCXZ.js +667 -0
  108. package/dist/src/responses-BvNm4Xv9.cjs +685 -0
  109. package/dist/src/rubyUtils-B0NwnfpY.cjs +245 -0
  110. package/dist/src/rubyUtils-BroxzZ7c.cjs +2 -0
  111. package/dist/src/rubyUtils-hqVw5UvJ.js +222 -0
  112. package/dist/src/sagemaker-Cno2V-Sx.js +689 -0
  113. package/dist/src/sagemaker-fV_KUgs5.cjs +691 -0
  114. package/dist/src/server-BOuAXb06.cjs +238 -0
  115. package/dist/src/server-CtI-EWzm.cjs +2 -0
  116. package/dist/src/server-Cy3DZymt.js +189 -0
  117. package/dist/src/slack-CP8xBePa.js +135 -0
  118. package/dist/src/slack-DSQ1yXVb.cjs +135 -0
  119. package/dist/src/store-BwDDaBjb.cjs +246 -0
  120. package/dist/src/store-DcbLC593.cjs +2 -0
  121. package/dist/src/store-IGpqMIkv.js +240 -0
  122. package/dist/src/tables-3Q2cL7So.cjs +373 -0
  123. package/dist/src/tables-Bi2fjr4W.js +288 -0
  124. package/dist/src/telemetry-Bg2WqF79.js +161 -0
  125. package/dist/src/telemetry-D0x6u5kX.cjs +166 -0
  126. package/dist/src/telemetry-DXNimrI0.cjs +2 -0
  127. package/dist/src/text-B_UCRPp2.js +22 -0
  128. package/dist/src/text-CW1cyrwj.cjs +33 -0
  129. package/dist/src/tokenUsageUtils-NYT-WKS6.js +138 -0
  130. package/dist/src/tokenUsageUtils-bVa1ga6f.cjs +173 -0
  131. package/dist/src/transcription-Cl_W16Pr.js +122 -0
  132. package/dist/src/transcription-yt1EecY8.cjs +124 -0
  133. package/dist/src/transform-BCtGrl_W.cjs +228 -0
  134. package/dist/src/transform-Bv6gG2MJ.cjs +1688 -0
  135. package/dist/src/transform-CY1wbpRy.js +1507 -0
  136. package/dist/src/transform-DU8rUL9P.cjs +2 -0
  137. package/dist/src/transform-yWaShiKr.js +216 -0
  138. package/dist/src/transformersAvailability-BGkzavwb.js +35 -0
  139. package/dist/src/transformersAvailability-DKoRtQLy.cjs +35 -0
  140. package/dist/src/types-5aqHpBwE.cjs +3769 -0
  141. package/dist/src/types-Bn6D9c4U.js +3300 -0
  142. package/dist/src/util-BkKlTkI2.js +293 -0
  143. package/dist/src/util-CTh0bfOm.cjs +1119 -0
  144. package/dist/src/util-D17oBwo7.cjs +328 -0
  145. package/dist/src/util-DsS_-v4p.js +613 -0
  146. package/dist/src/util-DuntT1Ga.js +951 -0
  147. package/dist/src/util-aWjdCYMI.cjs +667 -0
  148. package/dist/src/utils-CisQwpjA.js +94 -0
  149. package/dist/src/utils-yWamDvmz.cjs +123 -0
  150. package/dist/tsconfig.tsbuildinfo +1 -0
  151. package/drizzle/0000_lush_hellion.sql +36 -0
  152. package/drizzle/0001_wide_calypso.sql +3 -0
  153. package/drizzle/0002_tidy_juggernaut.sql +1 -0
  154. package/drizzle/0003_lively_naoko.sql +8 -0
  155. package/drizzle/0004_minor_peter_quill.sql +19 -0
  156. package/drizzle/0005_silky_millenium_guard.sql +2 -0
  157. package/drizzle/0006_harsh_caretaker.sql +42 -0
  158. package/drizzle/0007_cloudy_wong.sql +1 -0
  159. package/drizzle/0008_broad_boomer.sql +2 -0
  160. package/drizzle/0009_strong_marten_broadcloak.sql +19 -0
  161. package/drizzle/0010_needy_bishop.sql +11 -0
  162. package/drizzle/0011_moaning_millenium_guard.sql +1 -0
  163. package/drizzle/0012_late_marten_broadcloak.sql +2 -0
  164. package/drizzle/0013_previous_dormammu.sql +9 -0
  165. package/drizzle/0014_lazy_captain_universe.sql +2 -0
  166. package/drizzle/0015_zippy_wallop.sql +29 -0
  167. package/drizzle/0016_jazzy_zemo.sql +2 -0
  168. package/drizzle/0017_reflective_praxagora.sql +4 -0
  169. package/drizzle/0018_fat_vanisher.sql +22 -0
  170. package/drizzle/0019_new_clint_barton.sql +8 -0
  171. package/drizzle/0020_skinny_maverick.sql +1 -0
  172. package/drizzle/0021_mysterious_madelyne_pryor.sql +13 -0
  173. package/drizzle/0022_sleepy_ultimo.sql +25 -0
  174. package/drizzle/0023_wooden_mandrill.sql +2 -0
  175. package/drizzle/AGENTS.md +68 -0
  176. package/drizzle/CLAUDE.md +1 -0
  177. package/drizzle/meta/0000_snapshot.json +221 -0
  178. package/drizzle/meta/0001_snapshot.json +214 -0
  179. package/drizzle/meta/0002_snapshot.json +221 -0
  180. package/drizzle/meta/0005_snapshot.json +369 -0
  181. package/drizzle/meta/0006_snapshot.json +638 -0
  182. package/drizzle/meta/0007_snapshot.json +640 -0
  183. package/drizzle/meta/0008_snapshot.json +649 -0
  184. package/drizzle/meta/0009_snapshot.json +554 -0
  185. package/drizzle/meta/0010_snapshot.json +619 -0
  186. package/drizzle/meta/0011_snapshot.json +627 -0
  187. package/drizzle/meta/0012_snapshot.json +639 -0
  188. package/drizzle/meta/0013_snapshot.json +717 -0
  189. package/drizzle/meta/0014_snapshot.json +717 -0
  190. package/drizzle/meta/0015_snapshot.json +897 -0
  191. package/drizzle/meta/0016_snapshot.json +1031 -0
  192. package/drizzle/meta/0018_snapshot.json +1210 -0
  193. package/drizzle/meta/0019_snapshot.json +1165 -0
  194. package/drizzle/meta/0020_snapshot.json +1232 -0
  195. package/drizzle/meta/0021_snapshot.json +1311 -0
  196. package/drizzle/meta/0022_snapshot.json +1481 -0
  197. package/drizzle/meta/0023_snapshot.json +1496 -0
  198. package/drizzle/meta/_journal.json +174 -0
  199. package/package.json +240 -0
@@ -0,0 +1,213 @@
1
+ const require_logger = require("./logger-DyfK9PBt.cjs");
2
+ const require_fetch = require("./fetch-BTxakTSg.cjs");
3
+ const require_cache = require("./cache-DsCxFlsZ.cjs");
4
+ //#region src/providers/quiverai.ts
5
+ const QUIVERAI_API_BASE_URL = "https://api.quiver.ai/v1";
6
+ const QUIVERAI_DEFAULT_MODEL = "arrow-preview";
7
+ /**
8
+ * QuiverAI provider for SVG vector graphics generation using the Arrow model.
9
+ * Uses QuiverAI's native SVG generation API (POST /v1/svgs/generations).
10
+ * Streams by default for faster time-to-first-token.
11
+ */
12
+ var QuiverAiProvider = class {
13
+ config;
14
+ modelName;
15
+ apiKey;
16
+ apiBaseUrl;
17
+ constructor(modelName, options = {}) {
18
+ const { config, id, env } = options;
19
+ this.modelName = modelName;
20
+ this.apiKey = config?.apiKey || env?.QUIVERAI_API_KEY || require_logger.getEnvString("QUIVERAI_API_KEY") || "";
21
+ this.apiBaseUrl = config?.apiBaseUrl || QUIVERAI_API_BASE_URL;
22
+ if (id) this.id = () => id;
23
+ this.config = config || {};
24
+ }
25
+ id() {
26
+ return `quiverai:${this.modelName}`;
27
+ }
28
+ toString() {
29
+ return `[QuiverAI Provider ${this.modelName}]`;
30
+ }
31
+ getApiUrl() {
32
+ return `${this.apiBaseUrl}/svgs/generations`;
33
+ }
34
+ getHeaders() {
35
+ return {
36
+ "Content-Type": "application/json",
37
+ Authorization: `Bearer ${this.apiKey}`
38
+ };
39
+ }
40
+ async callApi(prompt, context) {
41
+ if (!this.apiKey) return { error: "QuiverAI API key is not set. Set the QUIVERAI_API_KEY environment variable or add apiKey to the provider config. Get a key at https://app.quiver.ai/settings/api-keys" };
42
+ const config = {
43
+ ...this.config,
44
+ ...context?.prompt?.config
45
+ };
46
+ const useStream = config.stream !== false;
47
+ const body = {
48
+ model: this.modelName,
49
+ prompt,
50
+ stream: useStream,
51
+ ...pickDefined(config, [
52
+ "instructions",
53
+ "references",
54
+ "n",
55
+ "temperature",
56
+ "top_p",
57
+ "presence_penalty",
58
+ "max_output_tokens"
59
+ ])
60
+ };
61
+ try {
62
+ if (useStream) return await this.callApiStreaming(body);
63
+ return await this.callApiNonStreaming(body, context);
64
+ } catch (error) {
65
+ require_logger.logger.error(`QuiverAI API call error: ${error}`);
66
+ return { error: `QuiverAI API call error: ${error}` };
67
+ }
68
+ }
69
+ async callApiNonStreaming(body, context) {
70
+ const { data, cached, status, statusText } = await require_cache.fetchWithCache(this.getApiUrl(), {
71
+ method: "POST",
72
+ headers: this.getHeaders(),
73
+ body: JSON.stringify(body)
74
+ }, require_fetch.REQUEST_TIMEOUT_MS, "json", context?.bustCache ?? context?.debug);
75
+ if (status < 200 || status >= 300) {
76
+ if (data && typeof data === "object" && "code" in data && "message" in data) return { error: formatError(data) };
77
+ return { error: `API error: ${status} ${statusText}\n${typeof data === "string" ? data : JSON.stringify(data)}` };
78
+ }
79
+ const response = data;
80
+ return {
81
+ cached,
82
+ output: extractSvgOutput(response),
83
+ tokenUsage: mapTokenUsage(response.usage, cached ? 0 : 1)
84
+ };
85
+ }
86
+ async callApiStreaming(body) {
87
+ const maxRetries = 3;
88
+ let lastResp;
89
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
90
+ const controller = new AbortController();
91
+ const timeout = setTimeout(() => controller.abort(), require_fetch.REQUEST_TIMEOUT_MS);
92
+ let reader;
93
+ try {
94
+ lastResp = await require_fetch.fetchWithProxy(this.getApiUrl(), {
95
+ method: "POST",
96
+ headers: this.getHeaders(),
97
+ body: JSON.stringify(body),
98
+ signal: controller.signal
99
+ });
100
+ if (lastResp.status === 429 && attempt < maxRetries) {
101
+ const waitMs = getRetryAfterMs(lastResp.headers, attempt);
102
+ require_logger.logger.debug(`QuiverAI: rate limited, retry ${attempt + 1}/${maxRetries} in ${waitMs}ms`);
103
+ await lastResp.body?.cancel();
104
+ await new Promise((resolve) => setTimeout(resolve, waitMs));
105
+ continue;
106
+ }
107
+ if (!lastResp.ok) return await handleStreamingError(lastResp);
108
+ if (!lastResp.body) return { error: "QuiverAI streaming response has no body" };
109
+ reader = lastResp.body.getReader();
110
+ return await readSSEStream(reader);
111
+ } finally {
112
+ reader?.cancel().catch(() => {});
113
+ clearTimeout(timeout);
114
+ }
115
+ }
116
+ return handleStreamingError(lastResp);
117
+ }
118
+ };
119
+ async function handleStreamingError(resp) {
120
+ try {
121
+ return { error: formatError(await resp.json()) };
122
+ } catch {
123
+ return { error: `QuiverAI API error: HTTP ${resp.status}` };
124
+ }
125
+ }
126
+ async function readSSEStream(reader) {
127
+ const decoder = new TextDecoder();
128
+ let buffer = "";
129
+ let finalSvg = "";
130
+ let usage;
131
+ while (true) {
132
+ const { done, value } = await reader.read();
133
+ if (done) break;
134
+ buffer += decoder.decode(value, { stream: true });
135
+ const lines = buffer.split("\n");
136
+ buffer = lines.pop() || "";
137
+ for (const line of lines) {
138
+ const parsed = parseSSELine(line);
139
+ if (parsed.svg) finalSvg = parsed.svg;
140
+ if (parsed.usage) usage = parsed.usage;
141
+ }
142
+ }
143
+ if (buffer.trim()) {
144
+ const parsed = parseSSELine(buffer);
145
+ if (parsed.svg) finalSvg = parsed.svg;
146
+ if (parsed.usage) usage = parsed.usage;
147
+ }
148
+ if (!finalSvg) return { error: "QuiverAI streaming response contained no SVG content" };
149
+ return {
150
+ output: finalSvg,
151
+ tokenUsage: mapTokenUsage(usage, 1)
152
+ };
153
+ }
154
+ function pickDefined(obj, keys) {
155
+ return Object.fromEntries(keys.filter((k) => obj[k] != null).map((k) => [k, obj[k]]));
156
+ }
157
+ function formatError(err) {
158
+ const base = `${err.message} [${err.code}]`;
159
+ return err.request_id ? `${base} (request_id: ${err.request_id})` : base;
160
+ }
161
+ function mapTokenUsage(usage, numRequests) {
162
+ return {
163
+ total: usage?.total_tokens || 0,
164
+ prompt: usage?.input_tokens || 0,
165
+ completion: usage?.output_tokens || 0,
166
+ numRequests
167
+ };
168
+ }
169
+ const MAX_RETRY_AFTER_MS = 6e4;
170
+ function getRetryAfterMs(headers, attempt) {
171
+ const retryAfter = headers.get("retry-after");
172
+ if (retryAfter) {
173
+ const seconds = Number(retryAfter);
174
+ if (!Number.isNaN(seconds)) return Math.min(seconds * 1e3, MAX_RETRY_AFTER_MS);
175
+ const date = new Date(retryAfter);
176
+ if (!Number.isNaN(date.getTime())) return Math.min(Math.max(0, date.getTime() - Date.now()), MAX_RETRY_AFTER_MS);
177
+ }
178
+ return Math.pow(2, attempt) * 1e3;
179
+ }
180
+ function parseSSELine(line) {
181
+ if (!line.startsWith("data:")) return {};
182
+ const payload = line.slice(line.startsWith("data: ") ? 6 : 5).trim();
183
+ if (!payload || payload === "[DONE]") return {};
184
+ try {
185
+ const event = JSON.parse(payload);
186
+ return {
187
+ svg: event.type === "content" && event.svg ? event.svg : void 0,
188
+ usage: event.usage
189
+ };
190
+ } catch {
191
+ require_logger.logger.debug(`QuiverAI: failed to parse SSE data: ${payload}`);
192
+ return {};
193
+ }
194
+ }
195
+ function extractSvgOutput(response) {
196
+ if (Array.isArray(response.data)) {
197
+ const svgs = response.data.map((item) => item.svg).filter(Boolean);
198
+ return svgs.length === 1 ? svgs[0] : svgs.join("\n\n");
199
+ }
200
+ return JSON.stringify(response);
201
+ }
202
+ function createQuiverAiProvider(providerPath, providerOptions = {}, env) {
203
+ const splits = providerPath.split(":");
204
+ return new QuiverAiProvider((splits[1] === "chat" ? splits.slice(2) : splits.slice(1)).join(":") || QUIVERAI_DEFAULT_MODEL, {
205
+ config: providerOptions.config,
206
+ id: providerOptions.id,
207
+ env: providerOptions.env ?? env
208
+ });
209
+ }
210
+ //#endregion
211
+ exports.createQuiverAiProvider = createQuiverAiProvider;
212
+
213
+ //# sourceMappingURL=quiverai-BDOwZBsM.cjs.map
@@ -0,0 +1,213 @@
1
+ import { r as logger, x as getEnvString } from "./logger-C40ZGil9.js";
2
+ import { h as REQUEST_TIMEOUT_MS, t as fetchWithProxy } from "./fetch-DQckpUFz.js";
3
+ import { r as fetchWithCache } from "./cache-BkrqU5Ba.js";
4
+ //#region src/providers/quiverai.ts
5
+ const QUIVERAI_API_BASE_URL = "https://api.quiver.ai/v1";
6
+ const QUIVERAI_DEFAULT_MODEL = "arrow-preview";
7
+ /**
8
+ * QuiverAI provider for SVG vector graphics generation using the Arrow model.
9
+ * Uses QuiverAI's native SVG generation API (POST /v1/svgs/generations).
10
+ * Streams by default for faster time-to-first-token.
11
+ */
12
+ var QuiverAiProvider = class {
13
+ config;
14
+ modelName;
15
+ apiKey;
16
+ apiBaseUrl;
17
+ constructor(modelName, options = {}) {
18
+ const { config, id, env } = options;
19
+ this.modelName = modelName;
20
+ this.apiKey = config?.apiKey || env?.QUIVERAI_API_KEY || getEnvString("QUIVERAI_API_KEY") || "";
21
+ this.apiBaseUrl = config?.apiBaseUrl || QUIVERAI_API_BASE_URL;
22
+ if (id) this.id = () => id;
23
+ this.config = config || {};
24
+ }
25
+ id() {
26
+ return `quiverai:${this.modelName}`;
27
+ }
28
+ toString() {
29
+ return `[QuiverAI Provider ${this.modelName}]`;
30
+ }
31
+ getApiUrl() {
32
+ return `${this.apiBaseUrl}/svgs/generations`;
33
+ }
34
+ getHeaders() {
35
+ return {
36
+ "Content-Type": "application/json",
37
+ Authorization: `Bearer ${this.apiKey}`
38
+ };
39
+ }
40
+ async callApi(prompt, context) {
41
+ if (!this.apiKey) return { error: "QuiverAI API key is not set. Set the QUIVERAI_API_KEY environment variable or add apiKey to the provider config. Get a key at https://app.quiver.ai/settings/api-keys" };
42
+ const config = {
43
+ ...this.config,
44
+ ...context?.prompt?.config
45
+ };
46
+ const useStream = config.stream !== false;
47
+ const body = {
48
+ model: this.modelName,
49
+ prompt,
50
+ stream: useStream,
51
+ ...pickDefined(config, [
52
+ "instructions",
53
+ "references",
54
+ "n",
55
+ "temperature",
56
+ "top_p",
57
+ "presence_penalty",
58
+ "max_output_tokens"
59
+ ])
60
+ };
61
+ try {
62
+ if (useStream) return await this.callApiStreaming(body);
63
+ return await this.callApiNonStreaming(body, context);
64
+ } catch (error) {
65
+ logger.error(`QuiverAI API call error: ${error}`);
66
+ return { error: `QuiverAI API call error: ${error}` };
67
+ }
68
+ }
69
+ async callApiNonStreaming(body, context) {
70
+ const { data, cached, status, statusText } = await fetchWithCache(this.getApiUrl(), {
71
+ method: "POST",
72
+ headers: this.getHeaders(),
73
+ body: JSON.stringify(body)
74
+ }, REQUEST_TIMEOUT_MS, "json", context?.bustCache ?? context?.debug);
75
+ if (status < 200 || status >= 300) {
76
+ if (data && typeof data === "object" && "code" in data && "message" in data) return { error: formatError(data) };
77
+ return { error: `API error: ${status} ${statusText}\n${typeof data === "string" ? data : JSON.stringify(data)}` };
78
+ }
79
+ const response = data;
80
+ return {
81
+ cached,
82
+ output: extractSvgOutput(response),
83
+ tokenUsage: mapTokenUsage(response.usage, cached ? 0 : 1)
84
+ };
85
+ }
86
+ async callApiStreaming(body) {
87
+ const maxRetries = 3;
88
+ let lastResp;
89
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
90
+ const controller = new AbortController();
91
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
92
+ let reader;
93
+ try {
94
+ lastResp = await fetchWithProxy(this.getApiUrl(), {
95
+ method: "POST",
96
+ headers: this.getHeaders(),
97
+ body: JSON.stringify(body),
98
+ signal: controller.signal
99
+ });
100
+ if (lastResp.status === 429 && attempt < maxRetries) {
101
+ const waitMs = getRetryAfterMs(lastResp.headers, attempt);
102
+ logger.debug(`QuiverAI: rate limited, retry ${attempt + 1}/${maxRetries} in ${waitMs}ms`);
103
+ await lastResp.body?.cancel();
104
+ await new Promise((resolve) => setTimeout(resolve, waitMs));
105
+ continue;
106
+ }
107
+ if (!lastResp.ok) return await handleStreamingError(lastResp);
108
+ if (!lastResp.body) return { error: "QuiverAI streaming response has no body" };
109
+ reader = lastResp.body.getReader();
110
+ return await readSSEStream(reader);
111
+ } finally {
112
+ reader?.cancel().catch(() => {});
113
+ clearTimeout(timeout);
114
+ }
115
+ }
116
+ return handleStreamingError(lastResp);
117
+ }
118
+ };
119
+ async function handleStreamingError(resp) {
120
+ try {
121
+ return { error: formatError(await resp.json()) };
122
+ } catch {
123
+ return { error: `QuiverAI API error: HTTP ${resp.status}` };
124
+ }
125
+ }
126
+ async function readSSEStream(reader) {
127
+ const decoder = new TextDecoder();
128
+ let buffer = "";
129
+ let finalSvg = "";
130
+ let usage;
131
+ while (true) {
132
+ const { done, value } = await reader.read();
133
+ if (done) break;
134
+ buffer += decoder.decode(value, { stream: true });
135
+ const lines = buffer.split("\n");
136
+ buffer = lines.pop() || "";
137
+ for (const line of lines) {
138
+ const parsed = parseSSELine(line);
139
+ if (parsed.svg) finalSvg = parsed.svg;
140
+ if (parsed.usage) usage = parsed.usage;
141
+ }
142
+ }
143
+ if (buffer.trim()) {
144
+ const parsed = parseSSELine(buffer);
145
+ if (parsed.svg) finalSvg = parsed.svg;
146
+ if (parsed.usage) usage = parsed.usage;
147
+ }
148
+ if (!finalSvg) return { error: "QuiverAI streaming response contained no SVG content" };
149
+ return {
150
+ output: finalSvg,
151
+ tokenUsage: mapTokenUsage(usage, 1)
152
+ };
153
+ }
154
+ function pickDefined(obj, keys) {
155
+ return Object.fromEntries(keys.filter((k) => obj[k] != null).map((k) => [k, obj[k]]));
156
+ }
157
+ function formatError(err) {
158
+ const base = `${err.message} [${err.code}]`;
159
+ return err.request_id ? `${base} (request_id: ${err.request_id})` : base;
160
+ }
161
+ function mapTokenUsage(usage, numRequests) {
162
+ return {
163
+ total: usage?.total_tokens || 0,
164
+ prompt: usage?.input_tokens || 0,
165
+ completion: usage?.output_tokens || 0,
166
+ numRequests
167
+ };
168
+ }
169
+ const MAX_RETRY_AFTER_MS = 6e4;
170
+ function getRetryAfterMs(headers, attempt) {
171
+ const retryAfter = headers.get("retry-after");
172
+ if (retryAfter) {
173
+ const seconds = Number(retryAfter);
174
+ if (!Number.isNaN(seconds)) return Math.min(seconds * 1e3, MAX_RETRY_AFTER_MS);
175
+ const date = new Date(retryAfter);
176
+ if (!Number.isNaN(date.getTime())) return Math.min(Math.max(0, date.getTime() - Date.now()), MAX_RETRY_AFTER_MS);
177
+ }
178
+ return Math.pow(2, attempt) * 1e3;
179
+ }
180
+ function parseSSELine(line) {
181
+ if (!line.startsWith("data:")) return {};
182
+ const payload = line.slice(line.startsWith("data: ") ? 6 : 5).trim();
183
+ if (!payload || payload === "[DONE]") return {};
184
+ try {
185
+ const event = JSON.parse(payload);
186
+ return {
187
+ svg: event.type === "content" && event.svg ? event.svg : void 0,
188
+ usage: event.usage
189
+ };
190
+ } catch {
191
+ logger.debug(`QuiverAI: failed to parse SSE data: ${payload}`);
192
+ return {};
193
+ }
194
+ }
195
+ function extractSvgOutput(response) {
196
+ if (Array.isArray(response.data)) {
197
+ const svgs = response.data.map((item) => item.svg).filter(Boolean);
198
+ return svgs.length === 1 ? svgs[0] : svgs.join("\n\n");
199
+ }
200
+ return JSON.stringify(response);
201
+ }
202
+ function createQuiverAiProvider(providerPath, providerOptions = {}, env) {
203
+ const splits = providerPath.split(":");
204
+ return new QuiverAiProvider((splits[1] === "chat" ? splits.slice(2) : splits.slice(1)).join(":") || QUIVERAI_DEFAULT_MODEL, {
205
+ config: providerOptions.config,
206
+ id: providerOptions.id,
207
+ env: providerOptions.env ?? env
208
+ });
209
+ }
210
+ //#endregion
211
+ export { createQuiverAiProvider };
212
+
213
+ //# sourceMappingURL=quiverai-D3JTF5lD.js.map