pi2dsh 0.13.2 → 0.13.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 (106) hide show
  1. package/README.md +22 -19
  2. package/README.zh.md +18 -15
  3. package/dist/{analyzer-CJFwQlSG.mjs → analyzer-DBtUYKI1.mjs} +2 -2
  4. package/dist/{analyzer-CJFwQlSG.mjs.map → analyzer-DBtUYKI1.mjs.map} +1 -1
  5. package/dist/anthropic-messages-CaYTgvLF.mjs +6436 -0
  6. package/dist/anthropic-messages-CaYTgvLF.mjs.map +1 -0
  7. package/dist/azure-openai-responses-HKWkzl2m.mjs +208 -0
  8. package/dist/azure-openai-responses-HKWkzl2m.mjs.map +1 -0
  9. package/dist/cli.mjs +3 -2
  10. package/dist/cli.mjs.map +1 -1
  11. package/dist/compat/pi-ai.d.mts +3 -2636
  12. package/dist/compat/pi-ai.mjs +3 -2
  13. package/dist/compat/pi-coding-agent.d.mts +2 -2
  14. package/dist/compat/pi-coding-agent.mjs +2 -2
  15. package/dist/{mcp-config-_idn-pzI.mjs → compatibility-Bz6ZXA7F.mjs} +8 -185
  16. package/dist/compatibility-Bz6ZXA7F.mjs.map +1 -0
  17. package/dist/completionchunk-Dhk56lZl.mjs +5212 -0
  18. package/dist/completionchunk-Dhk56lZl.mjs.map +1 -0
  19. package/dist/{credentials-oauth-Txs6oew8.mjs → credentials-oauth-CAohSLcB.mjs} +3 -3
  20. package/dist/{credentials-oauth-Txs6oew8.mjs.map → credentials-oauth-CAohSLcB.mjs.map} +1 -1
  21. package/dist/credentials-oauth.mjs +1 -1
  22. package/dist/deferred-tools-BD4g5QUx.mjs +32 -0
  23. package/dist/deferred-tools-BD4g5QUx.mjs.map +1 -0
  24. package/dist/diagnostics-BqYkodgB.mjs +35 -0
  25. package/dist/diagnostics-BqYkodgB.mjs.map +1 -0
  26. package/dist/dist-QBBA-dL_.mjs +1246 -0
  27. package/dist/dist-QBBA-dL_.mjs.map +1 -0
  28. package/dist/error-body-DKA3lknR.mjs +104 -0
  29. package/dist/error-body-DKA3lknR.mjs.map +1 -0
  30. package/dist/event-stream-QxN1yvIF.mjs +64 -0
  31. package/dist/event-stream-QxN1yvIF.mjs.map +1 -0
  32. package/dist/from-BCscBQ9P.mjs +3856 -0
  33. package/dist/from-BCscBQ9P.mjs.map +1 -0
  34. package/dist/github-copilot-headers-CZo2QHrt.mjs +25 -0
  35. package/dist/github-copilot-headers-CZo2QHrt.mjs.map +1 -0
  36. package/dist/google-generative-ai-2gCFYp-t.mjs +356 -0
  37. package/dist/google-generative-ai-2gCFYp-t.mjs.map +1 -0
  38. package/dist/google-shared-75IdVyrx.mjs +29041 -0
  39. package/dist/google-shared-75IdVyrx.mjs.map +1 -0
  40. package/dist/google-vertex-Bhyo4z2i.mjs +400 -0
  41. package/dist/google-vertex-Bhyo4z2i.mjs.map +1 -0
  42. package/dist/hash-Dbggamac.mjs +19 -0
  43. package/dist/hash-Dbggamac.mjs.map +1 -0
  44. package/dist/headers-CPzZhJQn.mjs +17 -0
  45. package/dist/headers-CPzZhJQn.mjs.map +1 -0
  46. package/dist/host.d.mts +12 -2
  47. package/dist/host.d.mts.map +1 -1
  48. package/dist/host.mjs +43 -5
  49. package/dist/host.mjs.map +1 -1
  50. package/dist/index.d.mts +5 -3
  51. package/dist/index.d.mts.map +1 -1
  52. package/dist/index.mjs +40 -16
  53. package/dist/index.mjs.map +1 -1
  54. package/dist/json-parse-CZ0U0sj_.mjs +384 -0
  55. package/dist/json-parse-CZ0U0sj_.mjs.map +1 -0
  56. package/dist/mcp-config-jmzbgdHa.mjs +181 -0
  57. package/dist/mcp-config-jmzbgdHa.mjs.map +1 -0
  58. package/dist/mistral-conversations-DJyeTo8C.mjs +36921 -0
  59. package/dist/mistral-conversations-DJyeTo8C.mjs.map +1 -0
  60. package/dist/multipart-parser-SRcGkVuX.mjs +301 -0
  61. package/dist/multipart-parser-SRcGkVuX.mjs.map +1 -0
  62. package/dist/{pi-ai-D7PqVeWs.mjs → openai-DkzRh5_G.mjs} +78 -5063
  63. package/dist/openai-DkzRh5_G.mjs.map +1 -0
  64. package/dist/openai-codex-responses-DedxQjNG.mjs +1220 -0
  65. package/dist/openai-codex-responses-DedxQjNG.mjs.map +1 -0
  66. package/dist/openai-completions-DrjrWRdX.mjs +945 -0
  67. package/dist/openai-completions-DrjrWRdX.mjs.map +1 -0
  68. package/dist/openai-prompt-cache-BDWtZRKh.mjs +11 -0
  69. package/dist/openai-prompt-cache-BDWtZRKh.mjs.map +1 -0
  70. package/dist/openai-responses-BRdGpBX6.mjs +251 -0
  71. package/dist/openai-responses-BRdGpBX6.mjs.map +1 -0
  72. package/dist/openai-responses-shared-BmnSvdKL.mjs +570 -0
  73. package/dist/openai-responses-shared-BmnSvdKL.mjs.map +1 -0
  74. package/dist/otel-CBhmS-NR.mjs +24935 -0
  75. package/dist/otel-CBhmS-NR.mjs.map +1 -0
  76. package/dist/pi-ai-CfokFhIL.d.mts +2673 -0
  77. package/dist/pi-ai-CfokFhIL.d.mts.map +1 -0
  78. package/dist/pi-ai-Dh7HUxbt.mjs +3239 -0
  79. package/dist/pi-ai-Dh7HUxbt.mjs.map +1 -0
  80. package/dist/{pi-coding-agent-B0PT23gE.d.mts → pi-coding-agent-69yY0ke-.d.mts} +4 -2
  81. package/dist/{pi-coding-agent-B0PT23gE.d.mts.map → pi-coding-agent-69yY0ke-.d.mts.map} +1 -1
  82. package/dist/{pi-coding-agent-BVZu0dHG.mjs → pi-coding-agent-Cvez0jkF.mjs} +0 -0
  83. package/dist/{pi-coding-agent-BVZu0dHG.mjs.map → pi-coding-agent-Cvez0jkF.mjs.map} +1 -1
  84. package/dist/pi-messages-D61G2tgs.mjs +307 -0
  85. package/dist/pi-messages-D61G2tgs.mjs.map +1 -0
  86. package/dist/provider-env-C72pF4vP.mjs +40 -0
  87. package/dist/provider-env-C72pF4vP.mjs.map +1 -0
  88. package/dist/provider-retry-Cw6YJ4cr.mjs +80 -0
  89. package/dist/provider-retry-Cw6YJ4cr.mjs.map +1 -0
  90. package/dist/rolldown-runtime-CTfmNlz1.mjs +44 -0
  91. package/dist/{runtime-DEjs_Qlf.mjs → runtime-Dd2KhoX-.mjs} +659 -125
  92. package/dist/runtime-Dd2KhoX-.mjs.map +1 -0
  93. package/dist/runtime.d.mts +135 -26
  94. package/dist/runtime.d.mts.map +1 -1
  95. package/dist/runtime.mjs +1 -1
  96. package/dist/simple-options-B_GO8FDE.mjs +456 -0
  97. package/dist/simple-options-B_GO8FDE.mjs.map +1 -0
  98. package/dist/src-DlTagfW5.mjs +1186 -0
  99. package/dist/src-DlTagfW5.mjs.map +1 -0
  100. package/dist/{types-7IWJPPvS.d.mts → types-B9VBF8le.d.mts} +2 -9
  101. package/dist/{types-7IWJPPvS.d.mts.map → types-B9VBF8le.d.mts.map} +1 -1
  102. package/package.json +2 -2
  103. package/dist/compat/pi-ai.d.mts.map +0 -1
  104. package/dist/mcp-config-_idn-pzI.mjs.map +0 -1
  105. package/dist/pi-ai-D7PqVeWs.mjs.map +0 -1
  106. package/dist/runtime-DEjs_Qlf.mjs.map +0 -1
