pagegraph 0.12.0 → 0.14.0

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 (160) hide show
  1. package/README.md +325 -66
  2. package/dist/anthropic-messages-TqKpKmfW.js +1067 -0
  3. package/dist/anthropic-messages-TqKpKmfW.js.map +1 -0
  4. package/dist/audit.d.ts +4 -2
  5. package/dist/audit.js +5 -5
  6. package/dist/audit.js.map +1 -1
  7. package/dist/azure-openai-responses-DJjBLwoI.js +231 -0
  8. package/dist/azure-openai-responses-DJjBLwoI.js.map +1 -0
  9. package/dist/build-only/audit.js +1 -1
  10. package/dist/build-only/claims.d.ts +1 -0
  11. package/dist/build-only/claims.js +6 -0
  12. package/dist/build-only/claims.js.map +1 -0
  13. package/dist/build-only/config.js +1 -1
  14. package/dist/build-only/oxlint.d.ts +1 -0
  15. package/dist/build-only/oxlint.js +6 -0
  16. package/dist/build-only/oxlint.js.map +1 -0
  17. package/dist/build-only/tanstack-start.js +1 -1
  18. package/dist/build-only/vite.js +1 -1
  19. package/dist/{checks-uZk5Em9A.js → checks-BS-aDXB_.js} +2 -2
  20. package/dist/checks-BS-aDXB_.js.map +1 -0
  21. package/dist/claims-Bch7Lxlo.d.ts +92 -0
  22. package/dist/claims-Bv7voeEV.js +431 -0
  23. package/dist/claims-Bv7voeEV.js.map +1 -0
  24. package/dist/claims.d.ts +94 -0
  25. package/dist/claims.js +2 -0
  26. package/dist/cli.js +17607 -43387
  27. package/dist/cli.js.map +1 -1
  28. package/dist/cloudflare-workers-ai-system-one-f3ZrvNYZ.js +41 -0
  29. package/dist/cloudflare-workers-ai-system-one-f3ZrvNYZ.js.map +1 -0
  30. package/dist/config.d.ts +9 -29
  31. package/dist/config.js +2 -2
  32. package/dist/config.js.map +1 -1
  33. package/dist/{content-kcEnQdfi.js → content-CHd0X4s6.js} +2 -2
  34. package/dist/{content-kcEnQdfi.js.map → content-CHd0X4s6.js.map} +1 -1
  35. package/dist/{content-B1cPtL8b.d.ts → content-DgNr7apS.d.ts} +4 -5
  36. package/dist/declare-D5o7hwmv.js.map +1 -1
  37. package/dist/diagnostics-Wt5faNDM.js +108 -0
  38. package/dist/diagnostics-Wt5faNDM.js.map +1 -0
  39. package/dist/dist-B6zg_Z3Z.js +4794 -0
  40. package/dist/dist-B6zg_Z3Z.js.map +1 -0
  41. package/dist/document-CztEu3Vd.d.ts +109 -0
  42. package/dist/document-Dvemcv7V.js +379 -0
  43. package/dist/document-Dvemcv7V.js.map +1 -0
  44. package/dist/env-api-keys-C-OA0yM-.js +124 -0
  45. package/dist/env-api-keys-C-OA0yM-.js.map +1 -0
  46. package/dist/error-body-CyiejW4b.js +103 -0
  47. package/dist/error-body-CyiejW4b.js.map +1 -0
  48. package/dist/facts-1OKclPOk.js +115 -0
  49. package/dist/facts-1OKclPOk.js.map +1 -0
  50. package/dist/github-copilot-headers-CEpMOpQF.js +24 -0
  51. package/dist/github-copilot-headers-CEpMOpQF.js.map +1 -0
  52. package/dist/google-generative-ai-BxABKIKO.js +330 -0
  53. package/dist/google-generative-ai-BxABKIKO.js.map +1 -0
  54. package/dist/google-shared-0gpM2jFi.js +19471 -0
  55. package/dist/google-shared-0gpM2jFi.js.map +1 -0
  56. package/dist/google-vertex-D8Eb5cbu.js +376 -0
  57. package/dist/google-vertex-D8Eb5cbu.js.map +1 -0
  58. package/dist/{declare-DVgdEdOL.d.ts → graph-D1PIndsC.d.ts} +117 -6
  59. package/dist/{graph-Bcsourlv.js → graph-DMNOLXLu.js} +23 -13
  60. package/dist/graph-DMNOLXLu.js.map +1 -0
  61. package/dist/hash-Dp7EzZUo.js +18 -0
  62. package/dist/hash-Dp7EzZUo.js.map +1 -0
  63. package/dist/headers-BRNMVpzu.js +19 -0
  64. package/dist/headers-BRNMVpzu.js.map +1 -0
  65. package/dist/index-C5w9ripz.d.ts +204 -0
  66. package/dist/index.d.ts +6 -160
  67. package/dist/index.js +37 -5
  68. package/dist/index.js.map +1 -1
  69. package/dist/inline-BbS93GAT.js +682 -0
  70. package/dist/inline-BbS93GAT.js.map +1 -0
  71. package/dist/json-parse-C10znB7l.js +383 -0
  72. package/dist/json-parse-C10znB7l.js.map +1 -0
  73. package/dist/llms-Dhr_5u2O.js +19 -0
  74. package/dist/llms-Dhr_5u2O.js.map +1 -0
  75. package/dist/markdown-C6dRE9zD.js +168 -0
  76. package/dist/markdown-C6dRE9zD.js.map +1 -0
  77. package/dist/markdown-path-lJB9BAVZ.js +6 -0
  78. package/dist/markdown-path-lJB9BAVZ.js.map +1 -0
  79. package/dist/{message-DT_CjUdt.js → message-CuBjgZ74.js} +2 -2
  80. package/dist/{message-DT_CjUdt.js.map → message-CuBjgZ74.js.map} +1 -1
  81. package/dist/mistral-conversations-CvaqBWjR.js +690 -0
  82. package/dist/mistral-conversations-CvaqBWjR.js.map +1 -0
  83. package/dist/models-DcT5qOEL.js +1203 -0
  84. package/dist/models-DcT5qOEL.js.map +1 -0
  85. package/dist/node-Ccvru9GE.js +26 -0
  86. package/dist/node-Ccvru9GE.js.map +1 -0
  87. package/dist/node-MEosBOF2.js +2403 -0
  88. package/dist/node-MEosBOF2.js.map +1 -0
  89. package/dist/openai-BCBEd2eO.js +17350 -0
  90. package/dist/openai-BCBEd2eO.js.map +1 -0
  91. package/dist/openai-codex-responses-vJqxeeRC.js +1268 -0
  92. package/dist/openai-codex-responses-vJqxeeRC.js.map +1 -0
  93. package/dist/openai-completions-Cb_fRAbI.js +989 -0
  94. package/dist/openai-completions-Cb_fRAbI.js.map +1 -0
  95. package/dist/openai-prompt-cache-Bc6qNWt0.js +10 -0
  96. package/dist/openai-prompt-cache-Bc6qNWt0.js.map +1 -0
  97. package/dist/openai-responses-sDuh82G5.js +268 -0
  98. package/dist/openai-responses-sDuh82G5.js.map +1 -0
  99. package/dist/openai-responses-shared-mhuo1Jov.js +599 -0
  100. package/dist/openai-responses-shared-mhuo1Jov.js.map +1 -0
  101. package/dist/openrouter-images-CRmBkzpX.js +127 -0
  102. package/dist/openrouter-images-CRmBkzpX.js.map +1 -0
  103. package/dist/oxlint.d.ts +58 -0
  104. package/dist/oxlint.js +202 -0
  105. package/dist/oxlint.js.map +1 -0
  106. package/dist/page-heads-BfjWQvau.d.ts +108 -0
  107. package/dist/{page-heads-6y-CARRQ.js → page-heads-BgbaIjj9.js} +3 -3
  108. package/dist/page-heads-BgbaIjj9.js.map +1 -0
  109. package/dist/pi-Bvw6J0gh.js +56795 -0
  110. package/dist/pi-Bvw6J0gh.js.map +1 -0
  111. package/dist/pi-messages-CejiVYvO.js +308 -0
  112. package/dist/pi-messages-CejiVYvO.js.map +1 -0
  113. package/dist/{projections-DeEFe7XT.d.ts → projections-Bk-qOOsR.d.ts} +2 -2
  114. package/dist/provider-env-t38GK5FF.js +39 -0
  115. package/dist/provider-env-t38GK5FF.js.map +1 -0
  116. package/dist/provider-retry-DzKoh1X7.js +80 -0
  117. package/dist/provider-retry-DzKoh1X7.js.map +1 -0
  118. package/dist/react.d.ts +3 -2
  119. package/dist/react.js +2 -1
  120. package/dist/react.js.map +1 -1
  121. package/dist/rolldown-runtime-B-lAHAz2.js +37 -0
  122. package/dist/sanitize-unicode-Ds14l9Om.js +28 -0
  123. package/dist/sanitize-unicode-Ds14l9Om.js.map +1 -0
  124. package/dist/sdk-C9_wiO6w.js +12503 -0
  125. package/dist/sdk-C9_wiO6w.js.map +1 -0
  126. package/dist/state-BuJP_3Lr.js +28102 -0
  127. package/dist/state-BuJP_3Lr.js.map +1 -0
  128. package/dist/system-one-shared-Dl10ZF7Z.js +167 -0
  129. package/dist/system-one-shared-Dl10ZF7Z.js.map +1 -0
  130. package/dist/tanstack-start/index.d.ts +29 -13
  131. package/dist/tanstack-start/index.js +391 -42
  132. package/dist/tanstack-start/index.js.map +1 -1
  133. package/dist/tanstack-start/markdown.d.ts +12 -0
  134. package/dist/tanstack-start/markdown.js +149 -0
  135. package/dist/tanstack-start/markdown.js.map +1 -0
  136. package/dist/tanstack-start/prerender-worker.d.ts +2 -0
  137. package/dist/tanstack-start/prerender-worker.js +7 -0
  138. package/dist/tanstack-start/prerender-worker.js.map +1 -0
  139. package/dist/tanstack-start/react.d.ts +7 -0
  140. package/dist/tanstack-start/react.js +12 -0
  141. package/dist/tanstack-start/react.js.map +1 -0
  142. package/dist/tanstack-start/server.d.ts +9 -3
  143. package/dist/tanstack-start/server.js +26 -2
  144. package/dist/tanstack-start/server.js.map +1 -1
  145. package/dist/transform-messages-BLJ8EfK6.js +468 -0
  146. package/dist/transform-messages-BLJ8EfK6.js.map +1 -0
  147. package/dist/typesafe-system-one-CwEWMV8P.js +25 -0
  148. package/dist/typesafe-system-one-CwEWMV8P.js.map +1 -0
  149. package/dist/{vite-graph-loader-01p1WxEq.js → vite-graph-loader-CsGiYNWE.js} +6 -5
  150. package/dist/vite-graph-loader-CsGiYNWE.js.map +1 -0
  151. package/dist/vite-graph-loader-DZCwejuJ.d.ts +133 -0
  152. package/package.json +47 -10
  153. package/dist/checks-uZk5Em9A.js.map +0 -1
  154. package/dist/graph-Bcsourlv.js.map +0 -1
  155. package/dist/graph-BxCY90vq.d.ts +0 -104
  156. package/dist/graph-CBIY71w6.d.ts +0 -57
  157. package/dist/page-heads-6y-CARRQ.js.map +0 -1
  158. package/dist/page-heads-DNkjMUEN.d.ts +0 -21
  159. package/dist/vite-graph-loader-01p1WxEq.js.map +0 -1
  160. package/dist/vite-graph-loader-Btgjz5RH.d.ts +0 -56
