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,208 @@
1
+
2
+ import { t as AzureOpenAI } from "./openai-DkzRh5_G.mjs";
3
+ import { t as AssistantMessageEventStream } from "./event-stream-QxN1yvIF.mjs";
4
+ import { l as createGrammarToolInputProperties, m as clampThinkingLevel, r as buildBaseOptions } from "./simple-options-B_GO8FDE.mjs";
5
+ import { n as normalizeProviderError, t as formatProviderError } from "./error-body-DKA3lknR.mjs";
6
+ import { t as headersToRecord } from "./headers-CPzZhJQn.mjs";
7
+ import { t as getProviderEnvValue } from "./provider-env-C72pF4vP.mjs";
8
+ import { t as retryProviderRequest } from "./provider-retry-Cw6YJ4cr.mjs";
9
+ import { t as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-BDWtZRKh.mjs";
10
+ import { n as convertResponsesTools, r as processResponsesStream, t as convertResponsesMessages } from "./openai-responses-shared-BmnSvdKL.mjs";
11
+ //#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/azure-openai-responses.js
12
+ const DEFAULT_AZURE_API_VERSION = "v1";
13
+ const AZURE_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set([
14
+ "openai",
15
+ "openai-codex",
16
+ "opencode",
17
+ "azure-openai-responses"
18
+ ]);
19
+ const OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;
20
+ function parseDeploymentNameMap(value) {
21
+ const map = /* @__PURE__ */ new Map();
22
+ if (!value) return map;
23
+ for (const entry of value.split(",")) {
24
+ const trimmed = entry.trim();
25
+ if (!trimmed) continue;
26
+ const [modelId, deploymentName] = trimmed.split("=", 2);
27
+ if (!modelId || !deploymentName) continue;
28
+ map.set(modelId.trim(), deploymentName.trim());
29
+ }
30
+ return map;
31
+ }
32
+ function resolveDeploymentName(model, options) {
33
+ if (options?.azureDeploymentName) return options.azureDeploymentName;
34
+ return parseDeploymentNameMap(getProviderEnvValue("AZURE_OPENAI_DEPLOYMENT_NAME_MAP", options?.env)).get(model.id) || model.id;
35
+ }
36
+ function formatAzureOpenAIError(error) {
37
+ return formatProviderError(normalizeProviderError(error), "Azure OpenAI API error");
38
+ }
39
+ /**
40
+ * Generate function for Azure OpenAI Responses API
41
+ */
42
+ const stream = (model, context, options) => {
43
+ const stream = new AssistantMessageEventStream();
44
+ (async () => {
45
+ const deploymentName = resolveDeploymentName(model, options);
46
+ const output = {
47
+ role: "assistant",
48
+ content: [],
49
+ api: "azure-openai-responses",
50
+ provider: model.provider,
51
+ model: model.id,
52
+ usage: {
53
+ input: 0,
54
+ output: 0,
55
+ cacheRead: 0,
56
+ cacheWrite: 0,
57
+ totalTokens: 0,
58
+ cost: {
59
+ input: 0,
60
+ output: 0,
61
+ cacheRead: 0,
62
+ cacheWrite: 0,
63
+ total: 0
64
+ }
65
+ },
66
+ stopReason: "pending",
67
+ timestamp: Date.now()
68
+ };
69
+ try {
70
+ const apiKey = options?.apiKey;
71
+ if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
72
+ const client = createClient(model, apiKey, options);
73
+ const grammarToolInputProperties = createGrammarToolInputProperties(context.tools, model.compat?.supportsOpenAIGrammarTools ?? false);
74
+ let params = buildParams(model, context, options, deploymentName, grammarToolInputProperties);
75
+ const nextParams = await options?.onPayload?.(params, model);
76
+ if (nextParams !== void 0) params = nextParams;
77
+ const requestOptions = {
78
+ ...options?.signal ? { signal: options.signal } : {},
79
+ ...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
80
+ maxRetries: 0
81
+ };
82
+ const { data: openaiStream, response } = await retryProviderRequest(() => client.responses.create(params, requestOptions).withResponse(), {
83
+ maxRetries: options?.maxRetries,
84
+ maxRetryDelayMs: options?.maxRetryDelayMs,
85
+ signal: options?.signal
86
+ });
87
+ await options?.onResponse?.({
88
+ status: response.status,
89
+ headers: headersToRecord(response.headers)
90
+ }, model);
91
+ stream.push({
92
+ type: "start",
93
+ partial: output
94
+ });
95
+ await processResponsesStream(openaiStream, output, stream, model, { grammarToolInputProperties });
96
+ if (options?.signal?.aborted) throw new Error("Request was aborted");
97
+ if (output.stopReason === "pending") throw new Error("Azure OpenAI Responses stream ended without a stop reason");
98
+ if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage || "An unknown error occurred");
99
+ stream.push({
100
+ type: "done",
101
+ reason: output.stopReason,
102
+ message: output
103
+ });
104
+ stream.end();
105
+ } catch (error) {
106
+ for (const block of output.content) {
107
+ delete block.index;
108
+ delete block.partialJson;
109
+ delete block.customInput;
110
+ }
111
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
112
+ output.errorMessage = formatAzureOpenAIError(error);
113
+ stream.push({
114
+ type: "error",
115
+ reason: output.stopReason,
116
+ error: output
117
+ });
118
+ stream.end();
119
+ }
120
+ })();
121
+ return stream;
122
+ };
123
+ const streamSimple = (model, context, options) => {
124
+ const apiKey = options?.apiKey;
125
+ if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
126
+ const base = buildBaseOptions(model, context, options, apiKey);
127
+ const clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : void 0;
128
+ const reasoningEffort = clampedReasoning === "off" ? void 0 : clampedReasoning;
129
+ return stream(model, context, {
130
+ ...base,
131
+ reasoningEffort
132
+ });
133
+ };
134
+ function normalizeAzureBaseUrl(baseUrl) {
135
+ const trimmed = baseUrl.trim().replace(/\/+$/, "");
136
+ let url;
137
+ try {
138
+ url = new URL(trimmed);
139
+ } catch {
140
+ throw new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`);
141
+ }
142
+ const isAzureHost = url.hostname.endsWith(".openai.azure.com") || url.hostname.endsWith(".cognitiveservices.azure.com") || url.hostname.endsWith(".ai.azure.com");
143
+ const normalizedPath = url.pathname.replace(/\/+$/, "");
144
+ if (isAzureHost && (normalizedPath === "" || normalizedPath === "/" || normalizedPath === "/openai" || normalizedPath === "/openai/v1/responses")) {
145
+ url.pathname = "/openai/v1";
146
+ url.search = "";
147
+ }
148
+ return url.toString().replace(/\/+$/, "");
149
+ }
150
+ function buildDefaultBaseUrl(resourceName) {
151
+ return `https://${resourceName}.openai.azure.com/openai/v1`;
152
+ }
153
+ function resolveAzureConfig(model, options) {
154
+ const apiVersion = options?.azureApiVersion || getProviderEnvValue("AZURE_OPENAI_API_VERSION", options?.env) || DEFAULT_AZURE_API_VERSION;
155
+ const baseUrl = options?.azureBaseUrl?.trim() || getProviderEnvValue("AZURE_OPENAI_BASE_URL", options?.env)?.trim() || void 0;
156
+ const resourceName = options?.azureResourceName || getProviderEnvValue("AZURE_OPENAI_RESOURCE_NAME", options?.env);
157
+ let resolvedBaseUrl = baseUrl;
158
+ if (!resolvedBaseUrl && resourceName) resolvedBaseUrl = buildDefaultBaseUrl(resourceName);
159
+ if (!resolvedBaseUrl && model.baseUrl) resolvedBaseUrl = model.baseUrl;
160
+ if (!resolvedBaseUrl) throw new Error("Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.");
161
+ return {
162
+ baseUrl: normalizeAzureBaseUrl(resolvedBaseUrl),
163
+ apiVersion
164
+ };
165
+ }
166
+ function createClient(model, apiKey, options) {
167
+ const headers = { ...model.headers };
168
+ if (options?.headers) Object.assign(headers, options.headers);
169
+ const { baseUrl, apiVersion } = resolveAzureConfig(model, options);
170
+ return new AzureOpenAI({
171
+ apiKey,
172
+ apiVersion,
173
+ dangerouslyAllowBrowser: true,
174
+ fetch: options?.fetch,
175
+ defaultHeaders: headers,
176
+ baseURL: baseUrl
177
+ });
178
+ }
179
+ function buildParams(model, context, options, deploymentName, grammarToolInputProperties = createGrammarToolInputProperties(context.tools, model.compat?.supportsOpenAIGrammarTools ?? false)) {
180
+ const params = {
181
+ model: deploymentName,
182
+ input: convertResponsesMessages(model, context, AZURE_TOOL_CALL_PROVIDERS, { grammarToolInputProperties }),
183
+ stream: true,
184
+ prompt_cache_key: clampOpenAIPromptCacheKey(options?.sessionId),
185
+ store: false
186
+ };
187
+ if (options?.maxTokens) params.max_output_tokens = Math.max(options.maxTokens, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS);
188
+ if (options?.temperature !== void 0) params.temperature = options?.temperature;
189
+ if (context.tools && context.tools.length > 0) params.tools = convertResponsesTools(context.tools, {
190
+ supportsStrictMode: model.compat?.supportsStrictMode ?? true,
191
+ supportsOpenAIGrammarTools: model.compat?.supportsOpenAIGrammarTools ?? false
192
+ });
193
+ if (model.reasoning) {
194
+ if (options?.reasoningEffort || options?.reasoningSummary) {
195
+ params.reasoning = {
196
+ effort: options?.reasoningEffort ? model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort : "medium",
197
+ summary: options?.reasoningSummary || "auto"
198
+ };
199
+ params.include = ["reasoning.encrypted_content"];
200
+ } else if (model.thinkingLevelMap?.off !== null) params.reasoning = { effort: model.thinkingLevelMap?.off ?? "none" };
201
+ }
202
+ if (options?.samplingParams) Object.assign(params, options.samplingParams);
203
+ return params;
204
+ }
205
+ //#endregion
206
+ export { stream, streamSimple };
207
+
208
+ //# sourceMappingURL=azure-openai-responses-HKWkzl2m.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure-openai-responses-HKWkzl2m.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/azure-openai-responses.js"],"sourcesContent":["import { AzureOpenAI } from \"openai\";\nimport { clampThinkingLevel } from \"../models.js\";\nimport { formatProviderError, normalizeProviderError } from \"../utils/error-body.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport { headersToRecord } from \"../utils/headers.js\";\nimport { getProviderEnvValue } from \"../utils/provider-env.js\";\nimport { retryProviderRequest } from \"../utils/provider-retry.js\";\nimport { createGrammarToolInputProperties } from \"./constrained-sampling.js\";\nimport { clampOpenAIPromptCacheKey } from \"./openai-prompt-cache.js\";\nimport { convertResponsesMessages, convertResponsesTools, processResponsesStream } from \"./openai-responses-shared.js\";\nimport { buildBaseOptions } from \"./simple-options.js\";\nconst DEFAULT_AZURE_API_VERSION = \"v1\";\nconst AZURE_TOOL_CALL_PROVIDERS = new Set([\"openai\", \"openai-codex\", \"opencode\", \"azure-openai-responses\"]);\n// OpenAI Responses rejects max_output_tokens below 16: https://github.com/earendil-works/pi/issues/6265\nconst OPENAI_RESPONSES_MIN_OUTPUT_TOKENS = 16;\nfunction parseDeploymentNameMap(value) {\n const map = new Map();\n if (!value)\n return map;\n for (const entry of value.split(\",\")) {\n const trimmed = entry.trim();\n if (!trimmed)\n continue;\n const [modelId, deploymentName] = trimmed.split(\"=\", 2);\n if (!modelId || !deploymentName)\n continue;\n map.set(modelId.trim(), deploymentName.trim());\n }\n return map;\n}\nfunction resolveDeploymentName(model, options) {\n if (options?.azureDeploymentName) {\n return options.azureDeploymentName;\n }\n const mappedDeployment = parseDeploymentNameMap(getProviderEnvValue(\"AZURE_OPENAI_DEPLOYMENT_NAME_MAP\", options?.env)).get(model.id);\n return mappedDeployment || model.id;\n}\nfunction formatAzureOpenAIError(error) {\n return formatProviderError(normalizeProviderError(error), \"Azure OpenAI API error\");\n}\n/**\n * Generate function for Azure OpenAI Responses API\n */\nexport const stream = (model, context, options) => {\n const stream = new AssistantMessageEventStream();\n // Start async processing\n (async () => {\n const deploymentName = resolveDeploymentName(model, options);\n const output = {\n role: \"assistant\",\n content: [],\n api: \"azure-openai-responses\",\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 // Create Azure OpenAI client\n const apiKey = options?.apiKey;\n if (!apiKey) {\n throw new Error(`No API key for provider: ${model.provider}`);\n }\n const client = createClient(model, apiKey, options);\n const grammarToolInputProperties = createGrammarToolInputProperties(context.tools, model.compat?.supportsOpenAIGrammarTools ?? false);\n let params = buildParams(model, context, options, deploymentName, grammarToolInputProperties);\n const nextParams = await options?.onPayload?.(params, model);\n if (nextParams !== undefined) {\n params = nextParams;\n }\n const requestOptions = {\n ...(options?.signal ? { signal: options.signal } : {}),\n ...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),\n maxRetries: 0,\n };\n const { data: openaiStream, response } = await retryProviderRequest(() => client.responses.create(params, requestOptions).withResponse(), {\n maxRetries: options?.maxRetries,\n maxRetryDelayMs: options?.maxRetryDelayMs,\n signal: options?.signal,\n });\n await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n stream.push({ type: \"start\", partial: output });\n await processResponsesStream(openaiStream, output, stream, model, { grammarToolInputProperties });\n if (options?.signal?.aborted) {\n throw new Error(\"Request was aborted\");\n }\n if (output.stopReason === \"pending\") {\n throw new Error(\"Azure OpenAI Responses stream ended without a stop reason\");\n }\n if (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n throw new Error(output.errorMessage || \"An unknown error occurred\");\n }\n stream.push({ type: \"done\", reason: output.stopReason, message: output });\n stream.end();\n }\n catch (error) {\n for (const block of output.content) {\n delete block.index;\n // Streaming scratch buffers are only used during parsing; never persist them.\n delete block.partialJson;\n delete block.customInput;\n }\n output.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n output.errorMessage = formatAzureOpenAIError(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 apiKey = options?.apiKey;\n if (!apiKey) {\n throw new Error(`No API key for provider: ${model.provider}`);\n }\n const base = buildBaseOptions(model, context, options, apiKey);\n const clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;\n const reasoningEffort = clampedReasoning === \"off\" ? undefined : clampedReasoning;\n return stream(model, context, {\n ...base,\n reasoningEffort,\n });\n};\nfunction normalizeAzureBaseUrl(baseUrl) {\n const trimmed = baseUrl.trim().replace(/\\/+$/, \"\");\n let url;\n try {\n url = new URL(trimmed);\n }\n catch {\n throw new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`);\n }\n const isAzureHost = url.hostname.endsWith(\".openai.azure.com\") ||\n url.hostname.endsWith(\".cognitiveservices.azure.com\") ||\n url.hostname.endsWith(\".ai.azure.com\");\n const normalizedPath = url.pathname.replace(/\\/+$/, \"\");\n // Ensure Azure hosts have /openai/v1 as base path so the AzureOpenAI SDK\n // can append /deployments/<model>/... and ?api-version=v1 correctly.\n if (isAzureHost &&\n (normalizedPath === \"\" ||\n normalizedPath === \"/\" ||\n normalizedPath === \"/openai\" ||\n normalizedPath === \"/openai/v1/responses\")) {\n url.pathname = \"/openai/v1\";\n url.search = \"\";\n }\n return url.toString().replace(/\\/+$/, \"\");\n}\nfunction buildDefaultBaseUrl(resourceName) {\n return `https://${resourceName}.openai.azure.com/openai/v1`;\n}\nfunction resolveAzureConfig(model, options) {\n const apiVersion = options?.azureApiVersion ||\n getProviderEnvValue(\"AZURE_OPENAI_API_VERSION\", options?.env) ||\n DEFAULT_AZURE_API_VERSION;\n const baseUrl = options?.azureBaseUrl?.trim() || getProviderEnvValue(\"AZURE_OPENAI_BASE_URL\", options?.env)?.trim() || undefined;\n const resourceName = options?.azureResourceName || getProviderEnvValue(\"AZURE_OPENAI_RESOURCE_NAME\", options?.env);\n let resolvedBaseUrl = baseUrl;\n if (!resolvedBaseUrl && resourceName) {\n resolvedBaseUrl = buildDefaultBaseUrl(resourceName);\n }\n if (!resolvedBaseUrl && model.baseUrl) {\n resolvedBaseUrl = model.baseUrl;\n }\n if (!resolvedBaseUrl) {\n throw new Error(\"Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.\");\n }\n return {\n baseUrl: normalizeAzureBaseUrl(resolvedBaseUrl),\n apiVersion,\n };\n}\nfunction createClient(model, apiKey, options) {\n const headers = { ...model.headers };\n if (options?.headers) {\n Object.assign(headers, options.headers);\n }\n const { baseUrl, apiVersion } = resolveAzureConfig(model, options);\n return new AzureOpenAI({\n apiKey,\n apiVersion,\n dangerouslyAllowBrowser: true,\n fetch: options?.fetch,\n defaultHeaders: headers,\n baseURL: baseUrl,\n });\n}\nfunction buildParams(model, context, options, deploymentName, grammarToolInputProperties = createGrammarToolInputProperties(context.tools, model.compat?.supportsOpenAIGrammarTools ?? false)) {\n const messages = convertResponsesMessages(model, context, AZURE_TOOL_CALL_PROVIDERS, {\n grammarToolInputProperties,\n });\n const params = {\n model: deploymentName,\n input: messages,\n stream: true,\n prompt_cache_key: clampOpenAIPromptCacheKey(options?.sessionId),\n store: false,\n };\n if (options?.maxTokens) {\n params.max_output_tokens = Math.max(options.maxTokens, OPENAI_RESPONSES_MIN_OUTPUT_TOKENS);\n }\n if (options?.temperature !== undefined) {\n params.temperature = options?.temperature;\n }\n if (context.tools && context.tools.length > 0) {\n params.tools = convertResponsesTools(context.tools, {\n supportsStrictMode: model.compat?.supportsStrictMode ?? true,\n supportsOpenAIGrammarTools: model.compat?.supportsOpenAIGrammarTools ?? false,\n });\n }\n if (model.reasoning) {\n if (options?.reasoningEffort || options?.reasoningSummary) {\n const effort = options?.reasoningEffort\n ? (model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort)\n : \"medium\";\n params.reasoning = {\n effort: effort,\n summary: options?.reasoningSummary || \"auto\",\n };\n params.include = [\"reasoning.encrypted_content\"];\n }\n else if (model.thinkingLevelMap?.off !== null) {\n params.reasoning = {\n effort: (model.thinkingLevelMap?.off ?? \"none\"),\n };\n }\n }\n // Last so custom keys override the named request fields.\n if (options?.samplingParams) {\n Object.assign(params, options.samplingParams);\n }\n return params;\n}\n//# sourceMappingURL=azure-openai-responses.js.map"],"x_google_ignoreList":[0],"mappings":"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"}
package/dist/cli.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as resolvePiPackage } from "./source-0sA5z08z.mjs";
3
- import { a as CONTEXT_RULES, d as UI_CONTEXT_RULES, i as API_RULES, n as convertPiMcpConfig, o as EVENT_RULES, r as renderMcpPatch, s as HOST_IMPORT_RULES } from "./mcp-config-_idn-pzI.mjs";
3
+ import { c as UI_CONTEXT_RULES, i as HOST_IMPORT_RULES, n as CONTEXT_RULES, r as EVENT_RULES, t as API_RULES } from "./compatibility-Bz6ZXA7F.mjs";
4
+ import { n as convertPiMcpConfig, r as renderMcpPatch } from "./mcp-config-jmzbgdHa.mjs";
4
5
  import { writeFileSync } from "node:fs";