@@ -0,0 +1,400 @@
1
+
2
+ import { t as AssistantMessageEventStream } from "./event-stream-QxN1yvIF.mjs";
3
+ import { m as clampThinkingLevel, p as calculateCost, r as buildBaseOptions, s as sanitizeSurrogates } from "./simple-options-B_GO8FDE.mjs";
4
+ import { n as normalizeProviderError, t as formatProviderError } from "./error-body-DKA3lknR.mjs";
5
+ import { n as providerHeadersToRecord } from "./headers-CPzZhJQn.mjs";
6
+ import { t as getProviderEnvValue } from "./provider-env-C72pF4vP.mjs";
7
+ import { a as resolveGoogleFunctionCallingMode, c as supportsGoogleStrictToolSampling, d as ThinkingLevel, i as mapStopReason, l as GoogleGenAI, n as convertTools, o as retainThoughtSignature, r as isThinkingPart, s as retryGoogleRequest, t as convertMessages, u as ResourceScope } from "./google-shared-75IdVyrx.mjs";
8
+ //#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js
9
+ const API_VERSION = "v1";
10
+ const GCP_VERTEX_CREDENTIALS_MARKER = "gcp-vertex-credentials";
11
+ const THINKING_LEVEL_MAP = {
12
+ THINKING_LEVEL_UNSPECIFIED: ThinkingLevel.THINKING_LEVEL_UNSPECIFIED,
13
+ MINIMAL: ThinkingLevel.MINIMAL,
14
+ LOW: ThinkingLevel.LOW,
15
+ MEDIUM: ThinkingLevel.MEDIUM,
16
+ HIGH: ThinkingLevel.HIGH
17
+ };
18
+ let toolCallCounter = 0;
19
+ const stream = (model, context, options) => {
20
+ const stream = new AssistantMessageEventStream();
21
+ (async () => {
22
+ const output = {
23
+ role: "assistant",
24
+ content: [],
25
+ api: "google-vertex",
26
+ provider: model.provider,
27
+ model: model.id,
28
+ usage: {
29
+ input: 0,
30
+ output: 0,
31
+ cacheRead: 0,
32
+ cacheWrite: 0,
33
+ totalTokens: 0,
34
+ cost: {
35
+ input: 0,
36
+ output: 0,
37
+ cacheRead: 0,
38
+ cacheWrite: 0,
39
+ total: 0
40
+ }
41
+ },
42
+ stopReason: "pending",
43
+ timestamp: Date.now()
44
+ };
45
+ try {
46
+ if (options?.fetch && options.fetch !== globalThis.fetch) throw new Error("Custom fetch is not supported by the Google Vertex adapter");
47
+ const apiKey = resolveApiKey(options);
48
+ const client = apiKey ? createClientWithApiKey(model, apiKey, options?.headers) : createClient(model, resolveProject(options), resolveLocation(options), options?.headers, options?.env);
49
+ let params = buildParams(model, context, options);
50
+ const nextParams = await options?.onPayload?.(params, model);
51
+ if (nextParams !== void 0) params = nextParams;
52
+ const googleStream = await retryGoogleRequest(() => client.models.generateContentStream(params), options);
53
+ stream.push({
54
+ type: "start",
55
+ partial: output
56
+ });
57
+ let currentBlock = null;
58
+ const blocks = output.content;
59
+ const blockIndex = () => blocks.length - 1;
60
+ for await (const chunk of googleStream) {
61
+ output.responseId ||= chunk.responseId;
62
+ const candidate = chunk.candidates?.[0];
63
+ if (candidate?.content?.parts) for (const part of candidate.content.parts) {
64
+ if (part.text !== void 0) {
65
+ const isThinking = isThinkingPart(part);
66
+ if (!currentBlock || isThinking && currentBlock.type !== "thinking" || !isThinking && currentBlock.type !== "text") {
67
+ if (currentBlock) {
68
+ if (currentBlock.type === "text") stream.push({
69
+ type: "text_end",
70
+ contentIndex: blocks.length - 1,
71
+ content: currentBlock.text,
72
+ partial: output
73
+ });
74
+ else stream.push({
75
+ type: "thinking_end",
76
+ contentIndex: blockIndex(),
77
+ content: currentBlock.thinking,
78
+ partial: output
79
+ });
80
+ }
81
+ if (isThinking) {
82
+ currentBlock = {
83
+ type: "thinking",
84
+ thinking: "",
85
+ thinkingSignature: void 0
86
+ };
87
+ output.content.push(currentBlock);
88
+ stream.push({
89
+ type: "thinking_start",
90
+ contentIndex: blockIndex(),
91
+ partial: output
92
+ });
93
+ } else {
94
+ currentBlock = {
95
+ type: "text",
96
+ text: ""
97
+ };
98
+ output.content.push(currentBlock);
99
+ stream.push({
100
+ type: "text_start",
101
+ contentIndex: blockIndex(),
102
+ partial: output
103
+ });
104
+ }
105
+ }
106
+ if (currentBlock.type === "thinking") {
107
+ currentBlock.thinking += part.text;
108
+ currentBlock.thinkingSignature = retainThoughtSignature(currentBlock.thinkingSignature, part.thoughtSignature);
109
+ stream.push({
110
+ type: "thinking_delta",
111
+ contentIndex: blockIndex(),
112
+ delta: part.text,
113
+ partial: output
114
+ });
115
+ } else {
116
+ currentBlock.text += part.text;
117
+ currentBlock.textSignature = retainThoughtSignature(currentBlock.textSignature, part.thoughtSignature);
118
+ stream.push({
119
+ type: "text_delta",
120
+ contentIndex: blockIndex(),
121
+ delta: part.text,
122
+ partial: output
123
+ });
124
+ }
125
+ }
126
+ if (part.functionCall) {
127
+ if (currentBlock) {
128
+ if (currentBlock.type === "text") stream.push({
129
+ type: "text_end",
130
+ contentIndex: blockIndex(),
131
+ content: currentBlock.text,
132
+ partial: output
133
+ });
134
+ else stream.push({
135
+ type: "thinking_end",
136
+ contentIndex: blockIndex(),
137
+ content: currentBlock.thinking,
138
+ partial: output
139
+ });
140
+ currentBlock = null;
141
+ }
142
+ const providedId = part.functionCall.id;
143
+ const toolCall = {
144
+ type: "toolCall",
145
+ id: !providedId || output.content.some((b) => b.type === "toolCall" && b.id === providedId) ? `${part.functionCall.name}_${Date.now()}_${++toolCallCounter}` : providedId,
146
+ name: part.functionCall.name || "",
147
+ arguments: part.functionCall.args ?? {},
148
+ ...part.thoughtSignature && { thoughtSignature: part.thoughtSignature }
149
+ };
150
+ output.content.push(toolCall);
151
+ stream.push({
152
+ type: "toolcall_start",
153
+ contentIndex: blockIndex(),
154
+ partial: output
155
+ });
156
+ stream.push({
157
+ type: "toolcall_delta",
158
+ contentIndex: blockIndex(),
159
+ delta: JSON.stringify(toolCall.arguments),
160
+ partial: output
161
+ });
162
+ stream.push({
163
+ type: "toolcall_end",
164
+ contentIndex: blockIndex(),
165
+ toolCall,
166
+ partial: output
167
+ });
168
+ }
169
+ }
170
+ if (candidate?.finishReason) {
171
+ output.rawStopReason = candidate.finishReason;
172
+ output.stopReason = mapStopReason(candidate.finishReason);
173
+ if (output.content.some((b) => b.type === "toolCall")) output.stopReason = "toolUse";
174
+ }
175
+ if (chunk.usageMetadata) {
176
+ output.usage = {
177
+ input: (chunk.usageMetadata.promptTokenCount || 0) - (chunk.usageMetadata.cachedContentTokenCount || 0),
178
+ output: (chunk.usageMetadata.candidatesTokenCount || 0) + (chunk.usageMetadata.thoughtsTokenCount || 0),
179
+ cacheRead: chunk.usageMetadata.cachedContentTokenCount || 0,
180
+ cacheWrite: 0,
181
+ reasoning: chunk.usageMetadata.thoughtsTokenCount || 0,
182
+ totalTokens: chunk.usageMetadata.totalTokenCount || 0,
183
+ cost: {
184
+ input: 0,
185
+ output: 0,
186
+ cacheRead: 0,
187
+ cacheWrite: 0,
188
+ total: 0
189
+ }
190
+ };
191
+ calculateCost(model, output.usage);
192
+ }
193
+ }
194
+ if (currentBlock) {
195
+ if (currentBlock.type === "text") stream.push({
196
+ type: "text_end",
197
+ contentIndex: blockIndex(),
198
+ content: currentBlock.text,
199
+ partial: output
200
+ });
201
+ else stream.push({
202
+ type: "thinking_end",
203
+ contentIndex: blockIndex(),
204
+ content: currentBlock.thinking,
205
+ partial: output
206
+ });
207
+ }
208
+ if (options?.signal?.aborted) throw new Error("Request was aborted");
209
+ if (output.stopReason === "pending") throw new Error("Google Vertex stream ended without a finish reason");
210
+ if (output.stopReason === "aborted" || output.stopReason === "error") {
211
+ const errorMessage = output.rawStopReason ? `Provider stopped with: ${output.rawStopReason}` : "An unknown error occurred";
212
+ throw new Error(errorMessage);
213
+ }
214
+ stream.push({
215
+ type: "done",
216
+ reason: output.stopReason,
217
+ message: output
218
+ });
219
+ stream.end();
220
+ } catch (error) {
221
+ for (const block of output.content) if ("index" in block) delete block.index;
222
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
223
+ output.errorMessage = formatProviderError(normalizeProviderError(error));
224
+ stream.push({
225
+ type: "error",
226
+ reason: output.stopReason,
227
+ error: output
228
+ });
229
+ stream.end();
230
+ }
231
+ })();
232
+ return stream;
233
+ };
234
+ const streamSimple = (model, context, options) => {
235
+ const base = buildBaseOptions(model, context, options, void 0);
236
+ if (!options?.reasoning) return stream(model, context, {
237
+ ...base,
238
+ thinking: { enabled: false }
239
+ });
240
+ const clampedReasoning = clampThinkingLevel(model, options.reasoning);
241
+ const effort = clampedReasoning === "off" ? "high" : clampedReasoning;
242
+ const geminiModel = model;
243
+ if (isGemini3ProModel(geminiModel) || isGemini3FlashModel(geminiModel)) return stream(model, context, {
244
+ ...base,
245
+ thinking: {
246
+ enabled: true,
247
+ level: getGemini3ThinkingLevel(effort, geminiModel)
248
+ }
249
+ });
250
+ return stream(model, context, {
251
+ ...base,
252
+ thinking: {
253
+ enabled: true,
254
+ budgetTokens: getGoogleBudget(geminiModel, effort, options.thinkingBudgets)
255
+ }
256
+ });
257
+ };
258
+ function createClient(model, project, location, optionsHeaders, env) {
259
+ const googleAuthOptions = buildGoogleAuthOptions(env);
260
+ return new GoogleGenAI({
261
+ vertexai: true,
262
+ project,
263
+ location,
264
+ apiVersion: API_VERSION,
265
+ ...googleAuthOptions ? { googleAuthOptions } : {},
266
+ httpOptions: buildHttpOptions(model, optionsHeaders)
267
+ });
268
+ }
269
+ function createClientWithApiKey(model, apiKey, optionsHeaders) {
270
+ return new GoogleGenAI({
271
+ vertexai: true,
272
+ apiKey,
273
+ apiVersion: API_VERSION,
274
+ httpOptions: buildHttpOptions(model, optionsHeaders)
275
+ });
276
+ }
277
+ function buildHttpOptions(model, optionsHeaders) {
278
+ const httpOptions = {};
279
+ const baseUrl = resolveCustomBaseUrl(model.baseUrl);
280
+ if (baseUrl) {
281
+ httpOptions.baseUrl = baseUrl;
282
+ httpOptions.baseUrlResourceScope = ResourceScope.COLLECTION;
283
+ if (baseUrlIncludesApiVersion(baseUrl)) httpOptions.apiVersion = "";
284
+ }
285
+ const headers = providerHeadersToRecord({
286
+ ...model.headers,
287
+ ...optionsHeaders
288
+ });
289
+ if (headers) httpOptions.headers = headers;
290
+ return Object.keys(httpOptions).length > 0 ? httpOptions : void 0;
291
+ }
292
+ function resolveCustomBaseUrl(baseUrl) {
293
+ const trimmed = baseUrl.trim();
294
+ if (!trimmed || trimmed.includes("{location}")) return;
295
+ return trimmed;
296
+ }
297
+ function baseUrlIncludesApiVersion(baseUrl) {
298
+ try {
299
+ return new URL(baseUrl).pathname.split("/").some((part) => /^v\d+(?:beta\d*)?$/.test(part));
300
+ } catch {
301
+ return /(?:^|\/)v\d+(?:beta\d*)?(?:\/|$)/.test(baseUrl);
302
+ }
303
+ }
304
+ function buildGoogleAuthOptions(env) {
305
+ const keyFilename = getProviderEnvValue("GOOGLE_APPLICATION_CREDENTIALS", env);
306
+ return keyFilename ? { keyFilename } : void 0;
307
+ }
308
+ function resolveApiKey(options) {
309
+ const apiKey = options?.apiKey?.trim();
310
+ if (!apiKey || apiKey === GCP_VERTEX_CREDENTIALS_MARKER || isPlaceholderApiKey(apiKey)) return;
311
+ return apiKey;
312
+ }
313
+ function isPlaceholderApiKey(apiKey) {
314
+ return /^<[^>]+>$/.test(apiKey);
315
+ }
316
+ function resolveProject(options) {
317
+ const project = options?.project || getProviderEnvValue("GOOGLE_CLOUD_PROJECT", options?.env) || getProviderEnvValue("GCLOUD_PROJECT", options?.env);
318
+ if (!project) throw new Error("Vertex AI requires a project ID. Set GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT or pass project in options.");
319
+ return project;
320
+ }
321
+ function resolveLocation(options) {
322
+ const location = options?.location || getProviderEnvValue("GOOGLE_CLOUD_LOCATION", options?.env);
323
+ if (!location) throw new Error("Vertex AI requires a location. Set GOOGLE_CLOUD_LOCATION or pass location in options.");
324
+ return location;
325
+ }
326
+ function buildParams(model, context, options = {}) {
327
+ const contents = convertMessages(model, context);
328
+ const generationConfig = {};
329
+ if (options.temperature !== void 0) generationConfig.temperature = options.temperature;
330
+ if (options.maxTokens !== void 0) generationConfig.maxOutputTokens = options.maxTokens;
331
+ const functionCallingMode = context.tools?.length ? resolveGoogleFunctionCallingMode(context.tools, options.toolChoice, supportsGoogleStrictToolSampling(model.id)) : void 0;
332
+ const config = {
333
+ ...Object.keys(generationConfig).length > 0 && generationConfig,
334
+ ...context.systemPrompt && { systemInstruction: sanitizeSurrogates(context.systemPrompt) },
335
+ ...context.tools && context.tools.length > 0 && { tools: convertTools(context.tools) },
336
+ ...functionCallingMode !== void 0 && { toolConfig: { functionCallingConfig: { mode: functionCallingMode } } }
337
+ };
338
+ if (options.thinking?.enabled && model.reasoning) {
339
+ const thinkingConfig = { includeThoughts: true };
340
+ if (options.thinking.level !== void 0) thinkingConfig.thinkingLevel = THINKING_LEVEL_MAP[options.thinking.level];
341
+ else if (options.thinking.budgetTokens !== void 0) thinkingConfig.thinkingBudget = options.thinking.budgetTokens;
342
+ config.thinkingConfig = thinkingConfig;
343
+ } else if (model.reasoning && options.thinking && !options.thinking.enabled) config.thinkingConfig = getDisabledThinkingConfig(model);
344
+ if (options.signal) {
345
+ if (options.signal.aborted) throw new Error("Request aborted");
346
+ config.abortSignal = options.signal;
347
+ }
348
+ return {
349
+ model: model.id,
350
+ contents,
351
+ config
352
+ };
353
+ }
354
+ function isGemini3ProModel(model) {
355
+ return /gemini-3(?:\.\d+)?-pro/.test(model.id.toLowerCase());
356
+ }
357
+ function isGemini3FlashModel(model) {
358
+ const id = model.id.toLowerCase();
359
+ return /gemini-3(?:\.\d+)?-flash/.test(id) || id === "gemini-flash-latest" || id === "gemini-flash-lite-latest";
360
+ }
361
+ function getDisabledThinkingConfig(model) {
362
+ const geminiModel = model;
363
+ if (isGemini3ProModel(geminiModel)) return { thinkingLevel: ThinkingLevel.LOW };
364
+ if (isGemini3FlashModel(geminiModel)) return { thinkingLevel: ThinkingLevel.MINIMAL };
365
+ return { thinkingBudget: 0 };
366
+ }
367
+ function getGemini3ThinkingLevel(effort, model) {
368
+ if (isGemini3ProModel(model)) switch (effort) {
369
+ case "minimal":
370
+ case "low": return "LOW";
371
+ case "medium":
372
+ case "high": return "HIGH";
373
+ }
374
+ switch (effort) {
375
+ case "minimal": return "MINIMAL";
376
+ case "low": return "LOW";
377
+ case "medium": return "MEDIUM";
378
+ case "high": return "HIGH";
379
+ }
380
+ }
381
+ function getGoogleBudget(model, effort, customBudgets) {
382
+ if (customBudgets?.[effort] !== void 0) return customBudgets[effort];
383
+ if (model.id.includes("2.5-pro")) return {
384
+ minimal: 128,
385
+ low: 2048,
386
+ medium: 8192,
387
+ high: 32768
388
+ }[effort];
389
+ if (model.id.includes("2.5-flash")) return {
390
+ minimal: 128,
391
+ low: 2048,
392
+ medium: 8192,
393
+ high: 24576
394
+ }[effort];
395
+ return -1;
396
+ }
397
+ //#endregion
398
+ export { stream, streamSimple };
399
+
400
+ //# sourceMappingURL=google-vertex-Bhyo4z2i.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-vertex-Bhyo4z2i.mjs","names":[],"sources":["../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js"],"sourcesContent":["import { GoogleGenAI, ResourceScope, ThinkingLevel, } 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 { getProviderEnvValue } from \"../utils/provider-env.js\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.js\";\nimport { convertMessages, convertTools, isThinkingPart, mapStopReason, resolveGoogleFunctionCallingMode, retainThoughtSignature, retryGoogleRequest, supportsGoogleStrictToolSampling, } from \"./google-shared.js\";\nimport { buildBaseOptions } from \"./simple-options.js\";\nconst API_VERSION = \"v1\";\nconst GCP_VERTEX_CREDENTIALS_MARKER = \"gcp-vertex-credentials\";\nconst THINKING_LEVEL_MAP = {\n THINKING_LEVEL_UNSPECIFIED: ThinkingLevel.THINKING_LEVEL_UNSPECIFIED,\n MINIMAL: ThinkingLevel.MINIMAL,\n LOW: ThinkingLevel.LOW,\n MEDIUM: ThinkingLevel.MEDIUM,\n HIGH: ThinkingLevel.HIGH,\n};\n// Counter for generating unique tool call IDs\nlet toolCallCounter = 0;\nexport const stream = (model, context, options) => {\n const stream = new AssistantMessageEventStream();\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, context, 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 // 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\")) {\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 = buildBaseOptions(model, context, options, undefined);\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 const effort = (clampedReasoning === \"off\" ? \"high\" : clampedReasoning);\n const geminiModel = model;\n if (isGemini3ProModel(geminiModel) || isGemini3FlashModel(geminiModel)) {\n return stream(model, context, {\n ...base,\n thinking: {\n enabled: true,\n level: getGemini3ThinkingLevel(effort, geminiModel),\n },\n });\n }\n return stream(model, context, {\n ...base,\n thinking: {\n enabled: true,\n budgetTokens: getGoogleBudget(geminiModel, effort, 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({ ...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 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 functionCallingMode = context.tools?.length\n ? resolveGoogleFunctionCallingMode(context.tools, options.toolChoice, supportsGoogleStrictToolSampling(model.id))\n : undefined;\n const config = {\n ...(Object.keys(generationConfig).length > 0 && generationConfig),\n ...(context.systemPrompt && { systemInstruction: sanitizeSurrogates(context.systemPrompt) }),\n ...(context.tools && context.tools.length > 0 && { tools: convertTools(context.tools) }),\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 = THINKING_LEVEL_MAP[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 = getDisabledThinkingConfig(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 isGemini3ProModel(model) {\n return /gemini-3(?:\\.\\d+)?-pro/.test(model.id.toLowerCase());\n}\nfunction isGemini3FlashModel(model) {\n const id = model.id.toLowerCase();\n return /gemini-3(?:\\.\\d+)?-flash/.test(id) || id === \"gemini-flash-latest\" || id === \"gemini-flash-lite-latest\";\n}\nfunction getDisabledThinkingConfig(model) {\n // Google docs: Gemini 3.1 Pro cannot disable thinking, and Gemini 3 Flash / Flash-Lite\n // do not support full thinking-off either. For Gemini 3 models, use the lowest supported\n // thinkingLevel without includeThoughts so hidden thinking remains invisible to pi.\n const geminiModel = model;\n if (isGemini3ProModel(geminiModel)) {\n return { thinkingLevel: ThinkingLevel.LOW };\n }\n if (isGemini3FlashModel(geminiModel)) {\n return { thinkingLevel: ThinkingLevel.MINIMAL };\n }\n // Gemini 2.x supports disabling via thinkingBudget = 0.\n return { thinkingBudget: 0 };\n}\nfunction getGemini3ThinkingLevel(effort, model) {\n if (isGemini3ProModel(model)) {\n switch (effort) {\n case \"minimal\":\n case \"low\":\n return \"LOW\";\n case \"medium\":\n case \"high\":\n return \"HIGH\";\n }\n }\n switch (effort) {\n case \"minimal\":\n return \"MINIMAL\";\n case \"low\":\n return \"LOW\";\n case \"medium\":\n return \"MEDIUM\";\n case \"high\":\n return \"HIGH\";\n }\n}\nfunction getGoogleBudget(model, effort, customBudgets) {\n if (customBudgets?.[effort] !== undefined) {\n return customBudgets[effort];\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[effort];\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[effort];\n }\n return -1;\n}\n//# sourceMappingURL=google-vertex.js.map"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+
2
+ //#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/hash.js
3
+ /** Fast deterministic hash to shorten long strings */
4
+ function shortHash(str) {
5
+ let h1 = 3735928559;
6
+ let h2 = 1103547991;
7
+ for (let i = 0; i < str.length; i++) {
8
+ const ch = str.charCodeAt(i);
9
+ h1 = Math.imul(h1 ^ ch, 2654435761);
10
+ h2 = Math.imul(h2 ^ ch, 1597334677);
11
+ }
12
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
13
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
14
+ return (h2 >>> 0).toString(36) + (h1 >>> 0).toString(36);
15
+ }
16
+ //#endregion
17
+ export { shortHash as t };
18
+
19
+ //# sourceMappingURL=hash-Dbggamac.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-Dbggamac.mjs","names":[],"sources":["../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/hash.js"],"sourcesContent":["/** Fast deterministic hash to shorten long strings */\nexport function shortHash(str) {\n let h1 = 0xdeadbeef;\n let h2 = 0x41c6ce57;\n for (let i = 0; i < str.length; i++) {\n const ch = str.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n return (h2 >>> 0).toString(36) + (h1 >>> 0).toString(36);\n}\n//# sourceMappingURL=hash.js.map"],"x_google_ignoreList":[0],"mappings":";;;AACA,SAAgB,UAAU,KAAK;CAC3B,IAAI,KAAK;CACT,IAAI,KAAK;CACT,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;EACjC,MAAM,KAAK,IAAI,WAAW,CAAC;EAC3B,KAAK,KAAK,KAAK,KAAK,IAAI,UAAU;EAClC,KAAK,KAAK,KAAK,KAAK,IAAI,UAAU;CACtC;CACA,KAAK,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU,IAAI,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU;CACrF,KAAK,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU,IAAI,KAAK,KAAK,KAAM,OAAO,IAAK,UAAU;CACrF,QAAQ,OAAO,EAAA,CAAG,SAAS,EAAE,KAAK,OAAO,EAAA,CAAG,SAAS,EAAE;AAC3D"}
@@ -0,0 +1,17 @@
1
+
2
+ //#region node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/headers.js
3
+ function headersToRecord(headers) {
4
+ const result = {};
5
+ for (const [key, value] of headers.entries()) result[key] = value;
6
+ return result;
7
+ }
8
+ function providerHeadersToRecord(headers) {
9
+ if (!headers) return void 0;
10
+ const result = {};
11
+ for (const [key, value] of Object.entries(headers)) if (value !== null) result[key] = value;
12
+ return Object.keys(result).length > 0 ? result : void 0;
13
+ }
14
+ //#endregion
15
+ export { providerHeadersToRecord as n, headersToRecord as t };
16
+
17
+ //# sourceMappingURL=headers-CPzZhJQn.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers-CPzZhJQn.mjs","names":[],"sources":["../node_modules/.pnpm/@earendil-works+pi-ai@0.84.1_ws@8.21.3_zod@4.4.3/node_modules/@earendil-works/pi-ai/dist/utils/headers.js"],"sourcesContent":["export function headersToRecord(headers) {\n const result = {};\n for (const [key, value] of headers.entries()) {\n result[key] = value;\n }\n return result;\n}\nexport function providerHeadersToRecord(headers) {\n if (!headers)\n return undefined;\n const result = {};\n for (const [key, value] of Object.entries(headers)) {\n if (value !== null)\n result[key] = value;\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n//# sourceMappingURL=headers.js.map"],"x_google_ignoreList":[0],"mappings":";;AAAA,SAAgB,gBAAgB,SAAS;CACrC,MAAM,SAAS,CAAC;CAChB,KAAK,MAAM,CAAC,KAAK,UAAU,QAAQ,QAAQ,GACvC,OAAO,OAAO;CAElB,OAAO;AACX;AACA,SAAgB,wBAAwB,SAAS;CAC7C,IAAI,CAAC,SACD,OAAO,KAAA;CACX,MAAM,SAAS,CAAC;CAChB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAC7C,IAAI,UAAU,MACV,OAAO,OAAO;CAEtB,OAAO,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,IAAI,SAAS,KAAA;AACrD"}
package/dist/host.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import { a as GeneratedRuntimeManifest, s as ResolvedPiPackage } from "./types-7IWJPPvS.mjs";
2
+ import { i as GeneratedRuntimeManifest, o as ResolvedPiPackage } from "./types-B9VBF8le.mjs";
3
3
  import { Context } from "@deepseek-ai/cordis";
