@opengeni/runtime 0.7.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/THIRD_PARTY_NOTICES +32 -0
  2. package/dist/agent-UMUIWWD2.js +8 -0
  3. package/dist/agent-UMUIWWD2.js.map +1 -0
  4. package/dist/chunk-4YJ5Z52Z.js +1789 -0
  5. package/dist/chunk-4YJ5Z52Z.js.map +1 -0
  6. package/dist/chunk-DPULLAJG.js +215 -0
  7. package/dist/chunk-DPULLAJG.js.map +1 -0
  8. package/dist/chunk-K4V4QYCL.js +37683 -0
  9. package/dist/chunk-K4V4QYCL.js.map +1 -0
  10. package/dist/chunk-PZ5AY32C.js +10 -0
  11. package/dist/chunk-PZ5AY32C.js.map +1 -0
  12. package/dist/chunk-YUAFQEFY.js +21522 -0
  13. package/dist/chunk-YUAFQEFY.js.map +1 -0
  14. package/dist/{index-DIiiwQY2.d.ts → index-D6yi-JcU.d.ts} +138 -15
  15. package/dist/index.d.ts +329 -121
  16. package/dist/index.js +8149 -307
  17. package/dist/index.js.map +1 -1
  18. package/dist/localSources-T3HZ6KY4.js +15 -0
  19. package/dist/localSources-T3HZ6KY4.js.map +1 -0
  20. package/dist/sandbox/index.d.ts +1 -1
  21. package/dist/sandbox/index.js +42 -5
  22. package/dist/skill-library.d.ts +74 -0
  23. package/dist/skill-library.js +18 -0
  24. package/dist/skill-library.js.map +1 -0
  25. package/package.json +13 -5
  26. package/src/bundled_hashicorp_terraform_skills/README.md +3 -3
  27. package/src/bundled_hashicorp_terraform_skills/checkov/SKILL.md +1 -1
  28. package/src/context-compaction.ts +421 -24
  29. package/src/history-sanitizer.ts +14 -5
  30. package/src/index.ts +1335 -280
  31. package/src/sandbox/channel-a.ts +535 -97
  32. package/src/sandbox/index.ts +36 -2
  33. package/src/sandbox/routing/routing-session.ts +10 -2
  34. package/src/sandbox/run-credentials.ts +818 -0
  35. package/src/sandbox/select.ts +3 -3
  36. package/src/sandbox/selfhosted/capabilities.ts +1 -1
  37. package/src/sandbox/selfhosted/op-stream.ts +40 -0
  38. package/src/sandbox/selfhosted/op-testing.ts +50 -3
  39. package/src/sandbox/selfhosted/session.ts +17 -4
  40. package/src/sandbox/selfhosted/testing.ts +1 -1
  41. package/src/sandbox/stream-port.ts +1 -1
  42. package/src/sandbox/stream-token.ts +1 -1
  43. package/src/sandbox/terminal-server.ts +6 -2
  44. package/src/sandbox/toolspace-token.ts +147 -0
  45. package/src/sandbox/turn-tool-cancellation.ts +940 -0
  46. package/src/skill-library.ts +323 -0
  47. package/dist/chunk-RYDCVTMW.js +0 -5531
  48. package/dist/chunk-RYDCVTMW.js.map +0 -1
  49. /package/src/{bundled_hashicorp_terraform_skills → bundled_skill_library}/azure-verified-modules/SKILL.md +0 -0