@@ -0,0 +1,376 @@
1
+ import { t as getProviderEnvValue } from "./provider-env-t38GK5FF.js";
2
+ import { a as AssistantMessageEventStream } from "./diagnostics-Wt5faNDM.js";
3
+ import { S as getSystemMessageText, d as getCurrentTools, n as clampThinkingLevel, o as collapseSystemMessages, p as getInitialSystemMessage, t as calculateCost } from "./models-DcT5qOEL.js";
4
+ import { n as providerHeadersToRecord } from "./headers-BRNMVpzu.js";
5
+ import { p as getPiUserAgent, r as buildBaseOptions } from "./transform-messages-BLJ8EfK6.js";
6
+ import { t as sanitizeSurrogates } from "./sanitize-unicode-Ds14l9Om.js";
7
+ import { n as normalizeProviderError, t as formatProviderError } from "./error-body-CyiejW4b.js";
8
+ import { a as mapStopReason, c as retainThoughtSignature, d as toGoogleSdkThinkingLevel, f as toGoogleThinkingLevel, h as ResourceScope, i as isThinkingPart, l as retryGoogleRequest, m as GoogleGenAI, n as convertTools, o as resolveGoogleFunctionCallingMode, p as usesGoogleThinkingLevel, r as getDisabledGoogleThinkingConfig, s as resolveGoogleThinkingLevel, t as convertMessages, u as supportsGoogleStrictToolSampling } from "./google-shared-0gpM2jFi.js";
9
+ //#region node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js
10
+ const API_VERSION = "v1";
11
+ const GCP_VERTEX_CREDENTIALS_MARKER = "gcp-vertex-credentials";
12
+ let toolCallCounter = 0;
13
+ const stream = (model, context, options) => {
14
+ const stream = new AssistantMessageEventStream();
15
+ const normalizedContext = collapseSystemMessages(context);
16
+ (async () => {
17
+ const output = {
18
+ role: "assistant",
19
+ content: [],
20
+ api: "google-vertex",
21
+ provider: model.provider,
22
+ model: model.id,
23
+ usage: {
24
+ input: 0,
25
+ output: 0,
26
+ cacheRead: 0,
27
+ cacheWrite: 0,
28
+ totalTokens: 0,
29
+ cost: {
30
+ input: 0,
31
+ output: 0,
32
+ cacheRead: 0,
33
+ cacheWrite: 0,
34
+ total: 0
35
+ }
36
+ },
37
+ stopReason: "pending",
38
+ timestamp: Date.now()
39
+ };
40
+ try {
41
+ if (options?.fetch && options.fetch !== globalThis.fetch) throw new Error("Custom fetch is not supported by the Google Vertex adapter");
42
+ const apiKey = resolveApiKey(options);
43
+ const client = apiKey ? createClientWithApiKey(model, apiKey, options?.headers) : createClient(model, resolveProject(options), resolveLocation(options), options?.headers, options?.env);
44
+ let params = buildParams(model, normalizedContext, options);
45
+ const nextParams = await options?.onPayload?.(params, model);
46
+ if (nextParams !== void 0) params = nextParams;
47
+ const googleStream = await retryGoogleRequest(() => client.models.generateContentStream(params), options);
48
+ stream.push({
49
+ type: "start",
50
+ partial: output
51
+ });
52
+ let currentBlock = null;
53
+ const blocks = output.content;
54
+ const blockIndex = () => blocks.length - 1;
55
+ for await (const chunk of googleStream) {
56
+ await options?.onProviderStreamEvent?.(chunk, model);
57
+ output.responseId ||= chunk.responseId;
58
+ const candidate = chunk.candidates?.[0];
59
+ if (candidate?.content?.parts) for (const part of candidate.content.parts) {
60
+ if (part.text !== void 0) {
61
+ const isThinking = isThinkingPart(part);
62
+ if (!currentBlock || isThinking && currentBlock.type !== "thinking" || !isThinking && currentBlock.type !== "text") {
63
+ if (currentBlock) if (currentBlock.type === "text") stream.push({
64
+ type: "text_end",
65
+ contentIndex: blocks.length - 1,
66
+ content: currentBlock.text,
67
+ partial: output
68
+ });
69
+ else stream.push({
70
+ type: "thinking_end",
71
+ contentIndex: blockIndex(),
72
+ content: currentBlock.thinking,
73
+ partial: output
74
+ });
75
+ if (isThinking) {
76
+ currentBlock = {
77
+ type: "thinking",
78
+ thinking: "",
79
+ thinkingSignature: void 0
80
+ };
81
+ output.content.push(currentBlock);
82
+ stream.push({
83
+ type: "thinking_start",
84
+ contentIndex: blockIndex(),
85
+ partial: output
86
+ });
87
+ } else {
88
+ currentBlock = {
89
+ type: "text",
90
+ text: ""
91
+ };
92
+ output.content.push(currentBlock);
93
+ stream.push({
94
+ type: "text_start",
95
+ contentIndex: blockIndex(),
96
+ partial: output
97
+ });
98
+ }
99
+ }
100
+ if (currentBlock.type === "thinking") {
101
+ currentBlock.thinking += part.text;
102
+ currentBlock.thinkingSignature = retainThoughtSignature(currentBlock.thinkingSignature, part.thoughtSignature);
103
+ stream.push({
104
+ type: "thinking_delta",
105
+ contentIndex: blockIndex(),
106
+ delta: part.text,
107
+ partial: output
108
+ });
109
+ } else {
110
+ currentBlock.text += part.text;
111
+ currentBlock.textSignature = retainThoughtSignature(currentBlock.textSignature, part.thoughtSignature);
112
+ stream.push({
113
+ type: "text_delta",
114
+ contentIndex: blockIndex(),
115
+ delta: part.text,
116
+ partial: output
117
+ });
118
+ }
119
+ }
120
+ if (part.functionCall) {
121
+ if (currentBlock) {
122
+ if (currentBlock.type === "text") stream.push({
123
+ type: "text_end",
124
+ contentIndex: blockIndex(),
125
+ content: currentBlock.text,
126
+ partial: output
127
+ });
128
+ else stream.push({
129
+ type: "thinking_end",
130
+ contentIndex: blockIndex(),
131
+ content: currentBlock.thinking,
132
+ partial: output
133
+ });
134
+ currentBlock = null;
135
+ }
136
+ const providedId = part.functionCall.id;
137
+ const toolCall = {
138
+ type: "toolCall",
139
+ id: !providedId || output.content.some((b) => b.type === "toolCall" && b.id === providedId) ? `${part.functionCall.name}_${Date.now()}_${++toolCallCounter}` : providedId,
140
+ name: part.functionCall.name || "",
141
+ arguments: part.functionCall.args ?? {},
142
+ ...part.thoughtSignature && { thoughtSignature: part.thoughtSignature }
143
+ };
144
+ output.content.push(toolCall);
145
+ stream.push({
146
+ type: "toolcall_start",
147
+ contentIndex: blockIndex(),
148
+ partial: output
149
+ });
150
+ stream.push({
151
+ type: "toolcall_delta",
152
+ contentIndex: blockIndex(),
153
+ delta: JSON.stringify(toolCall.arguments),
154
+ partial: output
155
+ });
156
+ stream.push({
157
+ type: "toolcall_end",
158
+ contentIndex: blockIndex(),
159
+ toolCall,
160
+ partial: output
161
+ });
162
+ }
163
+ }
164
+ if (candidate?.finishReason) {
165
+ output.rawStopReason = candidate.finishReason;
166
+ output.stopReason = mapStopReason(candidate.finishReason);
167
+ if (output.content.some((b) => b.type === "toolCall") && output.stopReason === "stop") output.stopReason = "toolUse";
168
+ }
169
+ if (chunk.usageMetadata) {
170
+ output.usage = {
171
+ input: (chunk.usageMetadata.promptTokenCount || 0) - (chunk.usageMetadata.cachedContentTokenCount || 0),
172
+ output: (chunk.usageMetadata.candidatesTokenCount || 0) + (chunk.usageMetadata.thoughtsTokenCount || 0),
173
+ cacheRead: chunk.usageMetadata.cachedContentTokenCount || 0,
174
+ cacheWrite: 0,
175
+ reasoning: chunk.usageMetadata.thoughtsTokenCount || 0,
176
+ totalTokens: chunk.usageMetadata.totalTokenCount || 0,
177
+ cost: {
178
+ input: 0,
179
+ output: 0,
180
+ cacheRead: 0,
181
+ cacheWrite: 0,
182
+ total: 0
183
+ }
184
+ };
185
+ calculateCost(model, output.usage);
186
+ }
187
+ }
188
+ if (currentBlock) if (currentBlock.type === "text") stream.push({
189
+ type: "text_end",
190
+ contentIndex: blockIndex(),
191
+ content: currentBlock.text,
192
+ partial: output
193
+ });
194
+ else stream.push({
195
+ type: "thinking_end",
196
+ contentIndex: blockIndex(),
197
+ content: currentBlock.thinking,
198
+ partial: output
199
+ });
200
+ if (options?.signal?.aborted) throw new Error("Request was aborted");
201
+ if (output.stopReason === "pending") throw new Error("Google Vertex stream ended without a finish reason");
202
+ if (output.stopReason === "aborted" || output.stopReason === "error") {
203
+ const errorMessage = output.rawStopReason ? `Provider stopped with: ${output.rawStopReason}` : "An unknown error occurred";
204
+ throw new Error(errorMessage);
205
+ }
206
+ stream.push({
207
+ type: "done",
208
+ reason: output.stopReason,
209
+ message: output
210
+ });
211
+ stream.end();
212
+ } catch (error) {
213
+ for (const block of output.content) if ("index" in block) delete block.index;
214
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
215
+ output.errorMessage = formatProviderError(normalizeProviderError(error));
216
+ stream.push({
217
+ type: "error",
218
+ reason: output.stopReason,
219
+ error: output
220
+ });
221
+ stream.end();
222
+ }
223
+ })();
224
+ return stream;
225
+ };
226
+ const streamSimple = (model, context, options) => {
227
+ const base = {
228
+ ...buildBaseOptions(model, context, options, void 0),
229
+ toolChoice: options?.toolChoice
230
+ };
231
+ if (!options?.reasoning) return stream(model, context, {
232
+ ...base,
233
+ thinking: { enabled: false }
234
+ });
235
+ const clampedReasoning = clampThinkingLevel(model, options.reasoning);
236
+ if (clampedReasoning === "off") return stream(model, context, {
237
+ ...base,
238
+ thinking: { enabled: false }
239
+ });
240
+ const resolvedLevel = resolveGoogleThinkingLevel(model, clampedReasoning);
241
+ if (usesGoogleThinkingLevel(model)) return stream(model, context, {
242
+ ...base,
243
+ thinking: {
244
+ enabled: true,
245
+ level: toGoogleThinkingLevel(resolvedLevel)
246
+ }
247
+ });
248
+ return stream(model, context, {
249
+ ...base,
250
+ thinking: {
251
+ enabled: true,
252
+ budgetTokens: getGoogleBudget(model, resolvedLevel, options.thinkingBudgets)
253
+ }
254
+ });
255
+ };
256
+ function createClient(model, project, location, optionsHeaders, env) {
257
+ const googleAuthOptions = buildGoogleAuthOptions(env);
258
+ return new GoogleGenAI({
259
+ vertexai: true,
260
+ project,
261
+ location,
262
+ apiVersion: API_VERSION,
263
+ ...googleAuthOptions ? { googleAuthOptions } : {},
264
+ httpOptions: buildHttpOptions(model, optionsHeaders)
265
+ });
266
+ }
267
+ function createClientWithApiKey(model, apiKey, optionsHeaders) {
268
+ return new GoogleGenAI({
269
+ vertexai: true,
270
+ apiKey,
271
+ apiVersion: API_VERSION,
272
+ httpOptions: buildHttpOptions(model, optionsHeaders)
273
+ });
274
+ }
275
+ function buildHttpOptions(model, optionsHeaders) {
276
+ const httpOptions = {};
277
+ const baseUrl = resolveCustomBaseUrl(model.baseUrl);
278
+ if (baseUrl) {
279
+ httpOptions.baseUrl = baseUrl;
280
+ httpOptions.baseUrlResourceScope = ResourceScope.COLLECTION;
281
+ if (baseUrlIncludesApiVersion(baseUrl)) httpOptions.apiVersion = "";
282
+ }
283
+ const headers = providerHeadersToRecord({
284
+ "User-Agent": getPiUserAgent(),
285
+ ...model.headers,
286
+ ...optionsHeaders
287
+ });
288
+ if (headers) httpOptions.headers = headers;
289
+ return Object.keys(httpOptions).length > 0 ? httpOptions : void 0;
290
+ }
291
+ function resolveCustomBaseUrl(baseUrl) {
292
+ const trimmed = baseUrl.trim();
293
+ if (!trimmed || trimmed.includes("{location}")) return;
294
+ return trimmed;
295
+ }
296
+ function baseUrlIncludesApiVersion(baseUrl) {
297
+ try {
298
+ return new URL(baseUrl).pathname.split("/").some((part) => /^v\d+(?:beta\d*)?$/.test(part));
299
+ } catch {
300
+ return /(?:^|\/)v\d+(?:beta\d*)?(?:\/|$)/.test(baseUrl);
301
+ }
302
+ }
303
+ function buildGoogleAuthOptions(env) {
304
+ const keyFilename = getProviderEnvValue("GOOGLE_APPLICATION_CREDENTIALS", env);
305
+ return keyFilename ? { keyFilename } : void 0;
306
+ }
307
+ function resolveApiKey(options) {
308
+ const apiKey = options?.apiKey?.trim();
309
+ if (!apiKey || apiKey === GCP_VERTEX_CREDENTIALS_MARKER || isPlaceholderApiKey(apiKey)) return;
310
+ return apiKey;
311
+ }
312
+ function isPlaceholderApiKey(apiKey) {
313
+ return /^<[^>]+>$/.test(apiKey);
314
+ }
315
+ function resolveProject(options) {
316
+ const project = options?.project || getProviderEnvValue("GOOGLE_CLOUD_PROJECT", options?.env) || getProviderEnvValue("GCLOUD_PROJECT", options?.env);
317
+ if (!project) throw new Error("Vertex AI requires a project ID. Set GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT or pass project in options.");
318
+ return project;
319
+ }
320
+ function resolveLocation(options) {
321
+ const location = options?.location || getProviderEnvValue("GOOGLE_CLOUD_LOCATION", options?.env);
322
+ if (!location) throw new Error("Vertex AI requires a location. Set GOOGLE_CLOUD_LOCATION or pass location in options.");
323
+ return location;
324
+ }
325
+ function buildParams(model, context, options = {}) {
326
+ const contents = convertMessages(model, context);
327
+ const initialSystemMessage = getInitialSystemMessage(context.messages);
328
+ const currentTools = getCurrentTools(context.messages);
329
+ const generationConfig = {};
330
+ if (options.temperature !== void 0) generationConfig.temperature = options.temperature;
331
+ if (options.maxTokens !== void 0) generationConfig.maxOutputTokens = options.maxTokens;
332
+ const supportsStrictMode = supportsGoogleStrictToolSampling(model.id);
333
+ const functionCallingMode = currentTools.length > 0 ? resolveGoogleFunctionCallingMode(currentTools, options.toolChoice, supportsStrictMode) : void 0;
334
+ const systemInstruction = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : "";
335
+ const config = {
336
+ ...Object.keys(generationConfig).length > 0 && generationConfig,
337
+ ...systemInstruction && { systemInstruction: sanitizeSurrogates(systemInstruction) },
338
+ ...currentTools.length > 0 && { tools: convertTools(currentTools, false, supportsStrictMode) },
339
+ ...functionCallingMode !== void 0 && { toolConfig: { functionCallingConfig: { mode: functionCallingMode } } }
340
+ };
341
+ if (options.thinking?.enabled && model.reasoning) {
342
+ const thinkingConfig = { includeThoughts: true };
343
+ if (options.thinking.level !== void 0) thinkingConfig.thinkingLevel = toGoogleSdkThinkingLevel(options.thinking.level);
344
+ else if (options.thinking.budgetTokens !== void 0) thinkingConfig.thinkingBudget = options.thinking.budgetTokens;
345
+ config.thinkingConfig = thinkingConfig;
346
+ } else if (model.reasoning && options.thinking && !options.thinking.enabled) config.thinkingConfig = getDisabledGoogleThinkingConfig(model);
347
+ if (options.signal) {
348
+ if (options.signal.aborted) throw new Error("Request aborted");
349
+ config.abortSignal = options.signal;
350
+ }
351
+ return {
352
+ model: model.id,
353
+ contents,
354
+ config
355
+ };
356
+ }
357
+ function getGoogleBudget(model, level, customBudgets) {
358
+ if (customBudgets?.[level] !== void 0) return customBudgets[level];
359
+ if (model.id.includes("2.5-pro")) return {
360
+ minimal: 128,
361
+ low: 2048,
362
+ medium: 8192,
363
+ high: 32768
364
+ }[level];
365
+ if (model.id.includes("2.5-flash")) return {
366
+ minimal: 128,
367
+ low: 2048,
368
+ medium: 8192,
369
+ high: 24576
370
+ }[level];
371
+ return -1;
372
+ }
373
+ //#endregion
374
+ export { stream, streamSimple };
375
+
376
+ //# sourceMappingURL=google-vertex-D8Eb5cbu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-vertex-D8Eb5cbu.js","names":[],"sources":["../node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js"],"sourcesContent":["import { GoogleGenAI, ResourceScope, } from \"@google/genai\";\nimport { calculateCost, clampThinkingLevel } from \"../models.js\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport { providerHeadersToRecord } from \"../utils/headers.js\";\nimport { getPiUserAgent } from \"../utils/pi-user-agent.js\";\nimport { getProviderEnvValue } from \"../utils/provider-env.js\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.js\";\nimport { getSystemMessageText } from \"../utils/text.js\";\nimport { collapseSystemMessages, getCurrentTools, getInitialSystemMessage } from \"../utils/transcript.js\";\nimport { convertMessages, convertTools, getDisabledGoogleThinkingConfig, isThinkingPart, mapStopReason, resolveGoogleFunctionCallingMode, resolveGoogleThinkingLevel, retainThoughtSignature, retryGoogleRequest, supportsGoogleStrictToolSampling, toGoogleSdkThinkingLevel, toGoogleThinkingLevel, usesGoogleThinkingLevel, } from \"./google-shared.js\";\nimport { buildBaseOptions } from \"./simple-options.js\";\nconst API_VERSION = \"v1\";\nconst GCP_VERTEX_CREDENTIALS_MARKER = \"gcp-vertex-credentials\";\n// Counter for generating unique tool call IDs\nlet toolCallCounter = 0;\nexport const stream = (model, context, options) => {\n const stream = new AssistantMessageEventStream();\n const normalizedContext = collapseSystemMessages(context);\n (async () => {\n const output = {\n role: \"assistant\",\n content: [],\n api: \"google-vertex\",\n provider: model.provider,\n model: model.id,\n usage: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n },\n stopReason: \"pending\",\n timestamp: Date.now(),\n };\n try {\n if (options?.fetch && options.fetch !== globalThis.fetch) {\n throw new Error(\"Custom fetch is not supported by the Google Vertex adapter\");\n }\n const apiKey = resolveApiKey(options);\n // Create the client using either a Vertex API key, if provided, or ADC with project and location\n const client = apiKey\n ? createClientWithApiKey(model, apiKey, options?.headers)\n : createClient(model, resolveProject(options), resolveLocation(options), options?.headers, options?.env);\n let params = buildParams(model, normalizedContext, options);\n const nextParams = await options?.onPayload?.(params, model);\n if (nextParams !== undefined) {\n params = nextParams;\n }\n const googleStream = await retryGoogleRequest(() => client.models.generateContentStream(params), options);\n stream.push({ type: \"start\", partial: output });\n let currentBlock = null;\n const blocks = output.content;\n const blockIndex = () => blocks.length - 1;\n for await (const chunk of googleStream) {\n await options?.onProviderStreamEvent?.(chunk, model);\n // Vertex uses the same @google/genai GenerateContentResponse type as Gemini.\n // responseId is documented there as an output-only identifier for each response.\n output.responseId ||= chunk.responseId;\n const candidate = chunk.candidates?.[0];\n if (candidate?.content?.parts) {\n for (const part of candidate.content.parts) {\n if (part.text !== undefined) {\n const isThinking = isThinkingPart(part);\n if (!currentBlock ||\n (isThinking && currentBlock.type !== \"thinking\") ||\n (!isThinking && currentBlock.type !== \"text\")) {\n if (currentBlock) {\n if (currentBlock.type === \"text\") {\n stream.push({\n type: \"text_end\",\n contentIndex: blocks.length - 1,\n content: currentBlock.text,\n partial: output,\n });\n }\n else {\n stream.push({\n type: \"thinking_end\",\n contentIndex: blockIndex(),\n content: currentBlock.thinking,\n partial: output,\n });\n }\n }\n if (isThinking) {\n currentBlock = { type: \"thinking\", thinking: \"\", thinkingSignature: undefined };\n output.content.push(currentBlock);\n stream.push({ type: \"thinking_start\", contentIndex: blockIndex(), partial: output });\n }\n else {\n currentBlock = { type: \"text\", text: \"\" };\n output.content.push(currentBlock);\n stream.push({ type: \"text_start\", contentIndex: blockIndex(), partial: output });\n }\n }\n if (currentBlock.type === \"thinking\") {\n currentBlock.thinking += part.text;\n currentBlock.thinkingSignature = retainThoughtSignature(currentBlock.thinkingSignature, part.thoughtSignature);\n stream.push({\n type: \"thinking_delta\",\n contentIndex: blockIndex(),\n delta: part.text,\n partial: output,\n });\n }\n else {\n currentBlock.text += part.text;\n currentBlock.textSignature = retainThoughtSignature(currentBlock.textSignature, part.thoughtSignature);\n stream.push({\n type: \"text_delta\",\n contentIndex: blockIndex(),\n delta: part.text,\n partial: output,\n });\n }\n }\n if (part.functionCall) {\n if (currentBlock) {\n if (currentBlock.type === \"text\") {\n stream.push({\n type: \"text_end\",\n contentIndex: blockIndex(),\n content: currentBlock.text,\n partial: output,\n });\n }\n else {\n stream.push({\n type: \"thinking_end\",\n contentIndex: blockIndex(),\n content: currentBlock.thinking,\n partial: output,\n });\n }\n currentBlock = null;\n }\n const providedId = part.functionCall.id;\n const needsNewId = !providedId || output.content.some((b) => b.type === \"toolCall\" && b.id === providedId);\n const toolCallId = needsNewId\n ? `${part.functionCall.name}_${Date.now()}_${++toolCallCounter}`\n : providedId;\n const toolCall = {\n type: \"toolCall\",\n id: toolCallId,\n name: part.functionCall.name || \"\",\n arguments: part.functionCall.args ?? {},\n ...(part.thoughtSignature && { thoughtSignature: part.thoughtSignature }),\n };\n output.content.push(toolCall);\n stream.push({ type: \"toolcall_start\", contentIndex: blockIndex(), partial: output });\n stream.push({\n type: \"toolcall_delta\",\n contentIndex: blockIndex(),\n delta: JSON.stringify(toolCall.arguments),\n partial: output,\n });\n stream.push({ type: \"toolcall_end\", contentIndex: blockIndex(), toolCall, partial: output });\n }\n }\n }\n if (candidate?.finishReason) {\n output.rawStopReason = candidate.finishReason;\n output.stopReason = mapStopReason(candidate.finishReason);\n if (output.content.some((b) => b.type === \"toolCall\") && output.stopReason === \"stop\") {\n output.stopReason = \"toolUse\";\n }\n }\n if (chunk.usageMetadata) {\n output.usage = {\n input: (chunk.usageMetadata.promptTokenCount || 0) - (chunk.usageMetadata.cachedContentTokenCount || 0),\n output: (chunk.usageMetadata.candidatesTokenCount || 0) + (chunk.usageMetadata.thoughtsTokenCount || 0),\n cacheRead: chunk.usageMetadata.cachedContentTokenCount || 0,\n cacheWrite: 0,\n reasoning: chunk.usageMetadata.thoughtsTokenCount || 0,\n totalTokens: chunk.usageMetadata.totalTokenCount || 0,\n cost: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n total: 0,\n },\n };\n calculateCost(model, output.usage);\n }\n }\n if (currentBlock) {\n if (currentBlock.type === \"text\") {\n stream.push({\n type: \"text_end\",\n contentIndex: blockIndex(),\n content: currentBlock.text,\n partial: output,\n });\n }\n else {\n stream.push({\n type: \"thinking_end\",\n contentIndex: blockIndex(),\n content: currentBlock.thinking,\n partial: output,\n });\n }\n }\n if (options?.signal?.aborted) {\n throw new Error(\"Request was aborted\");\n }\n if (output.stopReason === \"pending\") {\n throw new Error(\"Google Vertex stream ended without a finish reason\");\n }\n if (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n const errorMessage = output.rawStopReason\n ? `Provider stopped with: ${output.rawStopReason}`\n : \"An unknown error occurred\";\n throw new Error(errorMessage);\n }\n stream.push({ type: \"done\", reason: output.stopReason, message: output });\n stream.end();\n }\n catch (error) {\n // Remove internal index property used during streaming\n for (const block of output.content) {\n if (\"index\" in block) {\n delete block.index;\n }\n }\n output.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n output.errorMessage = formatProviderError(normalizeProviderError(error));\n stream.push({ type: \"error\", reason: output.stopReason, error: output });\n stream.end();\n }\n })();\n return stream;\n};\nexport const streamSimple = (model, context, options) => {\n const base = {\n ...buildBaseOptions(model, context, options, undefined),\n toolChoice: options?.toolChoice,\n };\n if (!options?.reasoning) {\n return stream(model, context, {\n ...base,\n thinking: { enabled: false },\n });\n }\n const clampedReasoning = clampThinkingLevel(model, options.reasoning);\n if (clampedReasoning === \"off\") {\n return stream(model, context, {\n ...base,\n thinking: { enabled: false },\n });\n }\n const resolvedLevel = resolveGoogleThinkingLevel(model, clampedReasoning);\n if (usesGoogleThinkingLevel(model)) {\n return stream(model, context, {\n ...base,\n thinking: {\n enabled: true,\n level: toGoogleThinkingLevel(resolvedLevel),\n },\n });\n }\n return stream(model, context, {\n ...base,\n thinking: {\n enabled: true,\n budgetTokens: getGoogleBudget(model, resolvedLevel, options.thinkingBudgets),\n },\n });\n};\nfunction createClient(model, project, location, optionsHeaders, env) {\n const googleAuthOptions = buildGoogleAuthOptions(env);\n return new GoogleGenAI({\n vertexai: true,\n project,\n location,\n apiVersion: API_VERSION,\n ...(googleAuthOptions ? { googleAuthOptions } : {}),\n httpOptions: buildHttpOptions(model, optionsHeaders),\n });\n}\nfunction createClientWithApiKey(model, apiKey, optionsHeaders) {\n return new GoogleGenAI({\n vertexai: true,\n apiKey,\n apiVersion: API_VERSION,\n httpOptions: buildHttpOptions(model, optionsHeaders),\n });\n}\nfunction buildHttpOptions(model, optionsHeaders) {\n const httpOptions = {};\n const baseUrl = resolveCustomBaseUrl(model.baseUrl);\n if (baseUrl) {\n httpOptions.baseUrl = baseUrl;\n httpOptions.baseUrlResourceScope = ResourceScope.COLLECTION;\n if (baseUrlIncludesApiVersion(baseUrl)) {\n httpOptions.apiVersion = \"\";\n }\n }\n const headers = providerHeadersToRecord({ \"User-Agent\": getPiUserAgent(), ...model.headers, ...optionsHeaders });\n if (headers) {\n httpOptions.headers = headers;\n }\n return Object.keys(httpOptions).length > 0 ? httpOptions : undefined;\n}\nfunction resolveCustomBaseUrl(baseUrl) {\n const trimmed = baseUrl.trim();\n if (!trimmed || trimmed.includes(\"{location}\")) {\n return undefined;\n }\n return trimmed;\n}\nfunction baseUrlIncludesApiVersion(baseUrl) {\n try {\n const url = new URL(baseUrl);\n return url.pathname.split(\"/\").some((part) => /^v\\d+(?:beta\\d*)?$/.test(part));\n }\n catch {\n return /(?:^|\\/)v\\d+(?:beta\\d*)?(?:\\/|$)/.test(baseUrl);\n }\n}\nfunction buildGoogleAuthOptions(env) {\n const keyFilename = getProviderEnvValue(\"GOOGLE_APPLICATION_CREDENTIALS\", env);\n return keyFilename ? { keyFilename } : undefined;\n}\nfunction resolveApiKey(options) {\n const apiKey = options?.apiKey?.trim();\n if (!apiKey || apiKey === GCP_VERTEX_CREDENTIALS_MARKER || isPlaceholderApiKey(apiKey)) {\n return undefined;\n }\n return apiKey;\n}\nfunction isPlaceholderApiKey(apiKey) {\n return /^<[^>]+>$/.test(apiKey);\n}\nfunction resolveProject(options) {\n const project = options?.project ||\n getProviderEnvValue(\"GOOGLE_CLOUD_PROJECT\", options?.env) ||\n getProviderEnvValue(\"GCLOUD_PROJECT\", options?.env);\n if (!project) {\n throw new Error(\"Vertex AI requires a project ID. Set GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT or pass project in options.\");\n }\n return project;\n}\nfunction resolveLocation(options) {\n const location = options?.location || getProviderEnvValue(\"GOOGLE_CLOUD_LOCATION\", options?.env);\n if (!location) {\n throw new Error(\"Vertex AI requires a location. Set GOOGLE_CLOUD_LOCATION or pass location in options.\");\n }\n return location;\n}\nfunction buildParams(model, context, options = {}) {\n const contents = convertMessages(model, context);\n const initialSystemMessage = getInitialSystemMessage(context.messages);\n const currentTools = getCurrentTools(context.messages);\n const generationConfig = {};\n if (options.temperature !== undefined) {\n generationConfig.temperature = options.temperature;\n }\n if (options.maxTokens !== undefined) {\n generationConfig.maxOutputTokens = options.maxTokens;\n }\n const supportsStrictMode = supportsGoogleStrictToolSampling(model.id);\n const functionCallingMode = currentTools.length > 0\n ? resolveGoogleFunctionCallingMode(currentTools, options.toolChoice, supportsStrictMode)\n : undefined;\n const systemInstruction = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : \"\";\n const config = {\n ...(Object.keys(generationConfig).length > 0 && generationConfig),\n ...(systemInstruction && { systemInstruction: sanitizeSurrogates(systemInstruction) }),\n ...(currentTools.length > 0 && {\n tools: convertTools(currentTools, false, supportsStrictMode),\n }),\n ...(functionCallingMode !== undefined && {\n toolConfig: { functionCallingConfig: { mode: functionCallingMode } },\n }),\n };\n if (options.thinking?.enabled && model.reasoning) {\n const thinkingConfig = { includeThoughts: true };\n if (options.thinking.level !== undefined) {\n thinkingConfig.thinkingLevel = toGoogleSdkThinkingLevel(options.thinking.level);\n }\n else if (options.thinking.budgetTokens !== undefined) {\n thinkingConfig.thinkingBudget = options.thinking.budgetTokens;\n }\n config.thinkingConfig = thinkingConfig;\n }\n else if (model.reasoning && options.thinking && !options.thinking.enabled) {\n config.thinkingConfig = getDisabledGoogleThinkingConfig(model);\n }\n if (options.signal) {\n if (options.signal.aborted) {\n throw new Error(\"Request aborted\");\n }\n config.abortSignal = options.signal;\n }\n const params = {\n model: model.id,\n contents,\n config,\n };\n return params;\n}\nfunction getGoogleBudget(model, level, customBudgets) {\n if (customBudgets?.[level] !== undefined) {\n return customBudgets[level];\n }\n if (model.id.includes(\"2.5-pro\")) {\n const budgets = {\n minimal: 128,\n low: 2048,\n medium: 8192,\n high: 32768,\n };\n return budgets[level];\n }\n if (model.id.includes(\"2.5-flash\")) {\n const budgets = {\n minimal: 128,\n low: 2048,\n medium: 8192,\n high: 24576,\n };\n return budgets[level];\n }\n return -1;\n}\n//# sourceMappingURL=google-vertex.js.map"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { AnyRouteMatch } from "@tanstack/react-router";
1
+ import { AnyRoute, AnyRouteMatch } from "@tanstack/react-router";
2
2
  //#region node_modules/schema-dts-lib/dist/index.d.ts