4
4
  //#region src/host.d.ts
5
5
  type UnknownRecord = Record<string, unknown>;
@@ -14,6 +14,12 @@ interface PiHostConfig {
14
14
  /** Image-admission companions: default automatic; `false` off; explicit map narrows. */
15
15
  visionCompanions?: false | Record<string, readonly string[]>;
16
16
  }
17
+ interface PreparedPiHostPackage {
18
+ readonly name: string;
19
+ readonly rootUrl: URL;
20
+ readonly manifest: GeneratedRuntimeManifest;
21
+ readonly config?: UnknownRecord;
22
+ }
17
23
  /** Build a runtime manifest in place over an installed Pi package directory. */
18
24
  declare function manifestForInstalled(pkg: ResolvedPiPackage): Promise<GeneratedRuntimeManifest>;
19
25
  /**
@@ -22,6 +28,10 @@ declare function manifestForInstalled(pkg: ResolvedPiPackage): Promise<Generated
22
28
  * host or their siblings — matching Pi's own per-extension error isolation.
23
29
  */
24
30
  declare function applyPiHost(ctx: Context, config: PiHostConfig, anchor?: string): Promise<void>;
31
+ /** Resolve installed Pi packages and build immutable manifests without mounting their runtimes. */
32
+ declare function preparePiHost(config: PiHostConfig, anchor?: string): Promise<PreparedPiHostPackage[]>;
33
+ /** Mount prepared Pi package runtimes into one exact DSH context. */
34
+ declare function applyPreparedPiHost(ctx: Context, prepared: readonly PreparedPiHostPackage[], ownerAgent?: UnknownRecord): Promise<void>;
25
35
  //#endregion