@@ -0,0 +1,1789 @@
1
+ import {
2
+ Manifest,
3
+ SandboxMountError,
4
+ SandboxPathResolutionError,
5
+ SandboxUnsupportedFeatureError,
6
+ UserError,
7
+ WorkspacePathPolicy,
8
+ addTraceProcessor,
9
+ cloneManifest,
10
+ defaultProcessor,
11
+ getLogger,
12
+ isMount,
13
+ isRecord,
14
+ logger,
15
+ mergeManifestDelta,
16
+ mergeManifestEntryDelta,
17
+ mergeMaterializedEnvironment,
18
+ normalizePosixPath,
19
+ normalizeRelativePath,
20
+ randomUUID,
21
+ relativePosixPathWithinRoot,
22
+ shellQuote
23
+ } from "./chunk-K4V4QYCL.js";
24
+
25
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/mcpServers.mjs
26
+ var DEFAULT_CONNECT_TIMEOUT_MS = 1e4;
27
+ var DEFAULT_CLOSE_TIMEOUT_MS = 1e4;
28
+ var logger2 = getLogger("openai-agents:mcp-servers");
29
+ var ServerWorker = class {
30
+ server;
31
+ connectTimeoutMs;
32
+ closeTimeoutMs;
33
+ queue = [];
34
+ draining = false;
35
+ done = false;
36
+ closing = null;
37
+ closeResult = null;
38
+ constructor(server, connectTimeoutMs, closeTimeoutMs) {
39
+ this.server = server;
40
+ this.connectTimeoutMs = connectTimeoutMs;
41
+ this.closeTimeoutMs = closeTimeoutMs;
42
+ }
43
+ get isDone() {
44
+ return this.done;
45
+ }
46
+ connect() {
47
+ return this.submit("connect", this.connectTimeoutMs);
48
+ }
49
+ close() {
50
+ return this.submit("close", this.closeTimeoutMs);
51
+ }
52
+ submit(action, timeoutMs) {
53
+ if (this.done) {
54
+ return Promise.reject(createClosedError(this.server));
55
+ }
56
+ if (this.closeResult || this.closing) {
57
+ if (action === "close" && this.closeResult) {
58
+ return this.closeResult;
59
+ }
60
+ return Promise.reject(createClosingError(this.server));
61
+ }
62
+ let resolveCommand;
63
+ let rejectCommand;
64
+ const promise = new Promise((resolve2, reject) => {
65
+ resolveCommand = resolve2;
66
+ rejectCommand = reject;
67
+ });
68
+ const command = {
69
+ action,
70
+ timeoutMs,
71
+ resolve: resolveCommand,
72
+ reject: rejectCommand
73
+ };
74
+ if (action === "close") {
75
+ this.closeResult = promise;
76
+ }
77
+ this.queue.push(command);
78
+ void this.drain();
79
+ return promise;
80
+ }
81
+ async drain() {
82
+ if (this.draining) {
83
+ return;
84
+ }
85
+ this.draining = true;
86
+ while (this.queue.length > 0) {
87
+ const command = this.queue.shift();
88
+ if (!command) {
89
+ continue;
90
+ }
91
+ const shouldExit = command.action === "close";
92
+ let closeError = null;
93
+ try {
94
+ if (command.action === "connect") {
95
+ await runWithTimeout(() => this.server.connect(), command.timeoutMs, createTimeoutError("connect", this.server, command.timeoutMs));
96
+ } else {
97
+ const closeTask = this.server.close();
98
+ this.closing = closeTask.then(() => void 0, () => void 0).finally(() => {
99
+ this.closing = null;
100
+ });
101
+ await runWithTimeoutTask(closeTask, command.timeoutMs, createTimeoutError("close", this.server, command.timeoutMs));
102
+ }
103
+ command.resolve();
104
+ } catch (error) {
105
+ const err = toError(error);
106
+ command.reject(err);
107
+ if (shouldExit) {
108
+ closeError = err;
109
+ }
110
+ }
111
+ if (shouldExit) {
112
+ const pendingError = closeError ?? createClosedError(this.server);
113
+ while (this.queue.length > 0) {
114
+ const pending = this.queue.shift();
115
+ if (pending) {
116
+ pending.reject(pendingError);
117
+ }
118
+ }
119
+ this.closeResult = null;
120
+ if (!closeError) {
121
+ this.done = true;
122
+ }
123
+ break;
124
+ }
125
+ }
126
+ this.draining = false;
127
+ }
128
+ };
129
+ var MCPServers = class _MCPServers {
130
+ allServers;
131
+ activeServers;
132
+ failedServers = [];
133
+ failedServerSet = /* @__PURE__ */ new Set();
134
+ errorsByServer = /* @__PURE__ */ new Map();
135
+ suppressedAbortFailures = /* @__PURE__ */ new Set();
136
+ workers = /* @__PURE__ */ new Map();
137
+ connectTimeoutMs;
138
+ closeTimeoutMs;
139
+ dropFailed;
140
+ strict;
141
+ suppressAbortError;
142
+ connectInParallel;
143
+ static {
144
+ const asyncDispose = Symbol.asyncDispose;
145
+ if (asyncDispose) {
146
+ Object.defineProperty(this.prototype, asyncDispose, {
147
+ value: function() {
148
+ return this.close();
149
+ },
150
+ configurable: true
151
+ });
152
+ }
153
+ }
154
+ constructor(servers, options) {
155
+ this.allServers = [...servers];
156
+ this.activeServers = [...servers];
157
+ this.connectTimeoutMs = options?.connectTimeoutMs === void 0 ? DEFAULT_CONNECT_TIMEOUT_MS : options.connectTimeoutMs;
158
+ this.closeTimeoutMs = options?.closeTimeoutMs === void 0 ? DEFAULT_CLOSE_TIMEOUT_MS : options.closeTimeoutMs;
159
+ this.dropFailed = options?.dropFailed ?? true;
160
+ this.strict = options?.strict ?? false;
161
+ this.suppressAbortError = options?.suppressAbortError ?? true;
162
+ this.connectInParallel = options?.connectInParallel ?? false;
163
+ }
164
+ static async open(servers, options) {
165
+ const session = new _MCPServers(servers, options);
166
+ logger2.debug(`Opening MCPServers with ${session.allServers.length} server(s).`);
167
+ await session.connectAll();
168
+ return session;
169
+ }
170
+ get all() {
171
+ return [...this.allServers];
172
+ }
173
+ get active() {
174
+ return [...this.activeServers];
175
+ }
176
+ get failed() {
177
+ return [...this.failedServers];
178
+ }
179
+ get errors() {
180
+ return new Map(this.errorsByServer);
181
+ }
182
+ async reconnect(options = {}) {
183
+ const failedOnly = options.failedOnly ?? true;
184
+ let serversToRetry;
185
+ if (failedOnly) {
186
+ serversToRetry = uniqueServers(this.failedServers);
187
+ } else {
188
+ serversToRetry = [...this.allServers];
189
+ this.failedServers = [];
190
+ this.failedServerSet = /* @__PURE__ */ new Set();
191
+ this.errorsByServer = /* @__PURE__ */ new Map();
192
+ this.suppressedAbortFailures = /* @__PURE__ */ new Set();
193
+ }
194
+ logger2.debug(`Reconnecting MCP servers (failedOnly=${failedOnly}) with ${serversToRetry.length} target(s).`);
195
+ if (this.connectInParallel) {
196
+ await this.connectAllParallel(serversToRetry);
197
+ } else {
198
+ for (const server of serversToRetry) {
199
+ await this.attemptConnect(server);
200
+ }
201
+ }
202
+ this.refreshActiveServers();
203
+ return this.active;
204
+ }
205
+ async close() {
206
+ await this.closeAll();
207
+ }
208
+ async connectAll() {
209
+ this.failedServers = [];
210
+ this.failedServerSet = /* @__PURE__ */ new Set();
211
+ this.errorsByServer = /* @__PURE__ */ new Map();
212
+ this.suppressedAbortFailures = /* @__PURE__ */ new Set();
213
+ const serversToConnect = [...this.allServers];
214
+ let connectedServers = [];
215
+ logger2.debug(`Connecting ${serversToConnect.length} MCP server(s).`);
216
+ try {
217
+ if (this.connectInParallel) {
218
+ await this.connectAllParallel(serversToConnect);
219
+ } else {
220
+ for (const server of serversToConnect) {
221
+ await this.attemptConnect(server);
222
+ if (!this.failedServerSet.has(server)) {
223
+ connectedServers.push(server);
224
+ }
225
+ }
226
+ }
227
+ } catch (error) {
228
+ if (this.connectInParallel) {
229
+ connectedServers = serversToConnect.filter((server) => !this.failedServerSet.has(server));
230
+ }
231
+ const serversToCleanup = uniqueServers([
232
+ ...connectedServers,
233
+ ...this.failedServers
234
+ ]);
235
+ await this.closeServers(serversToCleanup);
236
+ this.activeServers = [];
237
+ throw error;
238
+ }
239
+ this.refreshActiveServers();
240
+ return this.active;
241
+ }
242
+ async closeAll() {
243
+ for (const server of [...this.allServers].reverse()) {
244
+ await this.closeServer(server);
245
+ }
246
+ }
247
+ async attemptConnect(server) {
248
+ const raiseOnError = this.strict;
249
+ try {
250
+ logger2.debug(`Connecting MCP server '${server.name}'.`);
251
+ await this.runConnect(server);
252
+ logger2.debug(`Connected MCP server '${server.name}'.`);
253
+ if (this.failedServerSet.has(server)) {
254
+ this.removeFailedServer(server);
255
+ this.errorsByServer.delete(server);
256
+ }
257
+ } catch (error) {
258
+ const err = toError(error);
259
+ if (isAbortError(err)) {
260
+ this.recordFailure(server, err, "connect");
261
+ if (!this.suppressAbortError) {
262
+ this.suppressedAbortFailures.delete(server);
263
+ throw err;
264
+ }
265
+ this.suppressedAbortFailures.add(server);
266
+ return;
267
+ }
268
+ this.suppressedAbortFailures.delete(server);
269
+ this.recordFailure(server, err, "connect");
270
+ if (raiseOnError) {
271
+ throw err;
272
+ }
273
+ }
274
+ }
275
+ refreshActiveServers() {
276
+ if (this.dropFailed) {
277
+ const failed = new Set(this.failedServerSet);
278
+ this.activeServers = this.allServers.filter((server) => !failed.has(server));
279
+ } else {
280
+ this.activeServers = [...this.allServers];
281
+ }
282
+ logger2.debug(`Active MCP servers: ${this.activeServers.length}; failed: ${this.failedServers.length}.`);
283
+ }
284
+ recordFailure(server, error, phase) {
285
+ logger2.error(`Failed to ${phase} MCP server '${server.name}':`, error);
286
+ if (!this.failedServerSet.has(server)) {
287
+ this.failedServers.push(server);
288
+ this.failedServerSet.add(server);
289
+ }
290
+ this.errorsByServer.set(server, error);
291
+ }
292
+ async runConnect(server) {
293
+ if (this.connectInParallel) {
294
+ const worker = this.getWorker(server);
295
+ await worker.connect();
296
+ return;
297
+ }
298
+ await runWithTimeout(() => server.connect(), this.connectTimeoutMs, createTimeoutError("connect", server, this.connectTimeoutMs));
299
+ }
300
+ async closeServer(server) {
301
+ try {
302
+ logger2.debug(`Closing MCP server '${server.name}'.`);
303
+ await this.runClose(server);
304
+ logger2.debug(`Closed MCP server '${server.name}'.`);
305
+ } catch (error) {
306
+ const err = toError(error);
307
+ if (isAbortError(err)) {
308
+ if (!this.suppressAbortError) {
309
+ throw err;
310
+ }
311
+ logger2.debug(`Close cancelled for MCP server '${server.name}': ${err}`);
312
+ this.errorsByServer.set(server, err);
313
+ return;
314
+ }
315
+ logger2.error(`Failed to close MCP server '${server.name}':`, err);
316
+ this.errorsByServer.set(server, err);
317
+ }
318
+ }
319
+ async runClose(server) {
320
+ if (this.connectInParallel && this.workers.has(server)) {
321
+ const worker = this.workers.get(server);
322
+ if (worker) {
323
+ await worker.close();
324
+ if (worker.isDone) {
325
+ this.workers.delete(server);
326
+ }
327
+ return;
328
+ }
329
+ }
330
+ await runWithTimeout(() => server.close(), this.closeTimeoutMs, createTimeoutError("close", server, this.closeTimeoutMs));
331
+ }
332
+ async closeServers(servers) {
333
+ for (const server of [...servers].reverse()) {
334
+ await this.closeServer(server);
335
+ }
336
+ }
337
+ async connectAllParallel(servers) {
338
+ const results = await Promise.allSettled(servers.map((server) => this.attemptConnect(server)));
339
+ const rejection = results.find((result) => result.status === "rejected");
340
+ if (rejection) {
341
+ throw rejection.reason;
342
+ }
343
+ if (this.strict && this.failedServers.length > 0) {
344
+ const firstFailure = this.failedServers.find((server) => !this.suppressedAbortFailures.has(server));
345
+ if (firstFailure) {
346
+ const error = this.errorsByServer.get(firstFailure);
347
+ if (error) {
348
+ throw error;
349
+ }
350
+ throw new Error(`Failed to connect MCP server '${firstFailure.name}'.`);
351
+ }
352
+ }
353
+ }
354
+ getWorker(server) {
355
+ const worker = this.workers.get(server);
356
+ if (!worker || worker.isDone) {
357
+ const next = new ServerWorker(server, this.connectTimeoutMs, this.closeTimeoutMs);
358
+ this.workers.set(server, next);
359
+ return next;
360
+ }
361
+ return worker;
362
+ }
363
+ removeFailedServer(server) {
364
+ if (this.failedServerSet.has(server)) {
365
+ this.failedServerSet.delete(server);
366
+ }
367
+ this.suppressedAbortFailures.delete(server);
368
+ this.failedServers = this.failedServers.filter((failedServer) => failedServer !== server);
369
+ }
370
+ };
371
+ async function connectMcpServers(servers, options) {
372
+ return MCPServers.open(servers, options);
373
+ }
374
+ function createTimeoutError(action, server, timeoutMs) {
375
+ if (timeoutMs === null) {
376
+ return new Error(`MCP server ${action} timed out.`);
377
+ }
378
+ const error = new Error(`MCP server ${action} timed out after ${timeoutMs}ms for '${server.name}'.`);
379
+ error.name = "TimeoutError";
380
+ return error;
381
+ }
382
+ function createClosedError(server) {
383
+ const error = new Error(`MCP server '${server.name}' is closed.`);
384
+ error.name = "ClosedError";
385
+ return error;
386
+ }
387
+ function createClosingError(server) {
388
+ const error = new Error(`MCP server '${server.name}' is closing.`);
389
+ error.name = "ClosingError";
390
+ return error;
391
+ }
392
+ async function runWithTimeout(fn, timeoutMs, timeoutError) {
393
+ if (timeoutMs === null) {
394
+ await fn();
395
+ return;
396
+ }
397
+ let timer;
398
+ let timedOut = false;
399
+ const task = fn();
400
+ const timeoutPromise = new Promise((_, reject) => {
401
+ timer = setTimeout(() => {
402
+ timedOut = true;
403
+ reject(timeoutError);
404
+ }, timeoutMs);
405
+ });
406
+ try {
407
+ await Promise.race([task, timeoutPromise]);
408
+ } finally {
409
+ if (timer) {
410
+ clearTimeout(timer);
411
+ }
412
+ if (timedOut) {
413
+ task.catch(() => void 0);
414
+ }
415
+ }
416
+ }
417
+ async function runWithTimeoutTask(task, timeoutMs, timeoutError) {
418
+ if (timeoutMs === null) {
419
+ await task;
420
+ return;
421
+ }
422
+ let timer;
423
+ let timedOut = false;
424
+ const timeoutPromise = new Promise((_, reject) => {
425
+ timer = setTimeout(() => {
426
+ timedOut = true;
427
+ reject(timeoutError);
428
+ }, timeoutMs);
429
+ });
430
+ try {
431
+ await Promise.race([task, timeoutPromise]);
432
+ } finally {
433
+ if (timer) {
434
+ clearTimeout(timer);
435
+ }
436
+ if (timedOut) {
437
+ task.catch(() => void 0);
438
+ }
439
+ }
440
+ }
441
+ function toError(error) {
442
+ if (error instanceof Error) {
443
+ return error;
444
+ }
445
+ return new Error(String(error));
446
+ }
447
+ function isAbortError(error) {
448
+ const code = error.code;
449
+ return error.name === "AbortError" || error.name === "CanceledError" || error.name === "CancelledError" || code === "ABORT_ERR" || code === "ERR_ABORTED";
450
+ }
451
+ function uniqueServers(servers) {
452
+ const seen = /* @__PURE__ */ new Set();
453
+ const unique = [];
454
+ for (const server of servers) {
455
+ if (!seen.has(server)) {
456
+ seen.add(server);
457
+ unique.push(server);
458
+ }
459
+ }
460
+ return unique;
461
+ }
462
+
463
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/memory/historyMutations.mjs
464
+ function applySessionHistoryMutations(items, mutations) {
465
+ let nextItems = items.map((item) => structuredClone(item));
466
+ for (const mutation of mutations) {
467
+ if (mutation.type === "replace_function_call") {
468
+ nextItems = applyReplaceFunctionCallMutation(nextItems, mutation);
469
+ }
470
+ }
471
+ return nextItems;
472
+ }
473
+ function applyReplaceFunctionCallMutation(items, mutation) {
474
+ const replacement = structuredClone(mutation.replacement);
475
+ const nextItems = [];
476
+ let keptReplacement = false;
477
+ for (const item of items) {
478
+ if (item.type === "function_call" && item.callId === mutation.callId) {
479
+ if (!keptReplacement) {
480
+ nextItems.push(replacement);
481
+ keptReplacement = true;
482
+ }
483
+ continue;
484
+ }
485
+ nextItems.push(item);
486
+ }
487
+ return nextItems;
488
+ }
489
+
490
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/memory/memorySession.mjs
491
+ var MemorySession = class {
492
+ sessionId;
493
+ logger;
494
+ items;
495
+ constructor(options = {}) {
496
+ this.sessionId = options.sessionId ?? randomUUID();
497
+ this.items = options.initialItems ? options.initialItems.map(cloneAgentItem) : [];
498
+ this.logger = options.logger ?? logger;
499
+ }
500
+ async getSessionId() {
501
+ return this.sessionId;
502
+ }
503
+ async getItems(limit) {
504
+ if (limit === void 0) {
505
+ const cloned = this.items.map(cloneAgentItem);
506
+ this.logger.debug(`Getting items from memory session (${this.sessionId}): ${JSON.stringify(cloned)}`);
507
+ return cloned;
508
+ }
509
+ if (limit <= 0) {
510
+ return [];
511
+ }
512
+ const start = Math.max(this.items.length - limit, 0);
513
+ const items = this.items.slice(start).map(cloneAgentItem);
514
+ this.logger.debug(`Getting items from memory session (${this.sessionId}): ${JSON.stringify(items)}`);
515
+ return items;
516
+ }
517
+ async addItems(items) {
518
+ if (items.length === 0) {
519
+ return;
520
+ }
521
+ const cloned = items.map(cloneAgentItem);
522
+ this.logger.debug(`Adding items to memory session (${this.sessionId}): ${JSON.stringify(cloned)}`);
523
+ this.items = [...this.items, ...cloned];
524
+ }
525
+ async popItem() {
526
+ if (this.items.length === 0) {
527
+ return void 0;
528
+ }
529
+ const item = this.items[this.items.length - 1];
530
+ const cloned = cloneAgentItem(item);
531
+ this.logger.debug(`Popping item from memory session (${this.sessionId}): ${JSON.stringify(cloned)}`);
532
+ this.items = this.items.slice(0, -1);
533
+ return cloned;
534
+ }
535
+ async clearSession() {
536
+ this.logger.debug(`Clearing memory session (${this.sessionId})`);
537
+ this.items = [];
538
+ }
539
+ async applyHistoryMutations(args) {
540
+ if (args.mutations.length === 0) {
541
+ return;
542
+ }
543
+ this.items = applySessionHistoryMutations(this.items, args.mutations);
544
+ }
545
+ };
546
+ function cloneAgentItem(item) {
547
+ return structuredClone(item);
548
+ }
549
+
550
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/index.mjs
551
+ addTraceProcessor(defaultProcessor());
552
+
553
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/sandbox/shared/output.mjs
554
+ var APPROX_BYTES_PER_TOKEN = 4;
555
+ function truncateOutput(output, maxOutputTokens) {
556
+ if (maxOutputTokens == null) {
557
+ return { text: output };
558
+ }
559
+ const maxBytes = Math.max(0, maxOutputTokens) * APPROX_BYTES_PER_TOKEN;
560
+ const outputBytes = byteLength(output);
561
+ if (outputBytes <= maxBytes) {
562
+ return { text: output };
563
+ }
564
+ const originalTokenCount = approximateTokenCountFromBytes(outputBytes);
565
+ const totalLines = countLines(output);
566
+ const marker = `...${approximateTokenCountFromBytes(outputBytes - maxBytes)} tokens truncated...`;
567
+ const preservedPrefix = getPreservedLeadingNotice(output);
568
+ const prefixBytes = byteLength(preservedPrefix);
569
+ const body = preservedPrefix ? output.slice(preservedPrefix.length) : output;
570
+ const bodyBudget = Math.max(0, maxBytes - prefixBytes);
571
+ const truncatedBody = bodyBudget === 0 ? marker : truncateWithByteBudget(body, bodyBudget, marker);
572
+ const truncated = `${preservedPrefix}${truncatedBody}`;
573
+ return {
574
+ text: `Total output lines: ${totalLines}
575
+
576
+ ${truncated}`,
577
+ originalTokenCount
578
+ };
579
+ }
580
+ function formatExecResponse(args) {
581
+ const lines = [
582
+ `Chunk ID: ${randomUUID().replace(/-/g, "").slice(0, 6)}`,
583
+ `Wall time: ${args.wallTimeSeconds.toFixed(4)} seconds`
584
+ ];
585
+ if (typeof args.sessionId === "number") {
586
+ lines.push(`Process running with session ID ${args.sessionId}`);
587
+ } else if (typeof args.exitCode === "number") {
588
+ lines.push(`Process exited with code ${args.exitCode}`);
589
+ }
590
+ if (typeof args.originalTokenCount === "number") {
591
+ lines.push(`Original token count: ${args.originalTokenCount}`);
592
+ }
593
+ lines.push("Output:");
594
+ lines.push(args.output);
595
+ return lines.join("\n");
596
+ }
597
+ function elapsedSeconds(start) {
598
+ return (Date.now() - start) / 1e3;
599
+ }
600
+ function truncateWithByteBudget(output, maxBytes, marker) {
601
+ const leftBudget = Math.floor(maxBytes / 2);
602
+ const rightBudget = maxBytes - leftBudget;
603
+ const totalBytes = byteLength(output);
604
+ const tailStartTarget = Math.max(0, totalBytes - rightBudget);
605
+ let prefixEnd = 0;
606
+ let suffixStart = totalBytes;
607
+ let suffixStarted = false;
608
+ let byteIndex = 0;
609
+ for (const character of output) {
610
+ const characterBytes = byteLength(character);
611
+ const characterEnd = byteIndex + characterBytes;
612
+ if (characterEnd <= leftBudget) {
613
+ prefixEnd = characterEnd;
614
+ byteIndex = characterEnd;
615
+ continue;
616
+ }
617
+ if (byteIndex >= tailStartTarget) {
618
+ if (!suffixStarted) {
619
+ suffixStart = byteIndex;
620
+ suffixStarted = true;
621
+ }
622
+ byteIndex = characterEnd;
623
+ continue;
624
+ }
625
+ byteIndex = characterEnd;
626
+ }
627
+ if (suffixStart < prefixEnd) {
628
+ suffixStart = prefixEnd;
629
+ }
630
+ const bytes = new TextEncoder().encode(output);
631
+ const prefix = new TextDecoder().decode(bytes.slice(0, prefixEnd));
632
+ const suffix = new TextDecoder().decode(bytes.slice(suffixStart));
633
+ return `${prefix}${marker}${suffix}`;
634
+ }
635
+ function getPreservedLeadingNotice(output) {
636
+ const match = output.match(/^\[\.\.\.\d+ characters truncated from process output\.\.\.\]\n/u);
637
+ return match?.[0] ?? "";
638
+ }
639
+ function countLines(output) {
640
+ if (output.length === 0) {
641
+ return 0;
642
+ }
643
+ return output.split(/\r\n|\r|\n/).length;
644
+ }
645
+ function byteLength(output) {
646
+ return new TextEncoder().encode(output).byteLength;
647
+ }
648
+ function approximateTokenCountFromBytes(bytes) {
649
+ if (bytes <= 0) {
650
+ return 0;
651
+ }
652
+ return Math.ceil(bytes / APPROX_BYTES_PER_TOKEN);
653
+ }
654
+
655
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/sandbox/shared/hostPath.mjs
656
+ import { isAbsolute, relative, sep } from "path";
657
+ function relativeHostPathEscapesRoot(relativePath) {
658
+ return relativePath === ".." || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath);
659
+ }
660
+ function relativeHostPathEscapesRootOrSelf(relativePath) {
661
+ return relativePath === "" || relativeHostPathEscapesRoot(relativePath);
662
+ }
663
+ function isHostPathWithinRoot(root, path) {
664
+ return !relativeHostPathEscapesRoot(relative(root, path));
665
+ }
666
+ function isHostPathStrictlyWithinRoot(root, path) {
667
+ return !relativeHostPathEscapesRootOrSelf(relative(root, path));
668
+ }
669
+
670
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/sandbox/shared/credentials.mjs
671
+ function validateCredentialPair({ accessKeyId, secretAccessKey, message, details, code }) {
672
+ if (Boolean(accessKeyId) !== Boolean(secretAccessKey)) {
673
+ throw new SandboxMountError(message, details, code);
674
+ }
675
+ }
676
+
677
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/sandbox/shared/media.mjs
678
+ var MAX_VIEW_IMAGE_BYTES = 10 * 1024 * 1024;
679
+ function assertViewImageByteLength(path, byteLength2) {
680
+ if (byteLength2 > MAX_VIEW_IMAGE_BYTES) {
681
+ throw new UserError(`Image file exceeds the 10 MB limit: ${path}`);
682
+ }
683
+ }
684
+ function imageOutputFromBytes(path, bytes) {
685
+ assertViewImageByteLength(path, bytes.byteLength);
686
+ const mediaType = sniffImageMediaType(bytes, path);
687
+ if (!mediaType) {
688
+ throw new UserError(`Unsupported image format for view_image: ${path}`);
689
+ }
690
+ return {
691
+ type: "image",
692
+ image: {
693
+ data: Uint8Array.from(bytes),
694
+ mediaType
695
+ }
696
+ };
697
+ }
698
+ function sniffImageMediaType(bytes, path) {
699
+ if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
700
+ return "image/png";
701
+ }
702
+ if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
703
+ return "image/jpeg";
704
+ }
705
+ if (bytes[0] === 71 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 56) {
706
+ return "image/gif";
707
+ }
708
+ if (bytes[0] === 82 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 70 && bytes[8] === 87 && bytes[9] === 69 && bytes[10] === 66 && bytes[11] === 80) {
709
+ return "image/webp";
710
+ }
711
+ if (bytes[0] === 66 && bytes[1] === 77) {
712
+ return "image/bmp";
713
+ }
714
+ if (bytes[0] === 73 && bytes[1] === 73 && bytes[2] === 42 && bytes[3] === 0 || bytes[0] === 77 && bytes[1] === 77 && bytes[2] === 0 && bytes[3] === 42) {
715
+ return "image/tiff";
716
+ }
717
+ if (looksLikeSvg(bytes)) {
718
+ return "image/svg+xml";
719
+ }
720
+ return mediaTypeFromPath(path);
721
+ }
722
+ async function toUint8Array(value) {
723
+ if (!value) {
724
+ return new Uint8Array();
725
+ }
726
+ if (value instanceof Uint8Array) {
727
+ return Uint8Array.from(value);
728
+ }
729
+ if (value instanceof ArrayBuffer) {
730
+ return new Uint8Array(value);
731
+ }
732
+ if (ArrayBuffer.isView(value)) {
733
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
734
+ }
735
+ if (typeof value === "string") {
736
+ return new TextEncoder().encode(value);
737
+ }
738
+ if (typeof Blob !== "undefined" && value instanceof Blob) {
739
+ return new Uint8Array(await value.arrayBuffer());
740
+ }
741
+ return Uint8Array.from(value);
742
+ }
743
+ function looksLikeSvg(bytes) {
744
+ const prefix = new TextDecoder().decode(bytes.subarray(0, Math.min(bytes.byteLength, 512))).trimStart().toLowerCase();
745
+ return prefix.startsWith("<svg") || /^<\?xml[\s\S]*<svg/u.test(prefix);
746
+ }
747
+ function mediaTypeFromPath(path) {
748
+ const lowerPath = path?.trim().toLowerCase() ?? "";
749
+ if (lowerPath.endsWith(".png")) {
750
+ return "image/png";
751
+ }
752
+ if (lowerPath.endsWith(".jpg") || lowerPath.endsWith(".jpeg")) {
753
+ return "image/jpeg";
754
+ }
755
+ if (lowerPath.endsWith(".gif")) {
756
+ return "image/gif";
757
+ }
758
+ if (lowerPath.endsWith(".webp")) {
759
+ return "image/webp";
760
+ }
761
+ if (lowerPath.endsWith(".bmp")) {
762
+ return "image/bmp";
763
+ }
764
+ if (lowerPath.endsWith(".tif") || lowerPath.endsWith(".tiff")) {
765
+ return "image/tiff";
766
+ }
767
+ if (lowerPath.endsWith(".svg") || lowerPath.endsWith(".svgz")) {
768
+ return "image/svg+xml";
769
+ }
770
+ return null;
771
+ }
772
+
773
+ // ../../node_modules/.bun/@openai+agents-extensions@0.13.3+d7f081875ac70c34/node_modules/@openai/agents-extensions/dist/sandbox/shared/localSources.mjs
774
+ import { constants } from "fs";
775
+ import { lstat, mkdtemp, open, readFile, readdir, realpath, rm } from "fs/promises";
776
+ import { tmpdir } from "os";
777
+ import { dirname, join, resolve } from "path";
778
+
779
+ // ../../node_modules/.bun/@openai+agents-extensions@0.13.3+d7f081875ac70c34/node_modules/@openai/agents-extensions/dist/sandbox/shared/git.mjs
780
+ function normalizeGitRepository(repositoryOrEntry) {
781
+ const repository = typeof repositoryOrEntry === "string" ? repositoryOrEntry : repositoryOrEntry.repo;
782
+ if (!repository) {
783
+ throw new UserError("git_repo entries require a repo.");
784
+ }
785
+ if (repository.includes("://") || repository.startsWith("git@")) {
786
+ return repository;
787
+ }
788
+ const host = typeof repositoryOrEntry === "string" ? "github.com" : repositoryOrEntry.host ?? "github.com";
789
+ return `https://${host}/${repository}.git`;
790
+ }
791
+
792
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/sandbox/sandboxes/shared/runProcess.mjs
793
+ import { spawn } from "child_process";
794
+ var DEFAULT_MAX_OUTPUT_BYTES = 1024 * 1024;
795
+ var FORCE_KILL_DELAY_MS = 5e3;
796
+ async function runSandboxProcess(command, args, options = {}) {
797
+ return new Promise((resolve2) => {
798
+ const stdoutChunks = [];
799
+ const stderrChunks = [];
800
+ let stdoutBytes = 0;
801
+ let stderrBytes = 0;
802
+ let error;
803
+ let timedOut = false;
804
+ let closed = false;
805
+ let settled = false;
806
+ let timeout;
807
+ let forceKillTimeout;
808
+ const maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
809
+ const child = spawn(command, args, {
810
+ cwd: options.cwd,
811
+ env: options.env,
812
+ stdio: ["ignore", "pipe", "pipe"]
813
+ });
814
+ const captureChunk = (chunks, currentBytes, chunk) => {
815
+ const remainingBytes = maxOutputBytes - currentBytes;
816
+ if (remainingBytes <= 0) {
817
+ return currentBytes;
818
+ }
819
+ const captured = chunk.length > remainingBytes ? chunk.subarray(0, remainingBytes) : chunk;
820
+ chunks.push(captured);
821
+ return currentBytes + captured.length;
822
+ };
823
+ const finish = (status, signal) => {
824
+ if (settled) {
825
+ return;
826
+ }
827
+ settled = true;
828
+ closed = true;
829
+ if (timeout) {
830
+ clearTimeout(timeout);
831
+ }
832
+ if (forceKillTimeout) {
833
+ clearTimeout(forceKillTimeout);
834
+ }
835
+ resolve2({
836
+ status,
837
+ signal,
838
+ stdout: Buffer.concat(stdoutChunks).toString("utf8"),
839
+ stderr: Buffer.concat(stderrChunks).toString("utf8"),
840
+ error,
841
+ timedOut
842
+ });
843
+ };
844
+ child.stdout.on("data", (chunk) => {
845
+ stdoutBytes = captureChunk(stdoutChunks, stdoutBytes, chunk);
846
+ });
847
+ child.stderr.on("data", (chunk) => {
848
+ stderrBytes = captureChunk(stderrChunks, stderrBytes, chunk);
849
+ });
850
+ child.on("error", (childError) => {
851
+ error = childError;
852
+ finish(null, null);
853
+ });
854
+ if (options.timeoutMs !== void 0) {
855
+ timeout = setTimeout(() => {
856
+ timedOut = true;
857
+ child.kill("SIGTERM");
858
+ forceKillTimeout = setTimeout(() => {
859
+ if (!closed) {
860
+ child.kill("SIGKILL");
861
+ }
862
+ }, FORCE_KILL_DELAY_MS);
863
+ }, options.timeoutMs);
864
+ }
865
+ child.on("close", (status, signal) => {
866
+ finish(status, signal);
867
+ });
868
+ });
869
+ }
870
+ function formatSandboxProcessError(result) {
871
+ if (result.timedOut) {
872
+ return "process timed out";
873
+ }
874
+ return result.stderr || result.stdout || result.error?.message || "process failed";
875
+ }
876
+
877
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/sandbox/client.mjs
878
+ var DEFAULT_SANDBOX_ARCHIVE_LIMITS = {
879
+ maxInputBytes: 1024 * 1024 * 1024,
880
+ maxExtractedBytes: 4 * 1024 * 1024 * 1024,
881
+ maxMembers: 1e5
882
+ };
883
+ function normalizeSandboxClientCreateArgs(args, manifestOptions) {
884
+ if (args instanceof Manifest) {
885
+ return {
886
+ manifest: args,
887
+ options: manifestOptions,
888
+ snapshot: readSnapshotOption(manifestOptions),
889
+ concurrencyLimits: readConcurrencyLimitsOption(manifestOptions),
890
+ archiveLimits: readArchiveLimitsOption(manifestOptions)
891
+ };
892
+ }
893
+ const manifest = args?.manifest;
894
+ return {
895
+ manifest: manifest ? manifest instanceof Manifest ? manifest : cloneManifest(manifest) : new Manifest(),
896
+ options: args?.options,
897
+ snapshot: args?.snapshot,
898
+ concurrencyLimits: args?.concurrencyLimits,
899
+ archiveLimits: args?.archiveLimits
900
+ };
901
+ }
902
+ function resolveSandboxArchiveLimits(limits) {
903
+ if (limits == null) {
904
+ return null;
905
+ }
906
+ validateSandboxArchiveLimits(limits);
907
+ return {
908
+ maxInputBytes: limits.maxInputBytes === void 0 ? DEFAULT_SANDBOX_ARCHIVE_LIMITS.maxInputBytes : limits.maxInputBytes,
909
+ maxExtractedBytes: limits.maxExtractedBytes === void 0 ? DEFAULT_SANDBOX_ARCHIVE_LIMITS.maxExtractedBytes : limits.maxExtractedBytes,
910
+ maxMembers: limits.maxMembers === void 0 ? DEFAULT_SANDBOX_ARCHIVE_LIMITS.maxMembers : limits.maxMembers
911
+ };
912
+ }
913
+ function validateSandboxArchiveLimits(limits) {
914
+ if (limits == null) {
915
+ return;
916
+ }
917
+ validatePositiveArchiveLimit("maxInputBytes", limits.maxInputBytes);
918
+ validatePositiveArchiveLimit("maxExtractedBytes", limits.maxExtractedBytes);
919
+ validatePositiveArchiveLimit("maxMembers", limits.maxMembers);
920
+ }
921
+ function validatePositiveArchiveLimit(name, value) {
922
+ if (value == null) {
923
+ return;
924
+ }
925
+ if (!Number.isSafeInteger(value) || value < 1) {
926
+ throw new UserError(`archiveLimits.${name} must be at least 1.`);
927
+ }
928
+ }
929
+ function readSnapshotOption(options) {
930
+ if (!isRecord(options)) {
931
+ return void 0;
932
+ }
933
+ return options.snapshot;
934
+ }
935
+ function readConcurrencyLimitsOption(options) {
936
+ if (!isRecord(options)) {
937
+ return void 0;
938
+ }
939
+ return options.concurrencyLimits;
940
+ }
941
+ function readArchiveLimitsOption(options) {
942
+ if (!isRecord(options)) {
943
+ return void 0;
944
+ }
945
+ return options.archiveLimits;
946
+ }
947
+
948
+ // ../../node_modules/.bun/@openai+agents-core@0.13.3+bd37e07cd49ea605/node_modules/@openai/agents-core/dist/sandbox/snapshot.mjs
949
+ function isNoopSnapshotSpec(spec) {
950
+ return spec?.type === "noop";
951
+ }
952
+
953
+ // ../../node_modules/.bun/@openai+agents-extensions@0.13.3+d7f081875ac70c34/node_modules/@openai/agents-extensions/dist/sandbox/shared/paths.mjs
954
+ var RESOLVE_WORKSPACE_PATH_HELPER = String.raw`#!/bin/sh
955
+ set -eu
956
+
957
+ root="$1"
958
+ candidate="$2"
959
+ for_write="$3"
960
+ shift 3
961
+ max_symlink_depth=64
962
+
963
+ case "$for_write" in
964
+ 0|1) ;;
965
+ *) printf 'for_write must be 0 or 1: %s\n' "$for_write" >&2; exit 64 ;;
966
+ esac
967
+
968
+ if [ $(( $# % 2 )) -ne 0 ]; then
969
+ printf 'extra path grants must be root/read_only pairs\n' >&2
970
+ exit 64
971
+ fi
972
+
973
+ resolve_path() {
974
+ path="$1"
975
+ depth="$2"
976
+ seen=""
977
+ if [ "$#" -ge 3 ]; then
978
+ seen="$3"
979
+ fi
980
+ if [ "$path" = "/" ]; then
981
+ printf '/\n'
982
+ return 0
983
+ fi
984
+ if [ "$depth" -ge "$max_symlink_depth" ]; then
985
+ printf 'symlink resolution depth exceeded: %s\n' "$path" >&2
986
+ exit 112
987
+ fi
988
+ if [ -d "$path" ]; then
989
+ (cd "$path" && pwd -P)
990
+ return 0
991
+ fi
992
+ parent=$(dirname "$path")
993
+ base=$(basename "$path")
994
+ if [ -z "$parent" ] || [ "$parent" = "$path" ]; then
995
+ parent="/"
996
+ fi
997
+ resolved_parent=$(resolve_path "$parent" "$depth" "$seen")
998
+ candidate_path=$(join_child_path "$resolved_parent" "$base")
999
+ if [ -L "$candidate_path" ]; then
1000
+ case ":$seen:" in
1001
+ *":$candidate_path:"*)
1002
+ printf 'symlink resolution depth exceeded: %s\n' "$candidate_path" >&2
1003
+ exit 112
1004
+ ;;
1005
+ esac
1006
+ target=$(readlink "$candidate_path")
1007
+ next_depth=$((depth + 1))
1008
+ next_seen="$seen:$candidate_path"
1009
+ case "$target" in
1010
+ /*) resolve_path "$target" "$next_depth" "$next_seen" ;;
1011
+ *)
1012
+ relative_target=$(join_child_path "$resolved_parent" "$target")
1013
+ resolve_path "$relative_target" "$next_depth" "$next_seen"
1014
+ ;;
1015
+ esac
1016
+ return 0
1017
+ fi
1018
+ printf '%s\n' "$candidate_path"
1019
+ }
1020
+
1021
+ join_child_path() {
1022
+ parent="$1"
1023
+ child="$2"
1024
+ if [ "$parent" = "/" ]; then
1025
+ printf '/%s\n' "$child"
1026
+ else
1027
+ printf '%s/%s\n' "$parent" "$child"
1028
+ fi
1029
+ }
1030
+
1031
+ resolved_candidate=$(resolve_path "$candidate" 0)
1032
+ best_grant_root=""
1033
+ best_grant_original=""
1034
+ best_grant_read_only="0"
1035
+ best_grant_len=0
1036
+
1037
+ check_workspace_root() {
1038
+ resolved_root=$(resolve_path "$root" 0)
1039
+ if [ "$resolved_root" = "/" ]; then
1040
+ case "$resolved_candidate" in
1041
+ /*)
1042
+ printf '%s\n' "$resolved_candidate"
1043
+ exit 0
1044
+ ;;
1045
+ esac
1046
+ fi
1047
+ case "$resolved_candidate" in
1048
+ "$resolved_root"|"$resolved_root"/*)
1049
+ printf '%s\n' "$resolved_candidate"
1050
+ exit 0
1051
+ ;;
1052
+ esac
1053
+ }
1054
+
1055
+ consider_extra_grant() {
1056
+ allowed_root="$1"
1057
+ read_only="$2"
1058
+ case "$read_only" in
1059
+ 0|1) ;;
1060
+ *) printf 'extra path grant read_only must be 0 or 1: %s\n' "$read_only" >&2; exit 64 ;;
1061
+ esac
1062
+ resolved_root=$(resolve_path "$allowed_root" 0)
1063
+ if [ "$resolved_root" = "/" ]; then
1064
+ printf 'extra path grant must not resolve to filesystem root: %s\n' "$allowed_root" >&2
1065
+ exit 113
1066
+ fi
1067
+ case "$resolved_candidate" in
1068
+ "$resolved_root"|"$resolved_root"/*)
1069
+ root_len=$(printf '%s' "$resolved_root" | wc -c | tr -d ' ')
1070
+ if [ "$root_len" -gt "$best_grant_len" ]; then
1071
+ best_grant_root="$resolved_root"
1072
+ best_grant_original="$allowed_root"
1073
+ best_grant_read_only="$read_only"
1074
+ best_grant_len="$root_len"
1075
+ fi
1076
+ ;;
1077
+ esac
1078
+ }
1079
+
1080
+ while [ "$#" -gt 0 ]; do
1081
+ consider_extra_grant "$1" "$2"
1082
+ shift 2
1083
+ done
1084
+
1085
+ check_workspace_root
1086
+ if [ -n "$best_grant_root" ]; then
1087
+ if [ "$for_write" = "1" ] && [ "$best_grant_read_only" = "1" ]; then
1088
+ printf 'read-only extra path grant: %s\nresolved path: %s\n' "$best_grant_original" "$resolved_candidate" >&2
1089
+ exit 114
1090
+ fi
1091
+ printf '%s\n' "$resolved_candidate"
1092
+ exit 0
1093
+ fi
1094
+
1095
+ printf 'workspace escape: %s\n' "$resolved_candidate" >&2
1096
+ exit 111`;
1097
+ function createRemotePathHelperId() {
1098
+ const crypto = globalThis.crypto;
1099
+ if (typeof crypto?.randomUUID === "function") {
1100
+ return crypto.randomUUID();
1101
+ }
1102
+ if (typeof crypto?.getRandomValues === "function") {
1103
+ return Array.from(crypto.getRandomValues(new Uint32Array(4)), (value) => value.toString(36)).join("-");
1104
+ }
1105
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
1106
+ }
1107
+ function resolveSandboxAbsolutePath(root, path, options = {}) {
1108
+ return new WorkspacePathPolicy({
1109
+ root,
1110
+ extraPathGrants: options.extraPathGrants
1111
+ }).resolve(path, { forWrite: options.forWrite }).path;
1112
+ }
1113
+ async function validateRemoteSandboxPath({ root, path, options = {}, runCommand }) {
1114
+ const candidate = resolveSandboxAbsolutePath(root, path, options);
1115
+ const helperDir = `/tmp/openai-agents-resolve-path-${createRemotePathHelperId()}`;
1116
+ const helperArgs = [
1117
+ root,
1118
+ candidate,
1119
+ options.forWrite ? "1" : "0",
1120
+ ...(options.extraPathGrants ?? []).flatMap((grant) => [
1121
+ grant.path,
1122
+ grant.readOnly ? "1" : "0"
1123
+ ])
1124
+ ];
1125
+ const command = [
1126
+ `helper_dir=${shellQuote(helperDir)}`,
1127
+ 'helper_path="$helper_dir/resolve-workspace-path.sh"',
1128
+ 'cleanup() { rm -rf "$helper_dir"; }',
1129
+ "trap cleanup EXIT HUP INT TERM",
1130
+ "umask 077",
1131
+ 'mkdir "$helper_dir" || exit 125',
1132
+ `cat > "$helper_path" <<'OPENAI_AGENTS_RESOLVE_PATH'`,
1133
+ RESOLVE_WORKSPACE_PATH_HELPER,
1134
+ "OPENAI_AGENTS_RESOLVE_PATH",
1135
+ `sh "$helper_path" ${helperArgs.map(shellQuote).join(" ")}`
1136
+ ].join("\n");
1137
+ const result = await runCommand(command);
1138
+ if (result.status !== 0) {
1139
+ const message = (result.stderr || result.stdout || "remote validation failed").trim().split(/\r?\n/u).join("; ");
1140
+ throw new SandboxPathResolutionError(`Sandbox path "${path ?? ""}" failed remote validation: ${message}`, {
1141
+ root,
1142
+ path: path ?? "",
1143
+ forWrite: options.forWrite ?? false
1144
+ });
1145
+ }
1146
+ const resolvedPath = result.stdout?.trim().split(/\r?\n/u).pop();
1147
+ if (!resolvedPath?.startsWith("/")) {
1148
+ throw new SandboxPathResolutionError(`Sandbox path "${path ?? ""}" failed remote validation: validator did not return an absolute resolved path.`, {
1149
+ root,
1150
+ path: path ?? "",
1151
+ forWrite: options.forWrite ?? false
1152
+ });
1153
+ }
1154
+ return resolvedPath;
1155
+ }
1156
+ async function validateRemoteSandboxPathForManifest({ manifest, path, options = {}, runCommand }) {
1157
+ return await validateRemoteSandboxPath({
1158
+ root: manifest.root,
1159
+ path,
1160
+ options: {
1161
+ ...options,
1162
+ extraPathGrants: manifest.extraPathGrants
1163
+ },
1164
+ runCommand
1165
+ });
1166
+ }
1167
+ function resolveSandboxRelativePath(root, path) {
1168
+ const resolved = new WorkspacePathPolicy({
1169
+ root
1170
+ }).resolve(path, { forWrite: true });
1171
+ if (typeof resolved.workspaceRelativePath !== "string") {
1172
+ throw new UserError(`Sandbox path "${path ?? ""}" escapes the workspace root.`);
1173
+ }
1174
+ return normalizeRelativePath(resolved.workspaceRelativePath);
1175
+ }
1176
+ function resolveSandboxWorkdir(root, path) {
1177
+ return resolveSandboxAbsolutePath(root, path);
1178
+ }
1179
+
1180
+ // ../../node_modules/.bun/@openai+agents-extensions@0.13.3+d7f081875ac70c34/node_modules/@openai/agents-extensions/dist/sandbox/shared/manifest.mjs
1181
+ function cloneManifestWithRoot(manifest, root) {
1182
+ return cloneManifestWithOverrides(manifest, {
1183
+ root,
1184
+ entries: rebaseManifestEntryPathsForRoot(manifest.entries, manifest.root, root)
1185
+ });
1186
+ }
1187
+ function cloneManifestWithoutMountEntries(manifest) {
1188
+ return cloneManifestWithOverrides(manifest, {
1189
+ entries: removeMountEntries(manifest.entries)
1190
+ });
1191
+ }
1192
+ function manifestContainsLocalSource(manifest) {
1193
+ for (const { entry } of manifest.iterEntries()) {
1194
+ if (isLocalSourceEntry(entry)) {
1195
+ return true;
1196
+ }
1197
+ }
1198
+ return false;
1199
+ }
1200
+ function entryContainsLocalSource(entry) {
1201
+ if (isLocalSourceEntry(entry)) {
1202
+ return true;
1203
+ }
1204
+ if (entry.type !== "dir" || !entry.children) {
1205
+ return false;
1206
+ }
1207
+ return Object.values(entry.children).some((childEntry) => entryContainsLocalSource(childEntry));
1208
+ }
1209
+ function isLocalSourceEntry(entry) {
1210
+ return entry.type === "local_file" || entry.type === "local_dir" || entry.type === "git_repo";
1211
+ }
1212
+ function cloneManifestWithOverrides(manifest, overrides = {}) {
1213
+ return new Manifest({
1214
+ version: manifest.version,
1215
+ root: overrides.root ?? manifest.root,
1216
+ entries: structuredClone(overrides.entries ?? manifest.entries),
1217
+ environment: Object.fromEntries(Object.entries(manifest.environment).map(([key, value]) => [
1218
+ key,
1219
+ value.init()
1220
+ ])),
1221
+ users: structuredClone(manifest.users),
1222
+ groups: structuredClone(manifest.groups),
1223
+ extraPathGrants: structuredClone(manifest.extraPathGrants),
1224
+ remoteMountCommandAllowlist: [...manifest.remoteMountCommandAllowlist]
1225
+ });
1226
+ }
1227
+ function rebaseManifestEntryPathsForRoot(entries, fromRoot, toRoot) {
1228
+ return Object.fromEntries(Object.entries(entries).map(([path, entry]) => [
1229
+ path,
1230
+ rebaseManifestEntryForRoot(entry, fromRoot, toRoot)
1231
+ ]));
1232
+ }
1233
+ function rebaseManifestEntryForRoot(entry, fromRoot, toRoot) {
1234
+ const cloned = structuredClone(entry);
1235
+ if (isMount(cloned) && cloned.mountPath?.startsWith("/")) {
1236
+ cloned.mountPath = rebaseAbsolutePathWithinRoot(cloned.mountPath, fromRoot, toRoot);
1237
+ }
1238
+ if (cloned.type === "dir" && cloned.children) {
1239
+ cloned.children = rebaseManifestEntryPathsForRoot(cloned.children, fromRoot, toRoot);
1240
+ }
1241
+ return cloned;
1242
+ }
1243
+ function rebaseAbsolutePathWithinRoot(path, fromRoot, toRoot) {
1244
+ const relativePath = relativePosixPathWithinRoot(normalizePosixPath(fromRoot), normalizePosixPath(path));
1245
+ if (relativePath === null) {
1246
+ return path;
1247
+ }
1248
+ if (!relativePath) {
1249
+ return normalizePosixPath(toRoot);
1250
+ }
1251
+ const normalizedToRoot = normalizePosixPath(toRoot);
1252
+ if (normalizedToRoot === "/") {
1253
+ return `/${relativePath}`;
1254
+ }
1255
+ return `${normalizedToRoot}/${relativePath}`;
1256
+ }
1257
+ async function applyInlineManifestEntryToState(state, path, entry, providerLabel, writer, resolvePath, options = {}) {
1258
+ await applyMaterializedManifestEntryToState(state, path, entry, providerLabel, writer, resolvePath, materializeInlineManifestEntry, options);
1259
+ }
1260
+ async function applyInlineManifestToState(state, manifest, providerLabel, writer, resolvePath, options = {}) {
1261
+ await applyMaterializedManifestToState(state, manifest, providerLabel, writer, resolvePath, materializeInlineManifestEntry, options);
1262
+ }
1263
+ async function applyMaterializedManifestEntryToState(state, path, entry, providerLabel, writer, resolvePath, materializeEntry, options) {
1264
+ const logicalPath = resolveSandboxRelativePath(state.manifest.root, path);
1265
+ await materializeManifestEntries(writer, new Manifest({
1266
+ root: state.manifest.root,
1267
+ entries: {
1268
+ [logicalPath]: entry
1269
+ }
1270
+ }), providerLabel, resolvePath, materializeEntry, options);
1271
+ state.manifest = mergeManifestEntryDelta(state.manifest, logicalPath, entry);
1272
+ }
1273
+ async function applyMaterializedManifestToState(state, manifest, providerLabel, writer, resolvePath, materializeEntry, options) {
1274
+ const previousManifest = state.manifest;
1275
+ await materializeManifestEntries(writer, manifest, providerLabel, resolvePath, materializeEntry, options);
1276
+ state.manifest = mergeManifestDelta(previousManifest, manifest);
1277
+ state.environment = await mergeMaterializedEnvironment(previousManifest, state.manifest, state.environment);
1278
+ }
1279
+ async function materializeManifestEntries(writer, manifest, providerLabel, resolvePath, materializeEntry, options) {
1280
+ const deferredOptions = {
1281
+ ...options,
1282
+ skipMountEntries: true
1283
+ };
1284
+ const entries = Object.entries(manifest.entries).filter(([, entry]) => !isMount(entry));
1285
+ await runLimited(entries, resolveManifestEntryConcurrency(options.concurrencyLimits), async ([path, entry]) => {
1286
+ const logicalPath = normalizeRelativePath(path);
1287
+ const absolutePath = await resolvePath(logicalPath, { forWrite: true });
1288
+ const entryOptions = {
1289
+ ...deferredOptions,
1290
+ resolvePath,
1291
+ logicalPath
1292
+ };
1293
+ await materializeEntry(writer, absolutePath, entry, providerLabel, entryOptions);
1294
+ });
1295
+ for (const { mountPath, entry } of manifest.mountTargetsForMaterialization()) {
1296
+ const logicalPath = resolveSandboxRelativePath(manifest.root, mountPath);
1297
+ const absolutePath = await resolvePath(logicalPath, { forWrite: true });
1298
+ await materializeEntry(writer, absolutePath, entry, providerLabel, options);
1299
+ }
1300
+ }
1301
+ async function runLimited(items, limit, fn) {
1302
+ if (items.length === 0) {
1303
+ return;
1304
+ }
1305
+ let nextIndex = 0;
1306
+ const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
1307
+ while (nextIndex < items.length) {
1308
+ const item = items[nextIndex++];
1309
+ await fn(item);
1310
+ }
1311
+ });
1312
+ await Promise.all(workers);
1313
+ }
1314
+ function resolveManifestEntryConcurrency(limits) {
1315
+ return normalizeConcurrencyLimit(limits?.manifestEntries, 4);
1316
+ }
1317
+ function resolveLocalDirFileConcurrency(limits) {
1318
+ return normalizeConcurrencyLimit(limits?.localDirFiles, 4);
1319
+ }
1320
+ function normalizeConcurrencyLimit(value, fallback) {
1321
+ if (value === void 0) {
1322
+ return fallback;
1323
+ }
1324
+ if (!Number.isFinite(value) || value < 1) {
1325
+ throw new UserError("Sandbox concurrency limits must be positive numbers.");
1326
+ }
1327
+ return Math.floor(value);
1328
+ }
1329
+ async function materializeInlineManifestEntry(writer, absolutePath, entry, providerLabel, options = {}) {
1330
+ if (isMount(entry)) {
1331
+ if (options.skipMountEntries) {
1332
+ return;
1333
+ }
1334
+ if (options.materializeMount) {
1335
+ await options.materializeMount(absolutePath, entry);
1336
+ return;
1337
+ }
1338
+ throw new SandboxUnsupportedFeatureError(`${providerLabel} does not support mount entries yet: ${absolutePath}`);
1339
+ }
1340
+ switch (entry.type) {
1341
+ case "dir":
1342
+ await writer.mkdir(absolutePath);
1343
+ if (entry.children) {
1344
+ for (const [childPath, childEntry] of Object.entries(entry.children)) {
1345
+ const child = await resolveMaterializedChildPath(absolutePath, childPath, options);
1346
+ await materializeInlineManifestEntry(writer, child.absolutePath, childEntry, providerLabel, {
1347
+ ...options,
1348
+ logicalPath: child.logicalPath
1349
+ });
1350
+ }
1351
+ }
1352
+ break;
1353
+ case "file":
1354
+ await writer.writeFile(absolutePath, entry.content);
1355
+ break;
1356
+ case "local_file":
1357
+ case "local_dir":
1358
+ case "git_repo":
1359
+ throw new UserError(`${providerLabel} cannot materialize ${entry.type} entries in this runtime. Use inline file or dir entries, or materialize local sources from a Node-compatible runtime.`);
1360
+ default:
1361
+ throw new UserError(`Unsupported sandbox entry type: ${entry.type}`);
1362
+ }
1363
+ await options.applyMetadata?.(absolutePath, entry);
1364
+ }
1365
+ async function resolveMaterializedChildPath(parentAbsolutePath, childPath, options) {
1366
+ const normalizedChildPath = normalizeRelativePath(childPath);
1367
+ const logicalPath = options.logicalPath !== void 0 ? options.logicalPath ? `${options.logicalPath}/${normalizedChildPath}` : normalizedChildPath : void 0;
1368
+ if (options.resolvePath && logicalPath !== void 0) {
1369
+ return {
1370
+ absolutePath: await options.resolvePath(logicalPath, { forWrite: true }),
1371
+ logicalPath
1372
+ };
1373
+ }
1374
+ return {
1375
+ absolutePath: `${parentAbsolutePath}/${normalizedChildPath}`,
1376
+ logicalPath
1377
+ };
1378
+ }
1379
+ function removeMountEntries(entries) {
1380
+ const result = {};
1381
+ for (const [path, entry] of Object.entries(entries)) {
1382
+ if (isMount(entry)) {
1383
+ continue;
1384
+ }
1385
+ if (entry.type === "dir" && entry.children) {
1386
+ result[path] = {
1387
+ ...structuredClone(entry),
1388
+ children: removeMountEntries(entry.children)
1389
+ };
1390
+ continue;
1391
+ }
1392
+ result[path] = structuredClone(entry);
1393
+ }
1394
+ return result;
1395
+ }
1396
+
1397
+ // ../../node_modules/.bun/@openai+agents-extensions@0.13.3+d7f081875ac70c34/node_modules/@openai/agents-extensions/dist/sandbox/shared/localSources.mjs
1398
+ var GIT_VERSION_TIMEOUT_MS = 1e4;
1399
+ var GIT_CLONE_TIMEOUT_MS = 5 * 6e4;
1400
+ var COMMIT_REF_PATTERN = /^[0-9a-fA-F]{7,40}$/;
1401
+ var LOCAL_SOURCE_FILE_READ_FLAGS = constants.O_RDONLY | constants.O_NOFOLLOW;
1402
+ var LOCAL_SOURCE_DIRECTORY_READ_FLAGS = constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_DIRECTORY;
1403
+ async function applyLocalSourceManifestEntryToState(state, path, entry, providerLabel, writer, resolvePath, options = {}) {
1404
+ await applyMaterializedManifestEntryToState(state, path, entry, providerLabel, writer, resolvePath, materializeLocalSourceManifestEntry, {
1405
+ ...options,
1406
+ localSourceGrants: state.manifest.extraPathGrants
1407
+ });
1408
+ }
1409
+ async function applyLocalSourceManifestToState(state, manifest, providerLabel, writer, resolvePath, options = {}) {
1410
+ const sourceManifest = mergeManifestDelta(state.manifest, manifest);
1411
+ await applyMaterializedManifestToState(state, manifest, providerLabel, writer, resolvePath, materializeLocalSourceManifestEntry, {
1412
+ ...options,
1413
+ localSourceGrants: sourceManifest.extraPathGrants
1414
+ });
1415
+ }
1416
+ async function materializeLocalSourceManifest(writer, manifest, providerLabel, resolvePath, options = {}) {
1417
+ await materializeManifestEntries(writer, manifest, providerLabel, resolvePath, materializeLocalSourceManifestEntry, {
1418
+ ...options,
1419
+ localSourceGrants: manifest.extraPathGrants
1420
+ });
1421
+ }
1422
+ async function materializeLocalSourceManifestEntry(writer, absolutePath, entry, providerLabel, options = {}) {
1423
+ switch (entry.type) {
1424
+ case "dir":
1425
+ await writer.mkdir(absolutePath);
1426
+ if (entry.children) {
1427
+ for (const [childPath, childEntry] of Object.entries(entry.children)) {
1428
+ const child = await resolveMaterializedChildPath(absolutePath, childPath, options);
1429
+ await materializeLocalSourceManifestEntry(writer, child.absolutePath, childEntry, providerLabel, {
1430
+ ...options,
1431
+ logicalPath: child.logicalPath
1432
+ });
1433
+ }
1434
+ }
1435
+ break;
1436
+ case "local_file":
1437
+ await writer.writeFile(absolutePath, await readStableLocalFile(resolveLocalSourcePath("local_file", entry.src, options)));
1438
+ break;
1439
+ case "local_dir":
1440
+ await materializeLocalDirectory(writer, absolutePath, resolveLocalSourcePath("local_dir", entry.src, options), options);
1441
+ break;
1442
+ case "git_repo":
1443
+ await materializeGitRepo(writer, absolutePath, entry, entry.ref, providerLabel, options);
1444
+ break;
1445
+ default:
1446
+ await materializeInlineManifestEntry(writer, absolutePath, entry, providerLabel, options);
1447
+ return;
1448
+ }
1449
+ await options.applyMetadata?.(absolutePath, entry);
1450
+ }
1451
+ function resolveLocalSourcePath(entryType, sourcePath, options) {
1452
+ const base = resolve(options.localSourceBaseDir ?? process.cwd());
1453
+ const resolvedSourcePath = resolve(base, sourcePath);
1454
+ if (isHostPathWithinRoot(base, resolvedSourcePath) || (options.localSourceGrants ?? []).some((grant) => isHostPathWithinRoot(resolve(grant.path), resolvedSourcePath))) {
1455
+ return resolvedSourcePath;
1456
+ }
1457
+ throw new UserError(`${entryType} source must stay within the local source base directory or manifest.extraPathGrants: ${resolvedSourcePath} (base: ${base})`);
1458
+ }
1459
+ async function materializeLocalDirectory(writer, absolutePath, sourceDir, options, expectedSourceStat) {
1460
+ const source = await resolveStableLocalDirectorySource(sourceDir, expectedSourceStat);
1461
+ await writer.mkdir(absolutePath);
1462
+ const entries = await readStableLocalDirectoryEntries(sourceDir, source.stat);
1463
+ await runLimited(entries, resolveLocalDirFileConcurrency(options.concurrencyLimits), async (entry) => {
1464
+ const sourcePath = join(sourceDir, entry.name);
1465
+ const destinationPath = `${absolutePath}/${entry.name}`;
1466
+ if (entry.isDirectory()) {
1467
+ const childSourceStat = await assertStableLocalDirectoryChild(source.root, sourcePath);
1468
+ await materializeLocalDirectory(writer, destinationPath, sourcePath, options, childSourceStat);
1469
+ return;
1470
+ }
1471
+ if (entry.isFile()) {
1472
+ await writer.writeFile(destinationPath, await readStableLocalDirectoryFile(source.root, sourcePath));
1473
+ return;
1474
+ }
1475
+ if (entry.isSymbolicLink()) {
1476
+ throw new UserError(`local_dir entries do not support symbolic links: ${sourcePath}`);
1477
+ }
1478
+ });
1479
+ }
1480
+ async function resolveStableLocalDirectorySource(sourceDir, expectedSourceStat) {
1481
+ await assertNoLocalSourceSymlinkAncestors(sourceDir, "local_dir", localDirectoryPathChangedError);
1482
+ const sourceStat = await statStableLocalSourcePath(sourceDir);
1483
+ if (sourceStat.isSymbolicLink()) {
1484
+ throw new UserError(`local_dir entries do not support symbolic links: ${sourceDir}`);
1485
+ }
1486
+ if (!sourceStat.isDirectory()) {
1487
+ throw new UserError(`local_dir source must be a directory: ${sourceDir}`);
1488
+ }
1489
+ if (expectedSourceStat && !sameFilesystemEntry(sourceStat, expectedSourceStat)) {
1490
+ throw localDirectoryPathChangedError(sourceDir);
1491
+ }
1492
+ const sourceRoot = await realpathStableLocalSourcePath(sourceDir);
1493
+ let handle;
1494
+ try {
1495
+ handle = await open(sourceDir, LOCAL_SOURCE_DIRECTORY_READ_FLAGS);
1496
+ } catch (error) {
1497
+ if (isPathChangedError(error)) {
1498
+ throw localDirectoryPathChangedError(sourceDir);
1499
+ }
1500
+ throw error;
1501
+ }
1502
+ try {
1503
+ const openedStat = await handle.stat();
1504
+ if (!openedStat.isDirectory() || !sameFilesystemEntry(openedStat, sourceStat)) {
1505
+ throw localDirectoryPathChangedError(sourceDir);
1506
+ }
1507
+ return { root: sourceRoot, stat: openedStat };
1508
+ } finally {
1509
+ await handle.close();
1510
+ }
1511
+ }
1512
+ async function readStableLocalDirectoryEntries(sourceDir, expectedStat) {
1513
+ let entries;
1514
+ try {
1515
+ entries = await readdir(sourceDir, { withFileTypes: true });
1516
+ } catch (error) {
1517
+ if (isPathChangedError(error)) {
1518
+ throw localDirectoryPathChangedError(sourceDir);
1519
+ }
1520
+ throw error;
1521
+ }
1522
+ await assertStableLocalDirectoryPath(sourceDir, expectedStat);
1523
+ return entries;
1524
+ }
1525
+ async function assertStableLocalDirectoryPath(sourcePath, expectedStat) {
1526
+ const currentStat = await statStableLocalSourcePath(sourcePath);
1527
+ if (currentStat.isSymbolicLink() || !currentStat.isDirectory() || !sameFilesystemEntry(currentStat, expectedStat)) {
1528
+ throw localDirectoryPathChangedError(sourcePath);
1529
+ }
1530
+ }
1531
+ async function readStableLocalFile(sourcePath) {
1532
+ await assertNoLocalSourceSymlinkAncestors(sourcePath, "local_file", localFilePathChangedError);
1533
+ const sourceStat = await statStableLocalSourcePath(sourcePath, localFilePathChangedError);
1534
+ if (sourceStat.isSymbolicLink()) {
1535
+ throw new UserError(`local_file entries do not support symbolic links: ${sourcePath}`);
1536
+ }
1537
+ if (!sourceStat.isFile()) {
1538
+ throw localFilePathChangedError(sourcePath);
1539
+ }
1540
+ let handle;
1541
+ try {
1542
+ handle = await open(sourcePath, LOCAL_SOURCE_FILE_READ_FLAGS);
1543
+ } catch (error) {
1544
+ if (isPathChangedError(error)) {
1545
+ throw localFilePathChangedError(sourcePath);
1546
+ }
1547
+ throw error;
1548
+ }
1549
+ try {
1550
+ const openedStat = await handle.stat();
1551
+ if (!openedStat.isFile() || !sameFilesystemEntry(openedStat, sourceStat)) {
1552
+ throw localFilePathChangedError(sourcePath);
1553
+ }
1554
+ return await handle.readFile();
1555
+ } finally {
1556
+ await handle.close();
1557
+ }
1558
+ }
1559
+ async function assertNoLocalSourceSymlinkAncestors(sourcePath, entryType, pathChangedError) {
1560
+ const resolvedPath = resolve(sourcePath);
1561
+ let current = dirname(resolvedPath);
1562
+ while (current !== dirname(current)) {
1563
+ const parent = dirname(current);
1564
+ if (parent === dirname(parent)) {
1565
+ break;
1566
+ }
1567
+ let currentStat;
1568
+ try {
1569
+ currentStat = await lstat(current);
1570
+ } catch (error) {
1571
+ if (isPathChangedError(error)) {
1572
+ throw pathChangedError(sourcePath);
1573
+ }
1574
+ throw error;
1575
+ }
1576
+ if (currentStat.isSymbolicLink()) {
1577
+ throw new UserError(`${entryType} entries do not support symbolic link ancestors: ${sourcePath}`);
1578
+ }
1579
+ current = parent;
1580
+ }
1581
+ }
1582
+ async function readStableLocalDirectoryFile(sourceRoot, sourcePath) {
1583
+ const sourceStat = await statStableLocalSourcePath(sourcePath);
1584
+ if (sourceStat.isSymbolicLink()) {
1585
+ throw new UserError(`local_dir entries do not support symbolic links: ${sourcePath}`);
1586
+ }
1587
+ if (!sourceStat.isFile()) {
1588
+ throw localDirectoryPathChangedError(sourcePath);
1589
+ }
1590
+ const resolvedSourcePath = await realpathStableLocalSourcePath(sourcePath);
1591
+ assertPathInsideRootChild(sourceRoot, resolvedSourcePath, `local_dir entry path changed while materializing: ${sourcePath}`);
1592
+ let handle;
1593
+ try {
1594
+ handle = await open(sourcePath, LOCAL_SOURCE_FILE_READ_FLAGS);
1595
+ } catch (error) {
1596
+ if (isPathChangedError(error)) {
1597
+ throw localDirectoryPathChangedError(sourcePath);
1598
+ }
1599
+ throw error;
1600
+ }
1601
+ try {
1602
+ const openedStat = await handle.stat();
1603
+ if (!openedStat.isFile() || !sameFilesystemEntry(openedStat, sourceStat)) {
1604
+ throw localDirectoryPathChangedError(sourcePath);
1605
+ }
1606
+ return await handle.readFile();
1607
+ } finally {
1608
+ await handle.close();
1609
+ }
1610
+ }
1611
+ async function assertStableLocalDirectoryChild(sourceRoot, sourcePath) {
1612
+ const sourceStat = await statStableLocalSourcePath(sourcePath);
1613
+ if (sourceStat.isSymbolicLink()) {
1614
+ throw new UserError(`local_dir entries do not support symbolic links: ${sourcePath}`);
1615
+ }
1616
+ if (!sourceStat.isDirectory()) {
1617
+ throw localDirectoryPathChangedError(sourcePath);
1618
+ }
1619
+ const resolvedSourcePath = await realpathStableLocalSourcePath(sourcePath);
1620
+ assertPathInsideRootChild(sourceRoot, resolvedSourcePath, `local_dir entry path changed while materializing: ${sourcePath}`);
1621
+ return sourceStat;
1622
+ }
1623
+ async function statStableLocalSourcePath(sourcePath, pathChangedError = localDirectoryPathChangedError) {
1624
+ try {
1625
+ return await lstat(sourcePath);
1626
+ } catch (error) {
1627
+ if (isPathChangedError(error)) {
1628
+ throw pathChangedError(sourcePath);
1629
+ }
1630
+ throw error;
1631
+ }
1632
+ }
1633
+ async function realpathStableLocalSourcePath(sourcePath, pathChangedError = localDirectoryPathChangedError) {
1634
+ try {
1635
+ return await realpath(sourcePath);
1636
+ } catch (error) {
1637
+ if (isPathChangedError(error)) {
1638
+ throw pathChangedError(sourcePath);
1639
+ }
1640
+ throw error;
1641
+ }
1642
+ }
1643
+ function localDirectoryPathChangedError(sourcePath) {
1644
+ return new UserError(`local_dir entry path changed while materializing: ${sourcePath}`);
1645
+ }
1646
+ function localFilePathChangedError(sourcePath) {
1647
+ return new UserError(`local_file entry path changed while materializing: ${sourcePath}`);
1648
+ }
1649
+ function isPathChangedError(error) {
1650
+ return typeof error === "object" && error !== null && "code" in error && (error.code === "ELOOP" || error.code === "ENOENT" || error.code === "ENOTDIR");
1651
+ }
1652
+ function sameFilesystemEntry(left, right) {
1653
+ return left.dev === right.dev && left.ino === right.ino;
1654
+ }
1655
+ function assertPathInsideRootChild(sourceRoot, resolvedSourcePath, errorMessage) {
1656
+ if (!isHostPathStrictlyWithinRoot(sourceRoot, resolvedSourcePath)) {
1657
+ throw new UserError(errorMessage);
1658
+ }
1659
+ }
1660
+ async function materializeGitRepo(writer, absolutePath, repository, ref, providerLabel, options) {
1661
+ const gitVersion = await runSandboxProcess("git", ["--version"], {
1662
+ timeoutMs: GIT_VERSION_TIMEOUT_MS
1663
+ });
1664
+ if (gitVersion.status !== 0) {
1665
+ throw new UserError("git_repo entries require a local `git` executable, but `git` was not found.");
1666
+ }
1667
+ const tempDir = await mkdtemp(join(tmpdir(), `openai-agents-${providerLabel}-git-`));
1668
+ try {
1669
+ const repositoryUrl = normalizeGitRepository(repository);
1670
+ const { result: cloneResult, commitFetchError } = await cloneGitRepo(repositoryUrl, tempDir, ref);
1671
+ if (cloneResult.status !== 0) {
1672
+ throw new UserError(`Failed to materialize git_repo entry ${formatGitRepositoryForError(repository)}: ${formatSandboxProcessError(commitFetchError ?? cloneResult)}`);
1673
+ }
1674
+ const subpath = typeof repository === "string" ? void 0 : repository.subpath;
1675
+ const sourcePath = subpath ? join(tempDir, subpath) : tempDir;
1676
+ if (subpath) {
1677
+ const cloneRoot = await realpath(tempDir);
1678
+ const sourceRealpath = await realpath(sourcePath);
1679
+ assertPathInsideRootChild(cloneRoot, sourceRealpath, `git_repo subpath escapes the cloned repository: ${subpath}`);
1680
+ }
1681
+ await materializeGitRepoSource(writer, absolutePath, sourcePath, options, subpath);
1682
+ } finally {
1683
+ await rm(tempDir, { recursive: true, force: true });
1684
+ }
1685
+ }
1686
+ async function cloneGitRepo(repositoryUrl, destination, ref) {
1687
+ if (!ref || !looksLikeCommitRef(ref)) {
1688
+ return { result: await cloneNamedRef(repositoryUrl, destination, ref) };
1689
+ }
1690
+ const result = await fetchCommitRef(repositoryUrl, destination, ref);
1691
+ if (result.status === 0) {
1692
+ return { result };
1693
+ }
1694
+ await rm(destination, { recursive: true, force: true });
1695
+ return {
1696
+ result: await cloneNamedRef(repositoryUrl, destination, ref),
1697
+ commitFetchError: result
1698
+ };
1699
+ }
1700
+ async function cloneNamedRef(repositoryUrl, destination, ref) {
1701
+ const cloneArgs = ["clone", "--depth", "1", "--no-tags"];
1702
+ if (ref) {
1703
+ cloneArgs.push("--branch", ref);
1704
+ }
1705
+ cloneArgs.push(repositoryUrl, destination);
1706
+ return await runSandboxProcess("git", cloneArgs, {
1707
+ timeoutMs: GIT_CLONE_TIMEOUT_MS
1708
+ });
1709
+ }
1710
+ async function fetchCommitRef(repositoryUrl, destination, ref) {
1711
+ const steps = [
1712
+ ["init", destination],
1713
+ ["-C", destination, "remote", "add", "origin", repositoryUrl],
1714
+ ["-C", destination, "fetch", "--depth", "1", "--no-tags", "origin", ref],
1715
+ ["-C", destination, "checkout", "--detach", "FETCH_HEAD"]
1716
+ ];
1717
+ for (const args of steps) {
1718
+ const result = await runSandboxProcess("git", args, {
1719
+ timeoutMs: GIT_CLONE_TIMEOUT_MS
1720
+ });
1721
+ if (result.status !== 0) {
1722
+ return result;
1723
+ }
1724
+ }
1725
+ return {
1726
+ status: 0,
1727
+ signal: null,
1728
+ stdout: "",
1729
+ stderr: "",
1730
+ timedOut: false
1731
+ };
1732
+ }
1733
+ function looksLikeCommitRef(ref) {
1734
+ return COMMIT_REF_PATTERN.test(ref);
1735
+ }
1736
+ async function materializeGitRepoSource(writer, absolutePath, sourcePath, options, subpath) {
1737
+ const sourceInfo = await lstat(sourcePath);
1738
+ if (sourceInfo.isDirectory()) {
1739
+ await materializeLocalDirectory(writer, absolutePath, sourcePath, options);
1740
+ return;
1741
+ }
1742
+ if (sourceInfo.isFile()) {
1743
+ await writer.writeFile(absolutePath, await readFile(sourcePath));
1744
+ return;
1745
+ }
1746
+ throw new UserError(`git_repo subpath must resolve to a file or directory: ${subpath ?? "."}`);
1747
+ }
1748
+ function formatGitRepositoryForError(repository) {
1749
+ if (typeof repository === "string") {
1750
+ return repository;
1751
+ }
1752
+ return repository.repo;
1753
+ }
1754
+
1755
+ export {
1756
+ connectMcpServers,
1757
+ MemorySession,
1758
+ normalizeSandboxClientCreateArgs,
1759
+ resolveSandboxArchiveLimits,
1760
+ validateSandboxArchiveLimits,
1761
+ isNoopSnapshotSpec,
1762
+ relativeHostPathEscapesRoot,
1763
+ isHostPathWithinRoot,
1764
+ isHostPathStrictlyWithinRoot,
1765
+ runSandboxProcess,
1766
+ formatSandboxProcessError,
1767
+ assertViewImageByteLength,
1768
+ imageOutputFromBytes,
1769
+ toUint8Array,
1770
+ truncateOutput,
1771
+ formatExecResponse,
1772
+ elapsedSeconds,
1773
+ validateCredentialPair,
1774
+ resolveSandboxAbsolutePath,
1775
+ validateRemoteSandboxPathForManifest,
1776
+ resolveSandboxRelativePath,
1777
+ resolveSandboxWorkdir,
1778
+ cloneManifestWithRoot,
1779
+ cloneManifestWithoutMountEntries,
1780
+ manifestContainsLocalSource,
1781
+ entryContainsLocalSource,
1782
+ applyInlineManifestEntryToState,
1783
+ applyInlineManifestToState,
1784
+ applyLocalSourceManifestEntryToState,
1785
+ applyLocalSourceManifestToState,
1786
+ materializeLocalSourceManifest,
1787
+ materializeLocalSourceManifestEntry
1788
+ };
1789
+ //# sourceMappingURL=chunk-4YJ5Z52Z.js.map