deepline 0.3.57 → 0.3.59
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.
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +109 -61
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +39 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +76 -24
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -199,7 +199,7 @@ export const SDK_RELEASE = {
|
|
|
199
199
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
200
200
|
// getters keep their established compatibility behavior.
|
|
201
201
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
202
|
-
version: '0.3.
|
|
202
|
+
version: '0.3.59',
|
|
203
203
|
updateSummary:
|
|
204
204
|
'Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.',
|
|
205
205
|
packageCapabilities: {
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
compileRequestsWithStrategy,
|
|
31
31
|
executeChunkedRequests,
|
|
32
32
|
} from './batch-runtime';
|
|
33
|
+
import type { CompiledRequestBatch } from './batch-runtime';
|
|
33
34
|
import type { AnyBatchOperationStrategy } from './batching-types';
|
|
34
35
|
import {
|
|
35
36
|
PLAY_RUNTIME_WORK_RECEIPT_LEASE_TTL_MS,
|
|
@@ -169,10 +170,10 @@ import {
|
|
|
169
170
|
import {
|
|
170
171
|
buildDurableCtxCallCacheKey,
|
|
171
172
|
buildDurableRunPlayInvocationScope,
|
|
172
|
-
buildDurableToolAggregateProviderIdempotencyKey,
|
|
173
173
|
buildDurableToolAggregateReceiptKey,
|
|
174
174
|
buildDurableToolCallAuthScopeDigest,
|
|
175
175
|
buildDurableToolCallCacheKey,
|
|
176
|
+
buildDurableToolPayloadProviderIdempotencyKey,
|
|
176
177
|
buildDurableToolProviderIdempotencyKey,
|
|
177
178
|
buildDurableToolReceiptPrefix,
|
|
178
179
|
resolveDurableCallCachePolicy,
|
|
@@ -11273,6 +11274,21 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
11273
11274
|
strategy,
|
|
11274
11275
|
getPayload: (request: ToolCallRequest) => request.input,
|
|
11275
11276
|
});
|
|
11277
|
+
const compileOwnedPhysicalBatch = (
|
|
11278
|
+
owned: ToolCallRequest[],
|
|
11279
|
+
): CompiledRequestBatch<ToolCallRequest> => {
|
|
11280
|
+
const compiled = compileRequestsWithStrategy({
|
|
11281
|
+
requests: owned,
|
|
11282
|
+
strategy,
|
|
11283
|
+
getPayload: (request: ToolCallRequest) => request.input,
|
|
11284
|
+
});
|
|
11285
|
+
if (compiled.length !== 1) {
|
|
11286
|
+
throw new Error(
|
|
11287
|
+
'Native batch owned members must compile into exactly one provider request.',
|
|
11288
|
+
);
|
|
11289
|
+
}
|
|
11290
|
+
return compiled[0]!;
|
|
11291
|
+
};
|
|
11276
11292
|
const batchParallelismCeiling =
|
|
11277
11293
|
this.governor.policy.pacing.workerToolBatchDefaultParallelism;
|
|
11278
11294
|
const batchSize =
|
|
@@ -11282,6 +11298,9 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
11282
11298
|
batchParallelismCeiling,
|
|
11283
11299
|
)
|
|
11284
11300
|
: batchParallelismCeiling;
|
|
11301
|
+
const batchProviderActionVersion =
|
|
11302
|
+
(await this.#options.getToolActionCacheVersion?.(toolId))?.trim() ??
|
|
11303
|
+
'unversioned';
|
|
11285
11304
|
const successful: ToolCallRequest[] = [];
|
|
11286
11305
|
|
|
11287
11306
|
const deliver = (request: ToolCallRequest, result: ToolExecuteResult) => {
|
|
@@ -11332,6 +11351,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
11332
11351
|
string,
|
|
11333
11352
|
{
|
|
11334
11353
|
members: ToolCallRequest[];
|
|
11354
|
+
compiled: CompiledRequestBatch<ToolCallRequest>;
|
|
11335
11355
|
providerOperationKey: string;
|
|
11336
11356
|
receiptLeaseExpiresAt: string | null;
|
|
11337
11357
|
timeoutMs: number | undefined;
|
|
@@ -11380,26 +11400,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
11380
11400
|
detail.members[0]?.executionAuthScopeDigest ?? null,
|
|
11381
11401
|
providerIdempotencyReceiptKey:
|
|
11382
11402
|
detail.providerOperationKey,
|
|
11383
|
-
providerIdempotencyKey:
|
|
11384
|
-
buildDurableToolAggregateProviderIdempotencyKey({
|
|
11385
|
-
aggregateReceiptKey: detail.providerOperationKey,
|
|
11386
|
-
receiptKeys: detail.members.map(
|
|
11387
|
-
(member) =>
|
|
11388
|
-
member.providerIdempotencyKeyBase ??
|
|
11389
|
-
member.receiptKey!,
|
|
11390
|
-
),
|
|
11391
|
-
providerIdempotencyKeys: detail.members.map(
|
|
11392
|
-
(member) =>
|
|
11393
|
-
this.providerIdempotencyKeyForToolCall({
|
|
11394
|
-
cacheKey:
|
|
11395
|
-
member.providerIdempotencyKeyBase ??
|
|
11396
|
-
member.receiptKey!,
|
|
11397
|
-
force: member.force === true,
|
|
11398
|
-
leaseId: member.receiptLeaseId,
|
|
11399
|
-
logicalCallId: member.logicalCallId,
|
|
11400
|
-
}),
|
|
11401
|
-
),
|
|
11402
|
-
}),
|
|
11403
|
+
providerIdempotencyKey: detail.providerOperationKey,
|
|
11403
11404
|
receiptLeaseExpiresAt: detail.receiptLeaseExpiresAt,
|
|
11404
11405
|
timeoutMs: detail.timeoutMs,
|
|
11405
11406
|
},
|
|
@@ -11477,10 +11478,6 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
11477
11478
|
(member) => batchRequestByCallId.get(member.memberId)!,
|
|
11478
11479
|
);
|
|
11479
11480
|
const receiptKeys = owned.map((request) => request.receiptKey!);
|
|
11480
|
-
const providerReceiptKeys = owned.map(
|
|
11481
|
-
(request) =>
|
|
11482
|
-
request.providerIdempotencyKeyBase ?? request.receiptKey!,
|
|
11483
|
-
);
|
|
11484
11481
|
const aggregateReceiptKey = buildDurableToolAggregateReceiptKey({
|
|
11485
11482
|
receiptKeys,
|
|
11486
11483
|
prefix: 'batch',
|
|
@@ -11489,16 +11486,36 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
11489
11486
|
toolId: batch.batchOperation,
|
|
11490
11487
|
}),
|
|
11491
11488
|
});
|
|
11492
|
-
const
|
|
11493
|
-
|
|
11494
|
-
|
|
11495
|
-
|
|
11489
|
+
const compiled = compileOwnedPhysicalBatch(owned);
|
|
11490
|
+
if (compiled.batchOperation !== batch.batchOperation) {
|
|
11491
|
+
throw new Error(
|
|
11492
|
+
'Native batch owned members changed provider operation during compilation.',
|
|
11493
|
+
);
|
|
11494
|
+
}
|
|
11495
|
+
const providerOperationKey =
|
|
11496
|
+
buildDurableToolPayloadProviderIdempotencyKey({
|
|
11496
11497
|
orgId: this.#options.orgId,
|
|
11497
11498
|
toolId: batch.batchOperation,
|
|
11498
|
-
|
|
11499
|
-
|
|
11499
|
+
executionAuthScopeDigest:
|
|
11500
|
+
owned[0]?.executionAuthScopeDigest ?? null,
|
|
11501
|
+
providerActionVersion: batchProviderActionVersion,
|
|
11502
|
+
payload: compiled.batchPayload,
|
|
11503
|
+
forceRefreshIdentities: owned
|
|
11504
|
+
.filter((request) => request.force === true)
|
|
11505
|
+
.map((request) =>
|
|
11506
|
+
this.providerIdempotencyKeyForToolCall({
|
|
11507
|
+
cacheKey:
|
|
11508
|
+
request.providerIdempotencyKeyBase ??
|
|
11509
|
+
request.receiptKey!,
|
|
11510
|
+
force: true,
|
|
11511
|
+
leaseId: request.receiptLeaseId,
|
|
11512
|
+
logicalCallId: request.logicalCallId,
|
|
11513
|
+
}),
|
|
11514
|
+
),
|
|
11515
|
+
});
|
|
11500
11516
|
dispatchDetails.set(aggregateReceiptKey, {
|
|
11501
11517
|
members: owned,
|
|
11518
|
+
compiled,
|
|
11502
11519
|
providerOperationKey,
|
|
11503
11520
|
receiptLeaseExpiresAt: owned.reduce<string | null>(
|
|
11504
11521
|
(earliest, request) => {
|
|
@@ -11523,7 +11540,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
11523
11540
|
return {
|
|
11524
11541
|
...members[0]!.call,
|
|
11525
11542
|
tool: { id: batch.batchOperation, providerActionVersion: '' },
|
|
11526
|
-
payload:
|
|
11543
|
+
payload: compiled.batchPayload,
|
|
11527
11544
|
compatibility: {
|
|
11528
11545
|
resultReceiptKey: aggregateReceiptKey,
|
|
11529
11546
|
providerOperationKey,
|
|
@@ -11531,7 +11548,40 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
11531
11548
|
};
|
|
11532
11549
|
},
|
|
11533
11550
|
splitResult: async ({ result: aggregate, members }) => {
|
|
11534
|
-
const
|
|
11551
|
+
const receiptKeys = members.map((member) => {
|
|
11552
|
+
const request = batchRequestByCallId.get(member.memberId);
|
|
11553
|
+
if (!request?.receiptKey) {
|
|
11554
|
+
throw new Error(
|
|
11555
|
+
`Native batch Tool Call lost receipt for ${member.memberId}.`,
|
|
11556
|
+
);
|
|
11557
|
+
}
|
|
11558
|
+
return request.receiptKey;
|
|
11559
|
+
});
|
|
11560
|
+
const aggregateReceiptKey = buildDurableToolAggregateReceiptKey({
|
|
11561
|
+
receiptKeys,
|
|
11562
|
+
prefix: 'batch',
|
|
11563
|
+
aggregateReceiptPrefix: buildDurableToolReceiptPrefix({
|
|
11564
|
+
orgId: this.#options.orgId,
|
|
11565
|
+
toolId: batch.batchOperation,
|
|
11566
|
+
}),
|
|
11567
|
+
});
|
|
11568
|
+
const detail = dispatchDetails.get(aggregateReceiptKey);
|
|
11569
|
+
if (!detail) {
|
|
11570
|
+
throw new Error(
|
|
11571
|
+
'Native batch Tool Call lost its split compilation details.',
|
|
11572
|
+
);
|
|
11573
|
+
}
|
|
11574
|
+
if (
|
|
11575
|
+
detail.members.length !== members.length ||
|
|
11576
|
+
!detail.members.every(
|
|
11577
|
+
(request, index) => request.callId === members[index]?.memberId,
|
|
11578
|
+
)
|
|
11579
|
+
) {
|
|
11580
|
+
throw new Error(
|
|
11581
|
+
'Native batch Tool Call split members changed in transit.',
|
|
11582
|
+
);
|
|
11583
|
+
}
|
|
11584
|
+
const split = detail.compiled.splitResults(
|
|
11535
11585
|
legacyResultForBatchSplitter(aggregate),
|
|
11536
11586
|
);
|
|
11537
11587
|
return await Promise.all(
|
|
@@ -12573,11 +12623,6 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
12573
12623
|
const receiptKeys = batch.memberRequests.map(
|
|
12574
12624
|
(request) => request.cacheKey,
|
|
12575
12625
|
);
|
|
12576
|
-
const providerIdempotencyReceiptKeys =
|
|
12577
|
-
batch.memberRequests.map(
|
|
12578
|
-
(request) =>
|
|
12579
|
-
request.providerIdempotencyKeyBase ?? request.cacheKey,
|
|
12580
|
-
);
|
|
12581
12626
|
const aggregateReceiptKey =
|
|
12582
12627
|
buildDurableToolAggregateReceiptKey({
|
|
12583
12628
|
receiptKeys,
|
|
@@ -12588,13 +12633,31 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
12588
12633
|
}),
|
|
12589
12634
|
});
|
|
12590
12635
|
const aggregateProviderIdempotencyReceiptKey =
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
|
|
12636
|
+
buildDurableToolPayloadProviderIdempotencyKey({
|
|
12637
|
+
orgId: this.#options.orgId,
|
|
12638
|
+
toolId: batch.batchOperation,
|
|
12639
|
+
executionAuthScopeDigest:
|
|
12640
|
+
batch.memberRequests[0]?.executionAuthScopeDigest ??
|
|
12641
|
+
null,
|
|
12642
|
+
providerActionVersion:
|
|
12643
|
+
(
|
|
12644
|
+
await this.#options.getToolActionCacheVersion?.(
|
|
12645
|
+
batch.batchOperation,
|
|
12646
|
+
)
|
|
12647
|
+
)?.trim() ?? 'unversioned',
|
|
12648
|
+
payload: batch.batchPayload,
|
|
12649
|
+
forceRefreshIdentities: batch.memberRequests
|
|
12650
|
+
.filter((request) => request.force === true)
|
|
12651
|
+
.map((request) =>
|
|
12652
|
+
this.providerIdempotencyKeyForToolCall({
|
|
12653
|
+
cacheKey:
|
|
12654
|
+
request.providerIdempotencyKeyBase ??
|
|
12655
|
+
request.cacheKey,
|
|
12656
|
+
force: true,
|
|
12657
|
+
leaseId: request.receiptLeaseId,
|
|
12658
|
+
logicalCallId: request.logicalCallId,
|
|
12659
|
+
}),
|
|
12660
|
+
),
|
|
12598
12661
|
});
|
|
12599
12662
|
let releaseToolSlot: () => void = () => undefined;
|
|
12600
12663
|
try {
|
|
@@ -12621,22 +12684,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
12621
12684
|
providerIdempotencyReceiptKey:
|
|
12622
12685
|
aggregateProviderIdempotencyReceiptKey,
|
|
12623
12686
|
providerIdempotencyKey:
|
|
12624
|
-
|
|
12625
|
-
aggregateReceiptKey:
|
|
12626
|
-
aggregateProviderIdempotencyReceiptKey,
|
|
12627
|
-
receiptKeys: providerIdempotencyReceiptKeys,
|
|
12628
|
-
providerIdempotencyKeys: batch.memberRequests.map(
|
|
12629
|
-
(request) =>
|
|
12630
|
-
this.providerIdempotencyKeyForToolCall({
|
|
12631
|
-
cacheKey:
|
|
12632
|
-
request.providerIdempotencyKeyBase ??
|
|
12633
|
-
request.cacheKey,
|
|
12634
|
-
force: request.force === true,
|
|
12635
|
-
leaseId: request.receiptLeaseId,
|
|
12636
|
-
logicalCallId: request.logicalCallId,
|
|
12637
|
-
}),
|
|
12638
|
-
),
|
|
12639
|
-
}),
|
|
12687
|
+
aggregateProviderIdempotencyReceiptKey,
|
|
12640
12688
|
receiptLeaseExpiresAt: batch.memberRequests.reduce<
|
|
12641
12689
|
string | null
|
|
12642
12690
|
>((earliest, request) => {
|
|
@@ -241,3 +241,42 @@ export function buildDurableToolAggregateProviderIdempotencyKey(input: {
|
|
|
241
241
|
stableStringify({ receiptKeys, providerIdempotencyKeys }),
|
|
242
242
|
)}`;
|
|
243
243
|
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Provider-native batch caching is keyed by the exact compiled provider
|
|
247
|
+
* payload. Receipt identities coordinate ownership and terminal results; they
|
|
248
|
+
* cannot stand in for request identity because cache hits and foreign leases
|
|
249
|
+
* can remove members after the original batch was planned.
|
|
250
|
+
*
|
|
251
|
+
* An explicit force refresh is deliberately a separate namespace: it asks for
|
|
252
|
+
* a fresh provider operation even when the payload itself is unchanged.
|
|
253
|
+
*/
|
|
254
|
+
export function buildDurableToolPayloadProviderIdempotencyKey(input: {
|
|
255
|
+
orgId?: string | null;
|
|
256
|
+
toolId: string;
|
|
257
|
+
executionAuthScopeDigest?: string | null;
|
|
258
|
+
providerActionVersion?: string | null;
|
|
259
|
+
payload: Record<string, unknown>;
|
|
260
|
+
forceRefreshIdentities?: readonly string[];
|
|
261
|
+
}): string {
|
|
262
|
+
const toolId = input.toolId.trim();
|
|
263
|
+
if (!toolId) {
|
|
264
|
+
throw new Error(
|
|
265
|
+
'Provider payload idempotency key needs a non-empty toolId.',
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
const forceRefreshIdentities = input.forceRefreshIdentities
|
|
269
|
+
?.map((identity) => identity.trim())
|
|
270
|
+
.filter(Boolean);
|
|
271
|
+
return `${buildDurableToolReceiptPrefix({
|
|
272
|
+
orgId: input.orgId,
|
|
273
|
+
toolId,
|
|
274
|
+
})}payload-v1:${sha256Hex(
|
|
275
|
+
stableStringify({
|
|
276
|
+
executionAuthScopeDigest: input.executionAuthScopeDigest?.trim() || null,
|
|
277
|
+
providerActionVersion: input.providerActionVersion?.trim() || null,
|
|
278
|
+
payload: input.payload,
|
|
279
|
+
...(forceRefreshIdentities?.length ? { forceRefreshIdentities } : {}),
|
|
280
|
+
}),
|
|
281
|
+
)}`;
|
|
282
|
+
}
|
package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts
CHANGED
|
@@ -311,11 +311,16 @@ async function createOneShotDaytonaSandbox(input: {
|
|
|
311
311
|
});
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
+
type TimedOutDaytonaSandboxReconciliation =
|
|
315
|
+
| { kind: 'started'; sandbox: DaytonaSandbox }
|
|
316
|
+
| { kind: 'deleted' }
|
|
317
|
+
| { kind: 'not_found' };
|
|
318
|
+
|
|
314
319
|
async function reconcileAndDeleteTimedOutDaytonaSandbox(input: {
|
|
315
320
|
daytona: DaytonaClient;
|
|
316
321
|
sandboxName: string;
|
|
317
|
-
}): Promise<
|
|
318
|
-
if (!input.daytona.get) return
|
|
322
|
+
}): Promise<TimedOutDaytonaSandboxReconciliation> {
|
|
323
|
+
if (!input.daytona.get) return { kind: 'not_found' };
|
|
319
324
|
let lastDeleteConflict: unknown = null;
|
|
320
325
|
for (const delayMs of DAYTONA_TIMED_OUT_CREATE_RECONCILE_DELAYS_MS) {
|
|
321
326
|
if (delayMs > 0) {
|
|
@@ -327,6 +332,14 @@ async function reconcileAndDeleteTimedOutDaytonaSandbox(input: {
|
|
|
327
332
|
} catch {
|
|
328
333
|
continue;
|
|
329
334
|
}
|
|
335
|
+
// `create` waits only a bounded interval, but the named sandbox may finish
|
|
336
|
+
// the same create transition immediately afterwards. It is already the
|
|
337
|
+
// durable identity associated with this provider operation, so reusing it
|
|
338
|
+
// is safer and faster than attempting a conflicting delete or creating a
|
|
339
|
+
// second sandbox.
|
|
340
|
+
if (sandbox.state === 'started') {
|
|
341
|
+
return { kind: 'started', sandbox };
|
|
342
|
+
}
|
|
330
343
|
try {
|
|
331
344
|
await sandbox.delete(30);
|
|
332
345
|
} catch (error) {
|
|
@@ -344,7 +357,7 @@ async function reconcileAndDeleteTimedOutDaytonaSandbox(input: {
|
|
|
344
357
|
{ cause: error },
|
|
345
358
|
);
|
|
346
359
|
}
|
|
347
|
-
return
|
|
360
|
+
return { kind: 'deleted' };
|
|
348
361
|
}
|
|
349
362
|
if (lastDeleteConflict) {
|
|
350
363
|
throw new Error(
|
|
@@ -352,7 +365,7 @@ async function reconcileAndDeleteTimedOutDaytonaSandbox(input: {
|
|
|
352
365
|
{ cause: lastDeleteConflict },
|
|
353
366
|
);
|
|
354
367
|
}
|
|
355
|
-
return
|
|
368
|
+
return { kind: 'not_found' };
|
|
356
369
|
}
|
|
357
370
|
|
|
358
371
|
async function createRetriedOneShotDaytonaSandbox(input: {
|
|
@@ -402,16 +415,14 @@ async function createRetriedOneShotDaytonaSandbox(input: {
|
|
|
402
415
|
// A normal rejected create has no durable provider resource. A timeout
|
|
403
416
|
// can be ambiguous, so retain its lease until the crash TTL rather than
|
|
404
417
|
// admitting another sandbox against an unknown provider outcome.
|
|
405
|
-
if (reservation && !isDaytonaSandboxStartTimeout(String(error))) {
|
|
406
|
-
await input.releaseSandboxCapacity?.(reservation.leaseId);
|
|
407
|
-
}
|
|
408
|
-
await input.observeCreateCall?.({
|
|
409
|
-
type: 'daytona_create_call_failed',
|
|
410
|
-
occurredAtMs: Date.now(),
|
|
411
|
-
providerAttempt: attempt,
|
|
412
|
-
errorClass: daytonaCreateErrorClass(error),
|
|
413
|
-
});
|
|
414
418
|
const message = error instanceof Error ? error.message : String(error);
|
|
419
|
+
const recordCreateFailure = () =>
|
|
420
|
+
input.observeCreateCall?.({
|
|
421
|
+
type: 'daytona_create_call_failed',
|
|
422
|
+
occurredAtMs: Date.now(),
|
|
423
|
+
providerAttempt: attempt,
|
|
424
|
+
errorClass: daytonaCreateErrorClass(error),
|
|
425
|
+
});
|
|
415
426
|
errors.push(message);
|
|
416
427
|
input.emitStage('create:attempt_failed', {
|
|
417
428
|
attempt,
|
|
@@ -427,18 +438,49 @@ async function createRetriedOneShotDaytonaSandbox(input: {
|
|
|
427
438
|
});
|
|
428
439
|
const immediateFallbackReason =
|
|
429
440
|
resolveDaytonaSandboxAcquisitionUnavailableReason([message]);
|
|
430
|
-
if (immediateFallbackReason === 'daytona_total_cpu_limit_exceeded') {
|
|
431
|
-
throw new DaytonaSandboxAcquisitionUnavailableError(
|
|
432
|
-
immediateFallbackReason,
|
|
433
|
-
`Daytona sandbox create rejected by the organization CPU limit on provider attempt ${attempt}: ${message}`,
|
|
434
|
-
);
|
|
435
|
-
}
|
|
436
441
|
if (isDaytonaSandboxStartTimeout(message)) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
+
let reconciliation: TimedOutDaytonaSandboxReconciliation;
|
|
443
|
+
try {
|
|
444
|
+
reconciliation = await reconcileAndDeleteTimedOutDaytonaSandbox({
|
|
445
|
+
daytona: input.daytona,
|
|
446
|
+
sandboxName,
|
|
447
|
+
});
|
|
448
|
+
} catch (reconciliationError) {
|
|
449
|
+
await recordCreateFailure();
|
|
450
|
+
throw reconciliationError;
|
|
451
|
+
}
|
|
452
|
+
if (reconciliation.kind === 'started') {
|
|
453
|
+
const acquiredAt = Date.now();
|
|
454
|
+
try {
|
|
455
|
+
await input.observeCreateCall?.({
|
|
456
|
+
type: 'daytona_create_call_succeeded',
|
|
457
|
+
occurredAtMs: acquiredAt,
|
|
458
|
+
providerAttempt: attempt,
|
|
459
|
+
sandboxId: reconciliation.sandbox.id,
|
|
460
|
+
});
|
|
461
|
+
} catch {
|
|
462
|
+
console.error(
|
|
463
|
+
'[play-runner.daytona.create_lifecycle_event_unrecorded]',
|
|
464
|
+
{
|
|
465
|
+
workflowId: input.context.workflowId ?? null,
|
|
466
|
+
runId: input.context.runId ?? null,
|
|
467
|
+
attempt,
|
|
468
|
+
sandboxId: reconciliation.sandbox.id,
|
|
469
|
+
eventType: 'daytona_create_call_succeeded',
|
|
470
|
+
},
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
return {
|
|
474
|
+
sandbox: reconciliation.sandbox,
|
|
475
|
+
attempt,
|
|
476
|
+
attemptElapsedMs: acquiredAt - attemptStartedAt,
|
|
477
|
+
...(reservation
|
|
478
|
+
? { sandboxCapacityLeaseId: reservation.leaseId }
|
|
479
|
+
: {}),
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
await recordCreateFailure();
|
|
483
|
+
if (reconciliation.kind === 'deleted') {
|
|
442
484
|
// The provider-confirmed reconciliation means this reservation can
|
|
443
485
|
// no longer represent a live sandbox. Release before returning the
|
|
444
486
|
// acquisition-unavailable result so Modal fallback is not blocked
|
|
@@ -456,6 +498,16 @@ async function createRetriedOneShotDaytonaSandbox(input: {
|
|
|
456
498
|
{ cause: error },
|
|
457
499
|
);
|
|
458
500
|
}
|
|
501
|
+
if (reservation) {
|
|
502
|
+
await input.releaseSandboxCapacity?.(reservation.leaseId);
|
|
503
|
+
}
|
|
504
|
+
await recordCreateFailure();
|
|
505
|
+
if (immediateFallbackReason === 'daytona_total_cpu_limit_exceeded') {
|
|
506
|
+
throw new DaytonaSandboxAcquisitionUnavailableError(
|
|
507
|
+
immediateFallbackReason,
|
|
508
|
+
`Daytona sandbox create rejected by the organization CPU limit on provider attempt ${attempt}: ${message}`,
|
|
509
|
+
);
|
|
510
|
+
}
|
|
459
511
|
continue;
|
|
460
512
|
}
|
|
461
513
|
// The outcome must be attributed immediately after Daytona acknowledges
|
package/dist/cli/index.js
CHANGED
|
@@ -1075,7 +1075,7 @@ var SDK_RELEASE = {
|
|
|
1075
1075
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1076
1076
|
// getters keep their established compatibility behavior.
|
|
1077
1077
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1078
|
-
version: "0.3.
|
|
1078
|
+
version: "0.3.59",
|
|
1079
1079
|
updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
|
|
1080
1080
|
packageCapabilities: {
|
|
1081
1081
|
updatePreferences: 1
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1060,7 +1060,7 @@ var SDK_RELEASE = {
|
|
|
1060
1060
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1061
1061
|
// getters keep their established compatibility behavior.
|
|
1062
1062
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1063
|
-
version: "0.3.
|
|
1063
|
+
version: "0.3.59",
|
|
1064
1064
|
updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
|
|
1065
1065
|
packageCapabilities: {
|
|
1066
1066
|
updatePreferences: 1
|
package/dist/index.js
CHANGED
|
@@ -826,7 +826,7 @@ var SDK_RELEASE = {
|
|
|
826
826
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
827
827
|
// getters keep their established compatibility behavior.
|
|
828
828
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
829
|
-
version: "0.3.
|
|
829
|
+
version: "0.3.59",
|
|
830
830
|
updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
|
|
831
831
|
packageCapabilities: {
|
|
832
832
|
updatePreferences: 1
|
package/dist/index.mjs
CHANGED
|
@@ -738,7 +738,7 @@ var SDK_RELEASE = {
|
|
|
738
738
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
739
739
|
// getters keep their established compatibility behavior.
|
|
740
740
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
741
|
-
version: "0.3.
|
|
741
|
+
version: "0.3.59",
|
|
742
742
|
updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
|
|
743
743
|
packageCapabilities: {
|
|
744
744
|
updatePreferences: 1
|