26
- export { PiHostConfig, PiHostPackageSpec, applyPiHost, manifestForInstalled };
36
+ export { PiHostConfig, PiHostPackageSpec, PreparedPiHostPackage, applyPiHost, applyPreparedPiHost, manifestForInstalled, preparePiHost };
27
37
  //# sourceMappingURL=host.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.mts","names":[],"sources":["../src/host.ts"],"mappings":";;;;KAmBK,gBAAgB;UAEJ;;EAEf;;EAEA,SAAS;;UAGM;EACf,UAAU,eAAe;;EAEzB,2BAA2B;;;iBAuBP,qBAAqB,KAAK,oBAAoB,QAAQ;;;;;;iBA8DtD,YAAY,KAAK,SAAS,QAAQ,cAAc,kBAAkB"}
1
+ {"version":3,"file":"host.d.mts","names":[],"sources":["../src/host.ts"],"mappings":";;;;KAkBK,gBAAgB;UAEJ;;EAEf;;EAEA,SAAS;;UAGM;EACf,UAAU,eAAe;;EAEzB,2BAA2B;;UAGZ;WACN;WACA,SAAS;WACT,UAAU;WACV,SAAS;;;iBAuBE,qBAAqB,KAAK,oBAAoB,QAAQ;;;;;;iBA8DtD,YAAY,KAAK,SAAS,QAAQ,cAAc,kBAAkB;;iBAOlE,cAAc,QAAQ,cAAc,kBAAkB,QAAQ;;iBAsC9D,oBACpB,KAAK,SACL,mBAAmB,yBACnB,aAAa,gBACZ"}
package/dist/host.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import { r as registerVisionCompanions, t as applyPiPackage } from "./runtime-DEjs_Qlf.mjs";
2
+ import { r as registerVisionCompanions, t as applyPiPackage } from "./runtime-Dd2KhoX-.mjs";
3
3
  import { t as resolvePiPackage } from "./source-0sA5z08z.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import { readFile } from "node:fs/promises";