5
6
  import { parseArgs } from "node:util";
6
7
  //#region src/cli.ts
@@ -75,7 +76,7 @@ async function main() {
75
76
  if (command !== "inspect" || source === void 0) throw new Error(`invalid command\n\n${usage()}`);
76
77
  const pkg = await resolvePiPackage(source);
77
78
  try {
78
- const { analyzePackage } = await import("./analyzer-CJFwQlSG.mjs");
79
+ const { analyzePackage } = await import("./analyzer-DBtUYKI1.mjs");
79
80
  const report = await analyzePackage(pkg);
80
81
  console.log(parsed.values.json ? JSON.stringify(report, null, 2) : reportText(report));
81
82
  if (report.verdict === "blocked") process.exitCode = 2;
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["// The analyzer (which pulls the 23 MB typescript compiler, an optional peer)\n// loads lazily inside its own command only — `matrix` and `mcp-config` must\n// run on an install without typescript.\nimport { writeFileSync } from 'node:fs'\nimport { parseArgs } from 'node:util'\nimport { API_RULES, CONTEXT_RULES, EVENT_RULES, HOST_IMPORT_RULES, UI_CONTEXT_RULES } from './compatibility.js'\nimport { convertPiMcpConfig, renderMcpPatch } from './mcp-config.js'\nimport { resolvePiPackage } from './source.js'\nimport type { CompatibilityReport } from './types.js'\n\nfunction usage(): string {\n return `pi2dsh — migrate Pi packages to DeepSeek Harness\\n\\n`\n + `Usage:\\n`\n + ` pi2dsh inspect <package-or-path> [--json]\\n`\n + ` pi2dsh mcp-config [--cwd <dir>] [--out <file>] [--json]\\n`\n + ` pi2dsh matrix [--json]\\n\\n`\n + `Installing is dsh's own job — \\`dsh plugin add pi2dsh\\`, then\\n`\n + `\\`dsh plugin add <pi package>\\`. This CLI only inspects.\\n\\n`\n + `mcp-config reads Pi's standard mcpServers files (six-layer precedence)\\n`\n + `and emits DSH cordis.patch.yml entries for the official dsh-mcp-client —\\n`\n + `Pi's MCP adapter code is never executed.\\n`\n}\n\nfunction reportText(report: CompatibilityReport): string {\n const lines = [\n `${report.package.name}@${report.package.version}: ${report.verdict.toUpperCase()}`,\n `full=${report.summary.full} partial=${report.summary.partial} unsupported=${report.summary.unsupported}`,\n `extensions=${report.resources.extensions.length} skills=${report.resources.skills.length} prompts=${report.resources.prompts.length} themes=${report.resources.themes.length}`,\n ]\n for (const finding of report.findings) {\n lines.push(`${finding.level.toUpperCase().padEnd(11)} ${finding.file}:${finding.line} ${finding.capability} — ${finding.detail}`)\n }\n return lines.join('\\n')\n}\n\nfunction matrix(json: boolean): void {\n const value = {\n api: API_RULES,\n events: EVENT_RULES,\n context: CONTEXT_RULES,\n uiContext: UI_CONTEXT_RULES,\n hostImports: HOST_IMPORT_RULES,\n }\n if (json) console.log(JSON.stringify(value, null, 2))\n else {\n for (const [kind, rules] of Object.entries(value)) {\n console.log(`${kind}:`)\n for (const [name, candidate] of Object.entries(rules)) {\n if ('level' in candidate && 'detail' in candidate) {\n console.log(` ${candidate.level.padEnd(11)} ${name} — ${candidate.detail}`)\n } else {\n const hostRules = candidate as Readonly<Record<string, { level: string; detail: string }>>\n for (const [exportName, hostRule] of Object.entries(hostRules)) {\n console.log(` ${hostRule.level.padEnd(11)} ${name}:${exportName} — ${hostRule.detail}`)\n }\n }\n }\n }\n }\n}\n\nasync function main(): Promise<void> {\n const parsed = parseArgs({\n allowPositionals: true,\n strict: true,\n options: {\n json: { type: 'boolean', default: false },\n out: { type: 'string' },\n cwd: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n },\n })\n const [command, source] = parsed.positionals\n if (parsed.values.help || command === undefined) {\n console.log(usage())\n return\n }\n if (command === 'matrix') {\n matrix(parsed.values.json)\n return\n }\n if (command === 'mcp-config') {\n const result = convertPiMcpConfig(parsed.values.cwd ?? process.cwd())\n for (const warning of result.warnings) {\n console.error(`warning: ${warning.server}: ${warning.message}`)\n }\n const output = parsed.values.json ? `${JSON.stringify(result, null, 2)}\\n` : renderMcpPatch(result)\n if (parsed.values.out === undefined) process.stdout.write(output)\n else {\n writeFileSync(parsed.values.out, output)\n console.error(`wrote ${result.entries.length} MCP server entr${result.entries.length === 1 ? 'y' : 'ies'} from ${result.sources.length} Pi config file(s) to ${parsed.values.out}`)\n }\n return\n }\n if (command !== 'inspect' || source === undefined) {\n throw new Error(`invalid command\\n\\n${usage()}`)\n }\n\n const pkg = await resolvePiPackage(source)\n try {\n const { analyzePackage } = await import('./analyzer.js')\n const report = await analyzePackage(pkg)\n console.log(parsed.values.json ? JSON.stringify(report, null, 2) : reportText(report))\n if (report.verdict === 'blocked') process.exitCode = 2\n } finally {\n await pkg.dispose()\n }\n}\n\nmain().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error))\n process.exitCode = 1\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["// The analyzer (which pulls the 23 MB typescript compiler, an optional peer)\n// loads lazily inside its own command only — `matrix` and `mcp-config` must\n// run on an install without typescript.\nimport { writeFileSync } from 'node:fs'\nimport { parseArgs } from 'node:util'\nimport { API_RULES, CONTEXT_RULES, EVENT_RULES, HOST_IMPORT_RULES, UI_CONTEXT_RULES } from './compatibility.js'\nimport { convertPiMcpConfig, renderMcpPatch } from './mcp-config.js'\nimport { resolvePiPackage } from './source.js'\nimport type { CompatibilityReport } from './types.js'\n\nfunction usage(): string {\n return `pi2dsh — migrate Pi packages to DeepSeek Harness\\n\\n`\n + `Usage:\\n`\n + ` pi2dsh inspect <package-or-path> [--json]\\n`\n + ` pi2dsh mcp-config [--cwd <dir>] [--out <file>] [--json]\\n`\n + ` pi2dsh matrix [--json]\\n\\n`\n + `Installing is dsh's own job — \\`dsh plugin add pi2dsh\\`, then\\n`\n + `\\`dsh plugin add <pi package>\\`. This CLI only inspects.\\n\\n`\n + `mcp-config reads Pi's standard mcpServers files (six-layer precedence)\\n`\n + `and emits DSH cordis.patch.yml entries for the official dsh-mcp-client —\\n`\n + `Pi's MCP adapter code is never executed.\\n`\n}\n\nfunction reportText(report: CompatibilityReport): string {\n const lines = [\n `${report.package.name}@${report.package.version}: ${report.verdict.toUpperCase()}`,\n `full=${report.summary.full} partial=${report.summary.partial} unsupported=${report.summary.unsupported}`,\n `extensions=${report.resources.extensions.length} skills=${report.resources.skills.length} prompts=${report.resources.prompts.length} themes=${report.resources.themes.length}`,\n ]\n for (const finding of report.findings) {\n lines.push(`${finding.level.toUpperCase().padEnd(11)} ${finding.file}:${finding.line} ${finding.capability} — ${finding.detail}`)\n }\n return lines.join('\\n')\n}\n\nfunction matrix(json: boolean): void {\n const value = {\n api: API_RULES,\n events: EVENT_RULES,\n context: CONTEXT_RULES,\n uiContext: UI_CONTEXT_RULES,\n hostImports: HOST_IMPORT_RULES,\n }\n if (json) console.log(JSON.stringify(value, null, 2))\n else {\n for (const [kind, rules] of Object.entries(value)) {\n console.log(`${kind}:`)\n for (const [name, candidate] of Object.entries(rules)) {\n if ('level' in candidate && 'detail' in candidate) {\n console.log(` ${candidate.level.padEnd(11)} ${name} — ${candidate.detail}`)\n } else {\n const hostRules = candidate as Readonly<Record<string, { level: string; detail: string }>>\n for (const [exportName, hostRule] of Object.entries(hostRules)) {\n console.log(` ${hostRule.level.padEnd(11)} ${name}:${exportName} — ${hostRule.detail}`)\n }\n }\n }\n }\n }\n}\n\nasync function main(): Promise<void> {\n const parsed = parseArgs({\n allowPositionals: true,\n strict: true,\n options: {\n json: { type: 'boolean', default: false },\n out: { type: 'string' },\n cwd: { type: 'string' },\n help: { type: 'boolean', short: 'h', default: false },\n },\n })\n const [command, source] = parsed.positionals\n if (parsed.values.help || command === undefined) {\n console.log(usage())\n return\n }\n if (command === 'matrix') {\n matrix(parsed.values.json)\n return\n }\n if (command === 'mcp-config') {\n const result = convertPiMcpConfig(parsed.values.cwd ?? process.cwd())\n for (const warning of result.warnings) {\n console.error(`warning: ${warning.server}: ${warning.message}`)\n }\n const output = parsed.values.json ? `${JSON.stringify(result, null, 2)}\\n` : renderMcpPatch(result)\n if (parsed.values.out === undefined) process.stdout.write(output)\n else {\n writeFileSync(parsed.values.out, output)\n console.error(`wrote ${result.entries.length} MCP server entr${result.entries.length === 1 ? 'y' : 'ies'} from ${result.sources.length} Pi config file(s) to ${parsed.values.out}`)\n }\n return\n }\n if (command !== 'inspect' || source === undefined) {\n throw new Error(`invalid command\\n\\n${usage()}`)\n }\n\n const pkg = await resolvePiPackage(source)\n try {\n const { analyzePackage } = await import('./analyzer.js')\n const report = await analyzePackage(pkg)\n console.log(parsed.values.json ? JSON.stringify(report, null, 2) : reportText(report))\n if (report.verdict === 'blocked') process.exitCode = 2\n } finally {\n await pkg.dispose()\n }\n}\n\nmain().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error))\n process.exitCode = 1\n})\n"],"mappings":";;;;;;;AAUA,SAAS,QAAgB;CACvB,OAAO;AAUT;AAEA,SAAS,WAAW,QAAqC;CACvD,MAAM,QAAQ;EACZ,GAAG,OAAO,QAAQ,KAAK,GAAG,OAAO,QAAQ,QAAQ,IAAI,OAAO,QAAQ,YAAY;EAChF,QAAQ,OAAO,QAAQ,KAAK,WAAW,OAAO,QAAQ,QAAQ,eAAe,OAAO,QAAQ;EAC5F,cAAc,OAAO,UAAU,WAAW,OAAO,UAAU,OAAO,UAAU,OAAO,OAAO,WAAW,OAAO,UAAU,QAAQ,OAAO,UAAU,OAAO,UAAU,OAAO;CACzK;CACA,KAAK,MAAM,WAAW,OAAO,UAC3B,MAAM,KAAK,GAAG,QAAQ,MAAM,YAAY,CAAC,CAAC,OAAO,EAAE,EAAE,GAAG,QAAQ,KAAK,GAAG,QAAQ,KAAK,GAAG,QAAQ,WAAW,KAAK,QAAQ,QAAQ;CAElI,OAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,OAAO,MAAqB;CACnC,MAAM,QAAQ;EACZ,KAAK;EACL,QAAQ;EACR,SAAS;EACT,WAAW;EACX,aAAa;CACf;CACA,IAAI,MAAM,QAAQ,IAAI,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;MAElD,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,KAAK,GAAG;EACjD,QAAQ,IAAI,GAAG,KAAK,EAAE;EACtB,KAAK,MAAM,CAAC,MAAM,cAAc,OAAO,QAAQ,KAAK,GAClD,IAAI,WAAW,aAAa,YAAY,WACtC,QAAQ,IAAI,KAAK,UAAU,MAAM,OAAO,EAAE,EAAE,GAAG,KAAK,KAAK,UAAU,QAAQ;OACtE;GACL,MAAM,YAAY;GAClB,KAAK,MAAM,CAAC,YAAY,aAAa,OAAO,QAAQ,SAAS,GAC3D,QAAQ,IAAI,KAAK,SAAS,MAAM,OAAO,EAAE,EAAE,GAAG,KAAK,GAAG,WAAW,KAAK,SAAS,QAAQ;EAE3F;CAEJ;AAEJ;AAEA,eAAe,OAAsB;CACnC,MAAM,SAAS,UAAU;EACvB,kBAAkB;EAClB,QAAQ;EACR,SAAS;GACP,MAAM;IAAE,MAAM;IAAW,SAAS;GAAM;GACxC,KAAK,EAAE,MAAM,SAAS;GACtB,KAAK,EAAE,MAAM,SAAS;GACtB,MAAM;IAAE,MAAM;IAAW,OAAO;IAAK,SAAS;GAAM;EACtD;CACF,CAAC;CACD,MAAM,CAAC,SAAS,UAAU,OAAO;CACjC,IAAI,OAAO,OAAO,QAAQ,YAAY,KAAA,GAAW;EAC/C,QAAQ,IAAI,MAAM,CAAC;EACnB;CACF;CACA,IAAI,YAAY,UAAU;EACxB,OAAO,OAAO,OAAO,IAAI;EACzB;CACF;CACA,IAAI,YAAY,cAAc;EAC5B,MAAM,SAAS,mBAAmB,OAAO,OAAO,OAAO,QAAQ,IAAI,CAAC;EACpE,KAAK,MAAM,WAAW,OAAO,UAC3B,QAAQ,MAAM,YAAY,QAAQ,OAAO,IAAI,QAAQ,SAAS;EAEhE,MAAM,SAAS,OAAO,OAAO,OAAO,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,MAAM,eAAe,MAAM;EAClG,IAAI,OAAO,OAAO,QAAQ,KAAA,GAAW,QAAQ,OAAO,MAAM,MAAM;OAC3D;GACH,cAAc,OAAO,OAAO,KAAK,MAAM;GACvC,QAAQ,MAAM,SAAS,OAAO,QAAQ,OAAO,kBAAkB,OAAO,QAAQ,WAAW,IAAI,MAAM,MAAM,QAAQ,OAAO,QAAQ,OAAO,wBAAwB,OAAO,OAAO,KAAK;EACpL;EACA;CACF;CACA,IAAI,YAAY,aAAa,WAAW,KAAA,GACtC,MAAM,IAAI,MAAM,sBAAsB,MAAM,GAAG;CAGjD,MAAM,MAAM,MAAM,iBAAiB,MAAM;CACzC,IAAI;EACF,MAAM,EAAE,mBAAmB,MAAM,OAAO;EACxC,MAAM,SAAS,MAAM,eAAe,GAAG;EACvC,QAAQ,IAAI,OAAO,OAAO,OAAO,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC;EACrF,IAAI,OAAO,YAAY,WAAW,QAAQ,WAAW;CACvD,UAAU;EACR,MAAM,IAAI,QAAQ;CACpB;AACF;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;CACpE,QAAQ,WAAW;AACrB,CAAC"}