@cydm/pie 2.7.11 → 2.7.13

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.
@@ -7,10 +7,12 @@ import {
7
7
  defaultShellKindForPlatform,
8
8
  interpretShellExit,
9
9
  requestInteraction
10
- } from "./chunk-XIRBNP2S.js";
10
+ } from "./chunk-CIFC6QVB.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-R46YPPTU.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,
@@ -4,7 +4,27 @@ import {
4
4
  disposeModelTransports,
5
5
  streamSimple,
6
6
  validateToolArguments
7
- } from "./chunk-3VEIP2VY.js";
7
+ } from "./chunk-R46YPPTU.js";
8
+
9
+ // ../../packages/agent-core/src/failure.ts
10
+ function getAgentFailureMetadata(error) {
11
+ if (!error || typeof error !== "object") return {};
12
+ const source = error;
13
+ return {
14
+ ...source.retryable === false ? { retryable: false } : {},
15
+ ...source.remoteFailure ? { remoteFailure: source.remoteFailure } : {},
16
+ ...source.replayEligible === true ? { replayEligible: true } : {},
17
+ ...typeof source.replayClass === "string" ? { replayClass: source.replayClass } : {},
18
+ ...source.operationFailure ? { operationFailure: source.operationFailure } : {}
19
+ };
20
+ }
21
+ function createAgentOperationError(error, failure) {
22
+ return Object.assign(
23
+ new Error(error instanceof Error ? error.message : String(error), { cause: error }),
24
+ getAgentFailureMetadata(error),
25
+ { operationFailure: failure }
26
+ );
27
+ }
8
28
 
9
29
  // ../../packages/agent-core/src/agent-loop.ts
10
30
  function createLoopErrorMessage(error, config, signal) {
@@ -25,6 +45,7 @@ function createLoopErrorMessage(error, config, signal) {
25
45
  },
26
46
  stopReason: signal?.aborted ? "aborted" : "error",
27
47
  errorMessage: message,
48
+ ...getAgentFailureMetadata(error),
28
49
  timestamp: Date.now()
29
50
  };
30
51
  }
@@ -182,6 +203,11 @@ async function runLoop(currentContext, newMessages, config, signal, stream, stre
182
203
  }
183
204
  }
184
205
  stream.push({ type: "turn_end", message, toolResults });
206
+ if (hasMoreToolCalls && config.beforeToolContinuation) {
207
+ const replacement = await config.beforeToolContinuation(signal);
208
+ if (signal?.aborted) throw new Error("Request was aborted");
209
+ if (replacement) currentContext.messages = replacement.slice();
210
+ }
185
211
  if (steeringAfterTools && steeringAfterTools.length > 0) {
186
212
  pendingMessages = steeringAfterTools;
187
213
  steeringAfterTools = null;
@@ -444,7 +470,22 @@ function isUserContentBlock(value) {
444
470
  return false;
445
471
  }
446
472
  const type = value.type;
447
- return type === "text" || type === "image" || type === "audio" || type === "video" || type === "fileRef";
473
+ return type === "text" || type === "image" || type === "audio" || type === "video" || type === "fileRef" || type === "hostContext";
474
+ }
475
+ async function awaitToolContinuation(handler, signal) {
476
+ let onAbort;
477
+ const cancelled = new Promise((_resolve, reject) => {
478
+ onAbort = () => reject(new Error("Request was aborted"));
479
+ signal.addEventListener("abort", onAbort, { once: true });
480
+ });
481
+ try {
482
+ await Promise.race([Promise.resolve().then(() => {
483
+ if (signal.aborted) throw new Error("Request was aborted");
484
+ return handler(signal);
485
+ }), cancelled]);
486
+ } finally {
487
+ signal.removeEventListener("abort", onAbort);
488
+ }
448
489
  }