@@ -81,15 +81,21 @@ function resolveInstalledDir(anchor, packageName) {
81
81
  * host or their siblings — matching Pi's own per-extension error isolation.
82
82
  */
83
83
  async function applyPiHost(ctx, config, anchor) {
84
- const anchorPath = anchor ?? fileURLToPath(import.meta.url);
85
84
  registerVisionCompanions(ctx, config.visionCompanions);
85
+ await applyPreparedPiHost(ctx, await preparePiHost(config, anchor));
86
+ }
87
+ /** Resolve installed Pi packages and build immutable manifests without mounting their runtimes. */
88
+ async function preparePiHost(config, anchor) {
89
+ const anchorPath = anchor ?? fileURLToPath(import.meta.url);
86
90
  const errors = [];
91
+ const prepared = [];
87
92
  for (const spec of normalizeSpecs(config)) try {
88
93
  const dir = resolveInstalledDir(anchorPath, spec.name);
89
94
  const pkg = await resolvePiPackage(dir);
90
95
  try {
91
96
  const manifest = await manifestForInstalled(pkg);
92
- await applyPiPackage(ctx, {
97
+ prepared.push({
98
+ name: spec.name,
93
99
  rootUrl: pathToFileURL(`${pkg.rootDir}/`),
94
100
  manifest,
95
101
  ...spec.config === void 0 ? {} : { config: spec.config }
@@ -103,15 +109,47 @@ async function applyPiHost(ctx, config, anchor) {
103
109
  error: error instanceof Error ? error.message : String(error)
104
110
  });
105
111
  }
112
+ for (const failure of errors) {
113
+ const message = `[pi2dsh host] failed to mount ${failure.name}: ${failure.error}`;
114
+ console.warn(message);
115
+ }
116
+ if (errors.length > 0 && errors.length === normalizeSpecs(config).length) throw new Error(`pi2dsh host mounted no packages; first failure: ${errors[0].name}: ${errors[0].error}`);
117
+ return prepared;
118
+ }
119
+ /** Mount prepared Pi package runtimes into one exact DSH context. */
120
+ async function applyPreparedPiHost(ctx, prepared, ownerAgent) {
121
+ const errors = [];
122
+ for (const pkg of prepared) try {
123
+ await ctx.plugin(Object.assign(async (packageCtx) => {
124
+ await applyPiPackage(packageCtx, {
125
+ rootUrl: pkg.rootUrl,
126
+ manifest: pkg.manifest,
127
+ config: {
128
+ ...pkg.config ?? {},
129
+ visionCompanions: false
130
+ },
131
+ ...ownerAgent === void 0 ? {} : { ownerAgent }
132
+ });
133
+ }, { inject: [
134
+ "tools",
135
+ "systemPrompt",
136
+ "commands"
137
+ ] }));
138
+ } catch (error) {
139
+ errors.push({
140
+ name: pkg.name,
141
+ error: error instanceof Error ? error.message : String(error)
142
+ });
143
+ }
106
144
  for (const failure of errors) {
107
145
  const log = ctx.logger;
108
146
  const message = `[pi2dsh host] failed to mount ${failure.name}: ${failure.error}`;
109
147
  log?.warn?.(message);
110
148
  console.warn(message);
111
149
  }
112
- if (errors.length > 0 && errors.length === normalizeSpecs(config).length) throw new Error(`pi2dsh host mounted no packages; first failure: ${errors[0].name}: ${errors[0].error}`);
150
+ if (errors.length > 0 && errors.length === prepared.length) throw new Error(`pi2dsh host mounted no packages; first failure: ${errors[0].name}: ${errors[0].error}`);
113
151
  }
114
152
  //#endregion
115
- export { applyPiHost, manifestForInstalled };
153
+ export { applyPiHost, applyPreparedPiHost, manifestForInstalled, preparePiHost };
116
154
 
117
155
  //# sourceMappingURL=host.mjs.map