@cydm/pie 2.7.11 → 2.7.12

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.
@@ -1519,6 +1519,9 @@ function getSystemIO() {
1519
1519
  }
1520
1520
  return CS.System.IO;
1521
1521
  }
1522
+ function looksLikeBase64(value) {
1523
+ return value.length > 0 && value.length % 4 === 0 && /^[A-Za-z0-9+/]+={0,2}$/.test(value);
1524
+ }
1522
1525
  function getPieFileBridge() {
1523
1526
  if (typeof CS === "undefined" || !CS?.Pie?.PieFileBridge) {
1524
1527
  throw new Error("CS.Pie.PieFileBridge not available - runtime file bridge is missing");
@@ -1667,11 +1670,15 @@ var PuerTSFileSystem = class {
1667
1670
  }
1668
1671
  if (encoding === "base64") {
1669
1672
  if (typeof bridge.ReadAllBytesBase64Async === "function") {
1670
- const content3 = await taskToPromise(bridge.ReadAllBytesBase64Async(normalizedPath));
1671
- return String(content3 ?? "");
1673
+ const content2 = await taskToPromise(bridge.ReadAllBytesBase64Async(normalizedPath));
1674
+ if (typeof content2 === "string" && looksLikeBase64(content2)) {
1675
+ return content2;
1676
+ }
1677
+ console.warn(
1678
+ `[pie] async base64 file bridge returned an empty/invalid result for '${path}'; falling back to a synchronous read.`
1679
+ );
1672
1680
  }
1673
- const content2 = CS.System.Convert.ToBase64String(IO.File.ReadAllBytes(normalizedPath));
1674
- return String(content2 ?? "");
1681
+ return this.readBinaryAsBase64Sync(normalizedPath);
1675
1682
  }
1676
1683
  const content = await taskToPromise(bridge.ReadAllTextAsync(normalizedPath));
1677
1684
  return String(content ?? "");
@@ -1683,10 +1690,18 @@ var PuerTSFileSystem = class {
1683
1690
  throw new Error(`ENOENT: no such file or directory, open '${path}'`);
1684
1691
  }
1685
1692
  if (encoding === "base64") {
1686
- return String(CS.System.Convert.ToBase64String(IO.File.ReadAllBytes(normalizedPath)) ?? "");
1693
+ return this.readBinaryAsBase64Sync(normalizedPath);
1687
1694
  }
1688
1695
  return IO.File.ReadAllText(normalizedPath);
1689
1696
  }
1697
+ readBinaryAsBase64Sync(normalizedPath) {
1698
+ const bridge = typeof CS !== "undefined" && CS?.Pie?.PieFileBridge ? CS.Pie.PieFileBridge : null;
1699
+ if (bridge && typeof bridge.ReadAllBytesBase64 === "function") {
1700
+ return String(bridge.ReadAllBytesBase64(normalizedPath) ?? "");
1701
+ }
1702
+ const IO = getSystemIO();
1703
+ return String(CS.System.Convert.ToBase64String(IO.File.ReadAllBytes(normalizedPath)) ?? "");
1704
+ }
1690
1705
  async readFilePrefix(path, maxBytes) {
1691
1706
  const IO = getSystemIO();
1692
1707
  const bridge = getPieFileBridge();
@@ -3113,19 +3128,10 @@ var FileSystemGateway = class {
3113
3128
  return;
3114
3129
  }
3115
3130
  if (CS.System.IO.File.Exists(destination)) {
3116
- const staged = `${destination}.pie-replace-${Date.now()}.tmp`;
3117
- CS.System.IO.File.Copy(source, staged, false);
3118
- CS.System.IO.File.Delete(destination);
3119
- try {
3120
- CS.System.IO.File.Move(staged, destination);
3121
- } catch (error) {
3122
- try {
3123
- CS.System.IO.File.Move(staged, destination);
3124
- } catch {
3125
- }
3126
- throw error;
3131
+ if (typeof CS.System.IO.File.Replace !== "function") {
3132
+ throw new Error("File.Replace is unavailable; refusing unsafe file replacement");
3127
3133
  }
3128
- CS.System.IO.File.Delete(source);
3134
+ CS.System.IO.File.Replace(source, destination, null);
3129
3135
  return;
3130
3136
  }
3131
3137
  CS.System.IO.File.Move(source, destination);
@@ -6123,6 +6129,13 @@ function nextLocalRequestId(prefix = "req") {
6123
6129
  localRequestCounter += 1;
6124
6130
  return `${prefix}-${localRequestCounter}-${Math.random().toString(36).slice(2, 8)}`;
6125
6131
  }
6132
+ function timeoutSuffix(budgetMs, lagMs) {
6133
+ const budget = budgetMs && budgetMs > 0 ? ` (budget ${Math.round(budgetMs / 1e3)}s)` : "";
6134
+ if (lagMs > 1e3) {
6135
+ return `${budget} \u2014 timer fired ${Math.round(lagMs / 1e3)}s late (system sleep or suspended process)`;
6136
+ }
6137
+ return budget;
6138
+ }
6126
6139
  function monotonicNow() {
6127
6140
  const perf = globalThis.performance;
6128
6141
  return typeof perf?.now === "function" ? perf.now() : Date.now();
@@ -6410,7 +6423,9 @@ function streamResponsesSSE(model, context, options) {
6410
6423
  internalTimeout = adapterTimeoutKind === "first_byte" ? "first_response" : "stream_idle";
6411
6424
  }
6412
6425
  const protocolFailure = !endedWithoutTerminal && (error instanceof ResponsesProtocolError || error instanceof SyntaxError || !transportLost && error instanceof TypeError);
6413
- message.errorMessage = providerErrorMessage ?? (internalTimeout && !protocolFailure ? `Responses request timeout (${internalTimeout}) after ${Math.round(monotonicNow() - startedAt)}ms` : error instanceof Error ? error.message : JSON.stringify(error));
6426
+ const adapterBudgetMs = internalTimeout === "first_response" ? budgets?.firstResponseTimeoutMs : internalTimeout === "stream_idle" ? budgets?.streamIdleTimeoutMs : void 0;
6427
+ const adapterAgeMs = Math.round(monotonicNow() - startedAt);
6428
+ message.errorMessage = providerErrorMessage ?? (internalTimeout && !protocolFailure ? `Responses request timeout (${internalTimeout}) after ${adapterAgeMs}ms${timeoutSuffix(adapterBudgetMs, 0)}` : error instanceof Error ? error.message : JSON.stringify(error));
6414
6429
  const compat = getResponsesCompat(model);
6415
6430
  const streamLost = (endedWithoutTerminal || transportLost) && !protocolFailure && !internalTimeout && submitted && !localFailure && !providerRejected && message.stopReason === "error";
6416
6431
  if (internalTimeout && !message.remoteFailure && !protocolFailure && submitted && !providerRejected && !localFailure && !userAborted && compat.timeoutReplay) {
@@ -6668,6 +6683,8 @@ function streamResponsesWS(model, context, options) {
6668
6683
  let terminalEvents = [];
6669
6684
  let fallback = false;
6670
6685
  let timedOut;
6686
+ let timedOutBudgetMs;
6687
+ let timedOutLagMs;
6671
6688
  let providerRejected = false;
6672
6689
  let localFailure = true;
6673
6690
  let transportLost = false;
@@ -6782,17 +6799,25 @@ function streamResponsesWS(model, context, options) {
6782
6799
  if (timer !== void 0) clearTimeout(timer);
6783
6800
  }
6784
6801
  };
6802
+ let phaseTimerInfo;
6785
6803
  const armPhaseTimer = (kind, timeoutMs) => {
6786
6804
  if (requestTimer !== void 0) {
6787
6805
  clearTimeout(requestTimer);
6788
6806
  requestTimer = void 0;
6789
6807
  }
6790
- if (timeoutMs === void 0 || timeoutMs <= 0 || finished) return;
6808
+ if (timeoutMs === void 0 || timeoutMs <= 0 || finished) {
6809
+ phaseTimerInfo = void 0;
6810
+ return;
6811
+ }
6791
6812
  const generation = requestGeneration;
6813
+ phaseTimerInfo = { kind, budgetMs: timeoutMs, armedAt: monotonicNow() };
6792
6814
  requestTimer = setTimeout(() => {
6793
6815
  requestTimer = void 0;
6794
6816
  if (generation !== requestGeneration || finished || requestAbort.signal.aborted) return;
6817
+ const info = phaseTimerInfo;
6795
6818
  timedOut = kind;
6819
+ timedOutBudgetMs = info?.budgetMs;
6820
+ timedOutLagMs = info ? Math.max(0, monotonicNow() - info.armedAt - info.budgetMs) : 0;
6796
6821
  retryDecision = sent ? "not_retryable_after_submission" : "not_submitted";
6797
6822
  lifecycle("timeout", {
6798
6823
  timeoutKind: kind,
@@ -6983,7 +7008,7 @@ function streamResponsesWS(model, context, options) {
6983
7008
  armPhaseTimer("stream_idle", budgets.streamIdleTimeoutMs);
6984
7009
  if (receivedMessageCount === 1) lifecycle("first_application_message");
6985
7010
  if (state.abort.signal.aborted || requestAbort.signal.aborted) {
6986
- throw new Error(timedOut ? `Responses request timeout (${timedOut})` : "Request aborted");
7011
+ throw new Error(timedOut ? `Responses request timeout (${timedOut})${timeoutSuffix(timedOutBudgetMs, timedOutLagMs ?? 0)}` : "Request aborted");
6987
7012
  }
6988
7013
  let events;
6989
7014
  try {
@@ -7067,7 +7092,7 @@ function streamResponsesWS(model, context, options) {
7067
7092
  message.stopReason = userAborted || ownerDisposed ? "aborted" : "error";
7068
7093
  if (userAborted || ownerDisposed) delete message.remoteFailure;
7069
7094
  const protocolFailure = !endedWithoutTerminal && (error instanceof ResponsesProtocolError || error instanceof SyntaxError || !transportLost && error instanceof TypeError || error instanceof WebSocketTransportError && (error.kind === "protocol" || error.kind === "overflow"));
7070
- const cause = providerRejected && error instanceof WebSocketTransportError ? `${error.message} (HTTP status ${error.status})` : timedOut && !protocolFailure ? `Responses request timeout (${timedOut}) after ${ageMs()}ms` : error instanceof Error ? error.message : String(error);
7095
+ const cause = providerRejected && error instanceof WebSocketTransportError ? `${error.message} (HTTP status ${error.status})` : timedOut && !protocolFailure ? `Responses request timeout (${timedOut}) after ${ageMs()}ms${timeoutSuffix(timedOutBudgetMs, timedOutLagMs ?? 0)}` : error instanceof Error ? error.message : String(error);
7071
7096
  message.errorMessage = cause;
7072
7097
  const streamLost = (endedWithoutTerminal || transportLost) && !protocolFailure && !localFailure && sent && !timedOut && !providerRejected && message.stopReason === "error";
7073
7098
  if (timedOut && timedOut !== "connect" && !message.remoteFailure && !protocolFailure && !localFailure && sent && !providerRejected && !userAborted && !ownerDisposed && compat.timeoutReplay) {
@@ -7,10 +7,12 @@ import {
7
7
  defaultShellKindForPlatform,
8
8
  interpretShellExit,
9
9
  requestInteraction
10
- } from "./chunk-XIRBNP2S.js";
10
+ } from "./chunk-AFPRX5XI.js";
11
11
  import {
12
+ EMPTY_ASSISTANT_CONTENT_ERROR,
13
+ OPENAI_COMPAT_PROTOCOL_ERROR_CODE,
12
14
  getLogger
13
- } from "./chunk-3VEIP2VY.js";
15
+ } from "./chunk-EN47TIBG.js";
14
16
  import {
15
17
  Type
16
18
  } from "./chunk-XXGYUYXI.js";
@@ -128,6 +130,153 @@ function migrateConfigFromAgentDir() {
128
130
  }
129
131
  }
130
132
 
133
+ // src/runtime/retry-policy.ts
134
+ var TRANSIENT_NETWORK_ERROR_PATTERN = /sse stream aborted|sse stream closed before end|sse stream ended before response completed|responses stream ended without a terminal event|(?:read\s+)?ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|ECONNREFUSED|(?:read\s+|write\s+)?EPIPE|socket hang up|request timeout|websocket upgrade refused|websocket handshake|websocket connection failed|websocket transport failed|connection closed before opening|client network socket disconnected before secure TLS connection was established|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated/i;
135
+ var TLS_VALIDATION_ERROR_PATTERN = /certificate (?:has )?expired|certificate is not yet valid|unable to verify (?:the first certificate|certificate)|unable to get (?:local )?issuer certificate|self[-_ ]signed cert(?:ificate)?|CERT_HAS_EXPIRED|SELF_SIGNED_CERT|does not match certificate's altnames|ERR_TLS_CERT_ALTNAME_INVALID/i;
136
+ var PROVIDER_TRANSIENT_ERROR_PATTERN = /overloaded|rate.?limit|too many requests|\b429\b|\b500\b|\b502\b|\b503\b|\b504\b|service.?unavailable|server error|internal error|retry delay|quota (?:has been |is )?exhausted/i;
137
+ var USER_ABORT_PATTERN = /request was aborted|local abort signal|user abort|user_interrupt|interrupted by user|esc pressed|ctrl\+c/i;
138
+ var AUTH_CONFIG_PATTERN = /missing api key|invalid api key|api key.*invalid|unauthorized|\b401\b|\b403\b|forbidden|authentication failed|no configured model|no models? are configured/i;
139
+ var QUOTA_EXHAUSTED_PATTERN = /insufficient[_ ]quota|exceeded[_ ]current[_ ]quota|exceeded your current quota|billing[_ ]hard[_ ]limit|insufficient[_ ]balance|credit balance is too low|\barrearage\b|余额不足|\b(?:account|monthly|billing) quota (?:has been |is )?exhausted/i;
140
+ var INVALID_FILE_REFERENCE_PATTERN = /not the owner of this file|owner of this file|invalid_authentication_error/i;
141
+ var INVALID_REQUEST_PATTERN = /bad request|\b400\b|invalid request|invalid schema|schema validation|invalid parameter|unsupported parameter|malformed/i;
142
+ var CLI_RETRY_MAX_RETRIES = 3;
143
+ var CLI_RETRY_BASE_DELAY_MS = 2e3;
144
+ var CLI_TRANSIENT_NETWORK_MAX_RETRIES = 10;
145
+ var CLI_RETRY_TOTAL_MAX_RETRIES = 12;
146
+ var CLI_RETRY_MAX_DELAY_MS = 6e4;
147
+ function isCliContextOverflowError(errorMessage) {
148
+ return /context length exceeded|context_length_exceeded|maximum context length|maximum context size|too many tokens|input.*too long|prompt.*too long|context window|token limit exceeded|exceeds.{0,20}context/i.test(
149
+ errorMessage
150
+ );
151
+ }
152
+ function createClassification(kind, message, overrides) {
153
+ return {
154
+ kind,
155
+ message,
156
+ retryable: false,
157
+ compactable: false,
158
+ userAbort: false,
159
+ terminal: true,
160
+ ...overrides
161
+ };
162
+ }
163
+ function classifyCliFailure(context) {
164
+ const errorMessage = typeof context === "string" ? context : context.errorMessage;
165
+ const structuredReplayClass = typeof context === "string" ? void 0 : context.message?.role === "assistant" ? context.message.replayClass : void 0;
166
+ if (isCliContextOverflowError(errorMessage)) {
167
+ return createClassification("context_overflow", errorMessage, {
168
+ compactable: true,
169
+ terminal: false
170
+ });
171
+ }
172
+ if (USER_ABORT_PATTERN.test(errorMessage)) {
173
+ return createClassification("user_abort", errorMessage, {
174
+ userAbort: true,
175
+ terminal: false
176
+ });
177
+ }
178
+ if (INVALID_FILE_REFERENCE_PATTERN.test(errorMessage)) {
179
+ return createClassification("invalid_file_reference", errorMessage);
180
+ }
181
+ if (AUTH_CONFIG_PATTERN.test(errorMessage) || QUOTA_EXHAUSTED_PATTERN.test(errorMessage)) {
182
+ return createClassification("auth_config", errorMessage);
183
+ }
184
+ if (TLS_VALIDATION_ERROR_PATTERN.test(errorMessage)) {
185
+ return createClassification("tls_config", errorMessage, {
186
+ retryable: true,
187
+ terminal: false
188
+ });
189
+ }
190
+ if (structuredReplayClass === "stream_lost" || structuredReplayClass === "stream_lost_partial" || TRANSIENT_NETWORK_ERROR_PATTERN.test(errorMessage)) {
191
+ return createClassification("transient_network", errorMessage, {
192
+ retryable: true,
193
+ terminal: false
194
+ });
195
+ }
196
+ if (errorMessage.includes(EMPTY_ASSISTANT_CONTENT_ERROR)) {
197
+ return createClassification("provider_transient", errorMessage, {
198
+ retryable: true,
199
+ terminal: false
200
+ });
201
+ }
202
+ if (errorMessage.includes(OPENAI_COMPAT_PROTOCOL_ERROR_CODE)) {
203
+ return createClassification("provider_transient", errorMessage, {
204
+ retryable: true,
205
+ terminal: false
206
+ });
207
+ }
208
+ if (PROVIDER_TRANSIENT_ERROR_PATTERN.test(errorMessage)) {
209
+ return createClassification("provider_transient", errorMessage, {
210
+ retryable: true,
211
+ terminal: false
212
+ });
213
+ }
214
+ if (INVALID_REQUEST_PATTERN.test(errorMessage)) {
215
+ return createClassification("invalid_request", errorMessage);
216
+ }
217
+ return createClassification("unknown", errorMessage);
218
+ }
219
+ function isCliRetryableError(errorMessage) {
220
+ return classifyCliFailure(errorMessage).retryable;
221
+ }
222
+ function getCliRetryBaseDelayMs() {
223
+ const override = process.env.PIE_TEST_CLI_RETRY_BASE_DELAY_MS;
224
+ if (!override) {
225
+ return CLI_RETRY_BASE_DELAY_MS;
226
+ }
227
+ const parsed = Number(override);
228
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : CLI_RETRY_BASE_DELAY_MS;
229
+ }
230
+ function getCliTransientNetworkMaxRetries() {
231
+ const override = process.env.PIE_RETRY_TRANSIENT_NETWORK_MAX_RETRIES;
232
+ if (!override) {
233
+ return CLI_TRANSIENT_NETWORK_MAX_RETRIES;
234
+ }
235
+ const parsed = Number(override);
236
+ return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : CLI_TRANSIENT_NETWORK_MAX_RETRIES;
237
+ }
238
+ function getCliRetryMaxDelayMs() {
239
+ const override = process.env.PIE_RETRY_MAX_DELAY_MS;
240
+ if (!override) {
241
+ return CLI_RETRY_MAX_DELAY_MS;
242
+ }
243
+ const parsed = Number(override);
244
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : CLI_RETRY_MAX_DELAY_MS;
245
+ }
246
+ function getCliRetryTotalMaxRetries() {
247
+ const override = process.env.PIE_RETRY_TOTAL_MAX_RETRIES;
248
+ if (!override) {
249
+ return CLI_RETRY_TOTAL_MAX_RETRIES;
250
+ }
251
+ const parsed = Number(override);
252
+ return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : CLI_RETRY_TOTAL_MAX_RETRIES;
253
+ }
254
+ function createCliRetryPolicy(isRetryableErrorOverride) {
255
+ return {
256
+ isRetryableError: isRetryableErrorOverride ?? isCliRetryableError,
257
+ maxRetries: CLI_RETRY_MAX_RETRIES,
258
+ baseDelayMs: getCliRetryBaseDelayMs(),
259
+ maxDelayMs: getCliRetryMaxDelayMs(),
260
+ maxRetriesForFailure: (failure) => failure.kind === "transient_network" ? getCliTransientNetworkMaxRetries() : failure.replayExempt === true ? getCliTimeoutReplayMaxRetries() : CLI_RETRY_MAX_RETRIES,
261
+ maxTotalRetries: getCliRetryTotalMaxRetries(),
262
+ systemicReplayStallLimit: getCliSystemicReplayStallLimit()
263
+ };
264
+ }
265
+ var CLI_TIMEOUT_REPLAY_MAX_RETRIES = 5;
266
+ function getCliTimeoutReplayMaxRetries() {
267
+ const override = process.env.PIE_TIMEOUT_REPLAY_MAX_RETRIES;
268
+ if (!override) return CLI_TIMEOUT_REPLAY_MAX_RETRIES;
269
+ const parsed = Number(override);
270
+ return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : CLI_TIMEOUT_REPLAY_MAX_RETRIES;
271
+ }
272
+ var CLI_SYSTEMIC_REPLAY_STALL_LIMIT = 3;
273
+ function getCliSystemicReplayStallLimit() {
274
+ const override = process.env.PIE_SYSTEMIC_REPLAY_STALL_LIMIT;
275
+ if (!override) return CLI_SYSTEMIC_REPLAY_STALL_LIMIT;
276
+ const parsed = Number(override);
277
+ return Number.isFinite(parsed) && parsed >= 1 ? Math.floor(parsed) : CLI_SYSTEMIC_REPLAY_STALL_LIMIT;
278
+ }
279
+
131
280
  // src/runtime/transport-diagnostics.ts
132
281
  function numberOrDash(value) {
133
282
  return typeof value === "number" ? String(value) : "-";
@@ -1621,6 +1770,11 @@ export {
1621
1770
  setYoloGrantListener,
1622
1771
  cleanupBashOutputArtifacts,
1623
1772
  createBashTool,
1773
+ CLI_RETRY_MAX_RETRIES,
1774
+ isCliContextOverflowError,
1775
+ classifyCliFailure,
1776
+ isCliRetryableError,
1777
+ createCliRetryPolicy,
1624
1778
  formatTransportLifecycle,
1625
1779
  createTransportDiagnosticsStreamFn,
1626
1780
  logTransportLifecycle,
@@ -6,8 +6,8 @@ import {
6
6
  bindToolCallerIdentity,
7
7
  createToolCallerIdentity,
8
8
  getToolCallerIdentity
9
- } from "./chunk-XVF6V6Q5.js";
10
- import "./chunk-3VEIP2VY.js";
9
+ } from "./chunk-2NBUFVUQ.js";
10
+ import "./chunk-EN47TIBG.js";
11
11
  import "./chunk-XXGYUYXI.js";
12
12
  import "./chunk-LZQXQOPJ.js";
13
13
  export {
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  EventStream
4
- } from "./chunk-3VEIP2VY.js";
4
+ } from "./chunk-EN47TIBG.js";
5
5
  import "./chunk-XXGYUYXI.js";
6
6
  import "./chunk-LZQXQOPJ.js";
7
7