449
490
  var Agent = class {
450
491
  _state;
@@ -467,6 +508,7 @@ var Agent = class {
467
508
  _thinkingBudgets;
468
509
  _maxRetryDelayMs;
469
510
  hooks;
511
+ beforeToolContinuation;
470
512
  /** Stable identity for this agent instance, bound onto every run signal
471
513
  * handed to tools (signals themselves are per-run; see tool-caller-identity.ts). */
472
514
  toolCallerIdentity = createToolCallerIdentity();
@@ -559,6 +601,15 @@ var Agent = class {
559
601
  setHooks(hooks) {
560
602
  this.hooks = hooks;
561
603
  }
604
+ /** Single session-policy owner. Runs after the complete tool turn has been
605
+ * published to observers; replaceMessages here also updates the active loop.
606
+ * Removal does not detach a callback already captured by an active run. */
607
+ setBeforeToolContinuation(handler) {
608
+ this.beforeToolContinuation = handler;
609
+ return () => {
610
+ if (this.beforeToolContinuation === handler) this.beforeToolContinuation = void 0;
611
+ };
612
+ }
562
613
  replaceMessages(ms) {
563
614
  this.releaseTransport();
564
615
  this._state.messages = ms.slice();
@@ -648,6 +699,7 @@ var Agent = class {
648
699
  this._state.error = void 0;
649
700
  this.steeringQueue = [];
650
701
  this.followUpQueue = [];
702
+ this.resolveRunningPrompt?.();
651
703
  this.runningPrompt = void 0;
652
704
  this.resolveRunningPrompt = void 0;
653
705
  this.updateStatusSnapshot({
@@ -670,6 +722,7 @@ var Agent = class {
670
722
  this._state.error = void 0;
671
723
  this.steeringQueue = [];
672
724
  this.followUpQueue = [];
725
+ this.resolveRunningPrompt?.();
673
726
  this.runningPrompt = void 0;
674
727
  this.resolveRunningPrompt = void 0;
675
728
  this.abortController = void 0;
@@ -784,6 +837,8 @@ var Agent = class {
784
837
  tools: this._state.tools
785
838
  };
786
839
  let skipInitialSteeringPoll = options?.skipInitialSteeringPoll === true;
840
+ const beforeToolContinuation = this.beforeToolContinuation;
841
+ let acknowledgeToolTurn;
787
842
  const config = {
788
843
  model,
789
844
  reasoning,
@@ -794,6 +849,16 @@ var Agent = class {
794
849
  maxRetryDelayMs: this._maxRetryDelayMs,
795
850
  convertToLlm: this.convertToLlm,
796
851
  transformContext: this.transformContext,
852
+ beforeToolContinuation: beforeToolContinuation ? async () => {
853
+ await new Promise((resolve) => {
854
+ acknowledgeToolTurn = resolve;
855
+ });
856
+ acknowledgeToolTurn = void 0;
857
+ if (!ownsRun() || runController.signal.aborted) throw new Error("Request was aborted");
858
+ await awaitToolContinuation(beforeToolContinuation, runController.signal);
859
+ if (!ownsRun() || runController.signal.aborted) throw new Error("Request was aborted");
860
+ return this._state.messages.slice();
861
+ } : void 0,
797
862
  getApiKey: this.getApiKey,
798
863
  hooks: this.hooks,
799
864
  getSteeringMessages: async () => {
@@ -855,6 +920,7 @@ var Agent = class {
855
920
  break;
856
921
  }
857
922
  this.emit(event, ownsRun);
923
+ if (event.type === "turn_end") acknowledgeToolTurn?.();
858
924
  }
859
925
  if (ownsRun() && partial && partial.role === "assistant" && partial.content?.length > 0) {
860
926
  const onlyEmpty = !partial.content.some(
@@ -889,6 +955,7 @@ var Agent = class {
889
955
  this._state.error = err?.message || String(err);
890
956
  this.emit({ type: "agent_end", messages: [errorMsg] }, ownsRun);
891
957
  } finally {
958
+ acknowledgeToolTurn?.();
892
959
  if (ownsRun()) {
893
960
  this._state.isStreaming = false;
894
961
  this._state.streamMessage = null;
@@ -1086,6 +1153,8 @@ var Agent = class {
1086
1153
  };
1087
1154
 
1088
1155
  export {
1156
+ getAgentFailureMetadata,
1157
+ createAgentOperationError,
1089
1158
  agentLoop,
1090
1159
  agentLoopContinue,
1091
1160
  createToolCallerIdentity,
@@ -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);
@@ -3402,33 +3408,33 @@ function isPuertsReparsePoint(path) {
3402
3408
  }
3403
3409
  function containsPuertsReparsePoint(directory) {
3404
3410
  const slashed = directory.replace(/\\/g, "/");
3405
- const trimmed = slashed.replace(/\/+$/, "");
3406
- if (!trimmed || trimmed === "/") return false;
3407
- const unc = /^\/\/([^/]+)\/([^/]+)/.exec(trimmed);
3411
+ if (!slashed) return false;
3412
+ const unc = /^\/\/([^/]+)\/([^/]+)/.exec(slashed);
3408
3413
  let prefix;
3409
3414
  let rest;
3410
3415
  if (unc) {
3411
3416
  prefix = unc[0];
3412
- rest = trimmed.slice(prefix.length);
3417
+ rest = slashed.slice(prefix.length);
3413
3418
  } else {
3414
- const driveRoot = /^([a-zA-Z]:)\//.exec(trimmed);
3419
+ const driveRoot = /^([a-zA-Z]:)\//.exec(slashed);
3415
3420
  if (driveRoot) {
3416
3421
  prefix = `${driveRoot[1]}/`;
3417
- rest = trimmed.slice(prefix.length);
3422
+ rest = slashed.slice(prefix.length);
3418
3423
  } else {
3419
- const bareDrive = /^[a-zA-Z]:$/.test(trimmed);
3424
+ const bareDrive = /^[a-zA-Z]:$/.test(slashed);
3420
3425
  if (bareDrive) {
3421
- return isPuertsReparsePoint(trimmed);
3426
+ return isPuertsReparsePoint(slashed);
3422
3427
  }
3423
- if (trimmed.startsWith("/")) {
3428
+ if (slashed.startsWith("/")) {
3424
3429
  prefix = "/";
3425
- rest = trimmed.slice(1);
3430
+ rest = slashed.slice(1);
3426
3431
  } else {
3427
3432
  prefix = "";
3428
- rest = trimmed;
3433
+ rest = slashed;
3429
3434
  }
3430
3435
  }
3431
3436
  }
3437
+ if (prefix && isPuertsReparsePoint(prefix)) return true;
3432
3438
  let current = prefix;
3433
3439
  for (const part of rest.split("/").filter((segment) => segment.length > 0 && segment !== ".")) {
3434
3440
  current = current ? current.endsWith("/") ? `${current}${part}` : `${current}/${part}` : part;
@@ -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) {
@@ -4,10 +4,12 @@ import {
4
4
  agentLoop,
5
5
  agentLoopContinue,
6
6
  bindToolCallerIdentity,
7
+ createAgentOperationError,
7
8
  createToolCallerIdentity,
9
+ getAgentFailureMetadata,
8
10
  getToolCallerIdentity
9
- } from "./chunk-XVF6V6Q5.js";
10
- import "./chunk-3VEIP2VY.js";
11
+ } from "./chunk-HGUYS5SF.js";
12
+ import "./chunk-R46YPPTU.js";
11
13
  import "./chunk-XXGYUYXI.js";
12
14
  import "./chunk-LZQXQOPJ.js";
13
15
  export {
@@ -15,6 +17,8 @@ export {
15
17
  agentLoop,
16
18
  agentLoopContinue,
17
19
  bindToolCallerIdentity,
20
+ createAgentOperationError,
18
21
  createToolCallerIdentity,
22
+ getAgentFailureMetadata,
19
23
  getToolCallerIdentity
20
24
  };
@@ -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-R46YPPTU.js";
5
5
  import "./chunk-XXGYUYXI.js";
6
6
  import "./chunk-LZQXQOPJ.js";
7
7