3
3
  /**
4
4
  * Minimal valid JSON-LD object.
@@ -2302,7 +2302,7 @@ interface CreativeWorkLeaf extends CreativeWorkBase {
2302
2302
  "@type": "CreativeWork";
2303
2303
  }
2304
2304
  /** The most generic kind of creative work, including books, movies, photographs, software programs, etc. */
2305
- type CreativeWork = CreativeWorkLeaf | AmpStory | ArchiveComponent | Article | Atlas | Blog | Book | Certification | Chapter | Claim | Clip | Code | Collection | ComicStory | Comment | Conversation | Course | CreativeWorkSeason | CreativeWorkSeries | Credential | DataCatalog | Dataset | DefinedTermSet | Diet | DigitalDocument | Drawing | Episode | ExercisePlan | Game | Guide | HowTo | HowToDirection | HowToSection | HowToStep | HowToTip | HyperToc | HyperTocEntry | LearningResource | Legislation | Manuscript | Map | MathSolver | MediaObject | MediaReviewItem | Menu | MenuSection | Message | Movie | MusicComposition | MusicPlaylist | MusicRecording | Painting | Photograph | Play | Poster | PublicationIssue | PublicationVolume | Quotation | Review | Sculpture | Season | SheetMusic | ShortStory | SoftwareApplication | SoftwareSourceCode | SpecialAnnouncement | Statement | Thesis | TVSeason | TVSeries | VisualArtwork | WebContent | WebPage | WebPageElement | WebSite;
2305
+ type CreativeWork = CreativeWorkLeaf | AmpStory | ArchiveComponent | Article | Atlas | Blog | Book | Certification | Chapter | Claim | Clip | Code | Collection | ComicStory | Comment | Conversation | Course | CreativeWorkSeason | CreativeWorkSeries | Credential | DataCatalog | Dataset | DefinedTermSet | Diet | DigitalDocument | Drawing | Episode | ExercisePlan | Game | Guide | HowTo | HowToDirection | HowToSection | HowToStep | HowToTip | HyperToc | HyperTocEntry | LearningResource | Legislation | Manuscript | Map$1 | MathSolver | MediaObject | MediaReviewItem | Menu | MenuSection | Message | Movie | MusicComposition | MusicPlaylist | MusicRecording | Painting | Photograph | Play | Poster | PublicationIssue | PublicationVolume | Quotation | Review | Sculpture | Season | SheetMusic | ShortStory | SoftwareApplication | SoftwareSourceCode | SpecialAnnouncement | Statement | Thesis | TVSeason | TVSeries | VisualArtwork | WebContent | WebPage | WebPageElement | WebSite;
2306
2306
  interface CreativeWorkSeasonBase extends CreativeWorkBase {
2307
2307
  /** An actor (individual or a group), e.g. in TV, radio, movie, video games etc., or in an event. Actors can be associated with individual items or with a series, episode, clip. */
2308
2308
  "actor"?: SchemaValue<PerformingGroup | Person | IdReference, "actor">;
@@ -5467,7 +5467,7 @@ interface MapLeaf extends MapBase {
5467
5467
  "@type": "Map";
5468
5468
  }
5469
5469
  /** A map. */
5470
- type Map = MapLeaf;
5470
+ type Map$1 = MapLeaf;
5471
5471
  interface MapCategoryTypeLeaf extends EnumerationBase {
5472
5472
  "@type": "MapCategoryType";
5473
5473
  }
@@ -8176,7 +8176,7 @@ interface PlaceBase extends ThingBase {
8176
8176
  */
8177
8177
  "hasGS1DigitalLink"?: SchemaValue<URL, "hasGS1DigitalLink">;
8178
8178
  /** A URL to a map of the place. */
8179
- "hasMap"?: SchemaValue<Map | URL | IdReference, "hasMap">;
8179
+ "hasMap"?: SchemaValue<Map$1 | URL | IdReference, "hasMap">;
8180
8180
  /** A flag to signal that the item, event, or place is accessible for free. */
8181
8181
  "isAccessibleForFree"?: SchemaValue<Boolean, "isAccessibleForFree">;
8182
8182
  /** The International Standard of Industrial Classification of All Economic Activities (ISIC), Revision 4 code for a particular organization, business person, or place. */
@@ -11996,6 +11996,7 @@ type Zoo = ZooLeaf | string;
11996
11996
  * interface Register {
11997
11997
  * paths: FileRouteTypes["fullPaths"];
11998
11998
  * kinds: "page" | "article" | "hub";
11999
+ * facts: typeof facts;
11999
12000
  * }
12000
12001
  * }
12001
12002
  * ```
@@ -12120,8 +12121,118 @@ declare function applyTitleTemplate(template: string | undefined, title: string)
12120
12121
  declare module "@tanstack/react-router" {
12121
12122
  interface StaticDataRouteOption {
12122
12123
  seo?: RouteSeo | undefined;
12124
+ /** How this route supplies its authored document. */
12125
+ markdown?: "rendered" | "source" | undefined;
12126
+ /** Group label for this page in llms.txt. */
12127
+ llms?: string | undefined;
12123
12128
  }
12124
12129
  }
12125
12130
  //#endregion
12126
- export { Thing as _, SeoFaq as a, IdReference as b, SitemapPolicy as c, BreadcrumbList as d, FAQPage as f, Service as g, Organization as h, RouteSeo as i, applyTitleTemplate as l, ItemList as m, PublicPath as n, SeoKind as o, Graph as p, Register as r, SeoPageHead as s, JsonLdDocument as t, Article as u, WebSite as v, WithContext as y };
12127
- //# sourceMappingURL=declare-DVgdEdOL.d.ts.map
12131
+ //#region src/core/graph.d.ts
12132
+ /**
12133
+ * Where a node came from: `"route"` for a structural route declaration, or the
12134
+ * `source` label of the collection that produced the instance (e.g. "blog").
12135
+ */
12136
+ type SeoSource = string;
12137
+ interface SeoNode {
12138
+ /** Canonical path, no origin (e.g. "/pricing", "/blog/my-post"). */
12139
+ path: string;
12140
+ kind: SeoKind;
12141
+ source: SeoSource;
12142
+ /** Route-declared authored-document mode, inherited by collection instances. */
12143
+ markdown?: "rendered" | "source" | undefined;
12144
+ /** Group label for llms.txt, inherited by collection instances. */
12145
+ llms?: string | undefined;
12146
+ /** Route-declared policy, or synthesized (kind + inherited sitemap) for instances. */
12147
+ policy: RouteSeo;
12148
+ /**
12149
+ * The head the page ships: a static route's declared `head`, or an instance's
12150
+ * title (through its route's `titleTemplate`) and description. Absent when the
12151
+ * route computes its head at request time and no collection supplies it.
12152
+ */
12153
+ head?: SeoNodeHead | undefined;
12154
+ instance?: {
12155
+ title: string;
12156
+ description?: string | undefined;
12157
+ publishedAt?: string | undefined;
12158
+ modifiedAt?: string | undefined;
12159
+ } | undefined;
12160
+ }
12161
+ /**
12162
+ * A node's head as graph data: the full title, description, and FAQ text. An
12163
+ * instance without a description still carries its title.
12164
+ */
12165
+ interface SeoNodeHead {
12166
+ readonly title: string;
12167
+ readonly description?: string | undefined;
12168
+ readonly faqs?: ReadonlyArray<{
12169
+ readonly question: string;
12170
+ readonly answer: string;
12171
+ }> | undefined;
12172
+ }
12173
+ type SeoEdgeType = "crumb-parent" | "related" | "redirect" | "collection-member";
12174
+ interface SeoEdge {
12175
+ from: string;
12176
+ to: string;
12177
+ type: SeoEdgeType;
12178
+ }
12179
+ interface SeoGraph {
12180
+ nodes: Map<string, SeoNode>;
12181
+ edges: Array<SeoEdge>;
12182
+ /** Exact-path ownership conflicts encountered while assembling graph sources. */
12183
+ collisions?: ReadonlyArray<{
12184
+ path: string;
12185
+ sources: ReadonlyArray<SeoSource>;
12186
+ }> | undefined;
12187
+ }
12188
+ /** One concrete page produced by a collection. */
12189
+ interface SeoInstance {
12190
+ /** Canonical path of the page (e.g. "/blog/my-post"). */
12191
+ readonly path: string;
12192
+ readonly title: string;
12193
+ readonly description?: string | undefined;
12194
+ readonly publishedAt?: string | undefined;
12195
+ readonly modifiedAt?: string | undefined;
12196
+ }
12197
+ interface SeoCollection {
12198
+ /**
12199
+ * The param route these instances render through (e.g. "/blog/$slug"). Instances
12200
+ * inherit this route's declared policy (kind + sitemap) — the graph reads it from
12201
+ * the structural node, so declarations stay the single source of truth.
12202
+ */
12203
+ readonly route: PublicPath;
12204
+ /** The `source` stamped on every node this collection produces (e.g. "blog"). */
12205
+ readonly source: SeoSource;
12206
+ readonly instances: ReadonlyArray<SeoInstance>;
12207
+ /** Edges the collection declares between its instances and the rest of the graph. */
12208
+ readonly edges?: ReadonlyArray<SeoEdge> | undefined;
12209
+ }
12210
+ /**
12211
+ * The structural route shape the graph walks: a TanStack route tree has it
12212
+ * before `init()`, and an adapter can build it from parsed route files.
12213
+ */
12214
+ interface SeoRouteNode {
12215
+ readonly options: {
12216
+ readonly path?: string | undefined;
12217
+ readonly staticData?: {
12218
+ readonly seo?: RouteSeo | undefined;
12219
+ readonly markdown?: SeoNode["markdown"];
12220
+ readonly llms?: SeoNode["llms"];
12221
+ } | undefined;
12222
+ };
12223
+ readonly children?: ReadonlyArray<SeoRouteNode> | undefined;
12224
+ }
12225
+ interface BuildSeoGraphInput {
12226
+ readonly routeTree: AnyRoute | SeoRouteNode;
12227
+ readonly collections?: ReadonlyArray<SeoCollection> | undefined;
12228
+ }
12229
+ /**
12230
+ * Build the SEO graph from route declarations and content collections.
12231
+ *
12232
+ * Synchronous: the caller materializes its collections before calling, so there is
12233
+ * no async work here. Callers own the origin.
12234
+ */
12235
+ declare function buildSeoGraph(input: BuildSeoGraphInput): SeoGraph;
12236
+ //#endregion
12237
+ export { WithContext as A, FAQPage as C, Service as D, Organization as E, Thing as O, BreadcrumbList as S, ItemList as T, SeoKind as _, SeoGraph as a, applyTitleTemplate as b, SeoNodeHead as c, buildSeoGraph as d, JsonLdDocument as f, SeoFaq as g, RouteSeo as h, SeoEdgeType as i, IdReference as j, WebSite as k, SeoRouteNode as l, Register as m, SeoCollection as n, SeoInstance as o, PublicPath as p, SeoEdge as r, SeoNode as s, BuildSeoGraphInput as t, SeoSource as u, SeoPageHead as v, Graph as w, Article as x, SitemapPolicy as y };
12238
+ //# sourceMappingURL=graph-D1PIndsC.d.ts.map
@@ -47,22 +47,30 @@ function mergeSeo(base, override) {
47
47
  */
48
48
  function walkRoutes(route, parentPath, isRoot, nodes, edges, crumbStack) {
49
49
  const path = isRoot ? "/" : joinPath(parentPath, route.options.path);
50
- const seo = route.options.staticData?.seo;
51
- if (seo) {
50
+ const data = route.options.staticData;
51
+ const seo = data?.seo;
52
+ if (seo || data?.markdown !== void 0 || data?.llms !== void 0) {
52
53
  const existing = nodes.get(path);
53
54
  if (existing) {
54
- existing.policy = mergeSeo(existing.policy, seo);
55
+ if (seo) existing.policy = mergeSeo(existing.policy, seo);
55
56
  existing.kind = existing.policy.kind;
56
- existing.head = declaredHead(seo) ?? existing.head;
57
- } else nodes.set(path, {
58
- path,
59
- kind: seo.kind,
60
- source: "route",
61
- policy: { ...seo },
62
- head: declaredHead(seo)
63
- });
57
+ existing.head = (seo && declaredHead(seo)) ?? existing.head;
58
+ existing.markdown = data?.markdown ?? existing.markdown;
59
+ existing.llms = data?.llms ?? existing.llms;
60
+ } else {
61
+ const policy = seo ?? { kind: FALLBACK_KIND };
62
+ nodes.set(path, {
63
+ path,
64
+ kind: policy.kind,
65
+ source: "route",
66
+ policy: { ...policy },
67
+ head: seo && declaredHead(seo),
68
+ markdown: data?.markdown,
69
+ llms: data?.llms
70
+ });
71
+ }
64
72
  const nearestCrumbAncestor = crumbStack[crumbStack.length - 1];
65
- if (seo.crumb !== void 0 && nearestCrumbAncestor !== void 0) edges.push({
73
+ if (seo?.crumb !== void 0 && nearestCrumbAncestor !== void 0) edges.push({
66
74
  from: path,
67
75
  to: nearestCrumbAncestor,
68
76
  type: "crumb-parent"
@@ -104,6 +112,8 @@ function addCollection(nodes, edges, collisions, collection) {
104
112
  path: instance.path,
105
113
  kind,
106
114
  source: collection.source,
115
+ markdown: collectionNode?.markdown,
116
+ llms: collectionNode?.llms,
107
117
  policy: {
108
118
  kind,
109
119
  sitemap
@@ -159,4 +169,4 @@ function buildSeoGraph(input) {
159
169
  //#endregion
160
170
  export { buildSeoGraph as t };
161
171
 
162
- //# sourceMappingURL=graph-Bcsourlv.js.map
172
+ //# sourceMappingURL=graph-DMNOLXLu.js.map