deepline 0.3.200 → 0.3.202
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/client.ts +62 -1
- package/dist/bundling-sources/sdk/src/http.ts +55 -6
- package/dist/bundling-sources/sdk/src/index.ts +1 -0
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +10 -2
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +4 -2
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +460 -96
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +11 -1
- package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-invocation-fence.ts +6 -2
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +401 -2
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +458 -0
- package/dist/bundling-sources/shared_libs/play-runtime/provider-no-progress.ts +40 -0
- package/dist/bundling-sources/shared_libs/play-runtime/receipt-sql.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +25 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +119 -171
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-work-counters.ts +37 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-deadline-reconciliation.ts +160 -58
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +111 -6
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +51 -46
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +16 -7
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +304 -33
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +21 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-value-storage.ts +64 -15
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +133 -5
- package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +5 -5
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/index.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/result-receipt-policy.ts +46 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +14 -5
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +5 -1
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-state-machine.ts +3 -9
- package/dist/cli/index.js +364 -39
- package/dist/cli/index.mjs +367 -41
- package/dist/index.d.mts +131 -3
- package/dist/index.d.ts +131 -3
- package/dist/index.js +64 -7
- package/dist/index.mjs +64 -7
- package/dist/install-integrity.json +3 -0
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
|
@@ -64,6 +64,7 @@ function schemaTables(options?: Pick<PostgresSchedulerOptions, 'schema'>) {
|
|
|
64
64
|
leases: `${schema}."runtime_sandbox_capacity_leases"`,
|
|
65
65
|
operations: `${schema}."runtime_sandbox_operations"`,
|
|
66
66
|
cleanup: `${schema}."sandbox_cleanup_jobs_v2"`,
|
|
67
|
+
runs: `${schema}."runs"`,
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
70
|
|
|
@@ -266,7 +267,7 @@ export async function reserveRuntimeSandboxCapacityLease(
|
|
|
266
267
|
> {
|
|
267
268
|
const orgId = assertId(input.orgId, 'orgId');
|
|
268
269
|
const runId = assertId(input.runId, 'runId');
|
|
269
|
-
const { cache, leases, operations } = schemaTables(options);
|
|
270
|
+
const { cache, leases, operations, runs } = schemaTables(options);
|
|
270
271
|
// This is deliberately a soft admission check: concurrent workers may both
|
|
271
272
|
// observe space and insert. Avoid locks and long transactions; the provider
|
|
272
273
|
// has its own global safety cap and the 50-minute lease bounds crashes.
|
|
@@ -469,13 +470,21 @@ export async function reserveRuntimeSandboxCapacityLease(
|
|
|
469
470
|
}
|
|
470
471
|
await client.query(
|
|
471
472
|
`
|
|
472
|
-
WITH
|
|
473
|
+
WITH active_run AS MATERIALIZED (
|
|
474
|
+
SELECT run_id FROM ${runs}
|
|
475
|
+
WHERE run_id = $3 AND status IN ('queued', 'running', 'waiting')
|
|
476
|
+
AND NOT EXISTS (
|
|
477
|
+
SELECT 1 FROM ${quoteIdent(options?.schema ?? 'runtime_scheduler')}."control"
|
|
478
|
+
WHERE key = 'runtime_cancel:' || $3::text
|
|
479
|
+
)
|
|
480
|
+
FOR UPDATE
|
|
481
|
+
), reserved_lease AS (
|
|
473
482
|
INSERT INTO ${leases} (
|
|
474
483
|
lease_id, org_id, run_id, provider, expires_at
|
|
475
|
-
) VALUES (
|
|
476
|
-
$1, $2, $3, $4,
|
|
477
|
-
clock_timestamp() + ($5::integer * interval '1 millisecond')
|
|
478
484
|
)
|
|
485
|
+
SELECT $1, $2, $3, $4,
|
|
486
|
+
clock_timestamp() + ($5::integer * interval '1 millisecond')
|
|
487
|
+
WHERE $6::integer IS NULL OR EXISTS (SELECT 1 FROM active_run)
|
|
479
488
|
ON CONFLICT (lease_id) DO NOTHING
|
|
480
489
|
RETURNING lease_id
|
|
481
490
|
)
|
|
@@ -726,6 +735,125 @@ export async function abandonRuntimeSandboxOperationReservation(
|
|
|
726
735
|
return result.rows.length === 1;
|
|
727
736
|
}
|
|
728
737
|
|
|
738
|
+
export async function readReservedDaytonaCancellationOperation(
|
|
739
|
+
client: PostgresSchedulerQueryClient,
|
|
740
|
+
environment: 'preview' | 'production',
|
|
741
|
+
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
742
|
+
): Promise<{
|
|
743
|
+
operationKey: string;
|
|
744
|
+
providerOperationToken: string;
|
|
745
|
+
createdAtMs: number;
|
|
746
|
+
} | null> {
|
|
747
|
+
const { operations } = schemaTables(options);
|
|
748
|
+
const schema = quoteIdent(options?.schema ?? 'runtime_scheduler');
|
|
749
|
+
const rows = await client.query<{
|
|
750
|
+
operation_key: string;
|
|
751
|
+
provider_operation_token: string | null;
|
|
752
|
+
created_at_ms: number;
|
|
753
|
+
}>(
|
|
754
|
+
`WITH candidate AS (
|
|
755
|
+
SELECT operation.operation_key
|
|
756
|
+
FROM ${operations} AS operation
|
|
757
|
+
JOIN ${schema}."control" AS request
|
|
758
|
+
ON request.key = 'runtime_cancel:' || operation.run_id
|
|
759
|
+
WHERE operation.provider = 'daytona'
|
|
760
|
+
AND operation.environment = $1
|
|
761
|
+
AND operation.state = 'reserved'
|
|
762
|
+
ORDER BY operation.updated_at ASC, operation.operation_key ASC
|
|
763
|
+
LIMIT 1
|
|
764
|
+
FOR UPDATE OF operation SKIP LOCKED
|
|
765
|
+
)
|
|
766
|
+
UPDATE ${operations} AS operation
|
|
767
|
+
SET updated_at = clock_timestamp()
|
|
768
|
+
FROM candidate
|
|
769
|
+
WHERE operation.operation_key = candidate.operation_key
|
|
770
|
+
RETURNING operation.operation_key, operation.provider_operation_token,
|
|
771
|
+
floor(extract(epoch FROM operation.created_at) * 1000)::bigint AS created_at_ms`,
|
|
772
|
+
[environment],
|
|
773
|
+
);
|
|
774
|
+
const row = rows.rows[0];
|
|
775
|
+
if (!row) return null;
|
|
776
|
+
if (!row.provider_operation_token) {
|
|
777
|
+
throw new Error(
|
|
778
|
+
`Reserved Daytona cancellation operation ${row.operation_key} lacks its provider token.`,
|
|
779
|
+
);
|
|
780
|
+
}
|
|
781
|
+
return {
|
|
782
|
+
operationKey: row.operation_key,
|
|
783
|
+
providerOperationToken: row.provider_operation_token,
|
|
784
|
+
createdAtMs: Number(row.created_at_ms),
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
export async function recordRecoveredDaytonaCancellationSandbox(
|
|
789
|
+
client: PostgresSchedulerQueryClient,
|
|
790
|
+
input: { operationKey: string; sandboxId: string; routingDomain: string },
|
|
791
|
+
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
792
|
+
): Promise<boolean> {
|
|
793
|
+
const { operations, leases, cleanup } = schemaTables(options);
|
|
794
|
+
const schema = quoteIdent(options?.schema ?? 'runtime_scheduler');
|
|
795
|
+
const recorded = await client.query<{ operation_key: string }>(
|
|
796
|
+
`WITH promoted AS (
|
|
797
|
+
UPDATE ${operations} AS operation
|
|
798
|
+
SET state = 'deleting',
|
|
799
|
+
sandbox_id = $2,
|
|
800
|
+
routing_domain = $3,
|
|
801
|
+
provider_created_at = clock_timestamp(),
|
|
802
|
+
updated_at = clock_timestamp()
|
|
803
|
+
WHERE operation.operation_key = $1
|
|
804
|
+
AND operation.provider = 'daytona'
|
|
805
|
+
AND operation.state = 'reserved'
|
|
806
|
+
RETURNING operation.operation_key, operation.run_id, operation.attempt,
|
|
807
|
+
operation.environment, operation.created_at
|
|
808
|
+
), resource AS (
|
|
809
|
+
SELECT promoted.*,
|
|
810
|
+
jsonb_build_object(
|
|
811
|
+
'kind', 'daytona_sandbox',
|
|
812
|
+
'sandboxId', $2::text,
|
|
813
|
+
'runtimeEnvironment', promoted.environment,
|
|
814
|
+
'daytonaOrganizationId', $3::text,
|
|
815
|
+
'billingStartedAt', extract(epoch FROM promoted.created_at) * 1000,
|
|
816
|
+
'sandboxCapacityLeaseId', promoted.operation_key,
|
|
817
|
+
'lateAcquired', true
|
|
818
|
+
) AS value
|
|
819
|
+
FROM promoted
|
|
820
|
+
), recorded_attempt AS (
|
|
821
|
+
UPDATE ${schema}."attempts" AS attempt
|
|
822
|
+
SET resource_json = CASE
|
|
823
|
+
WHEN attempt.resource_json IS NULL THEN jsonb_build_array(resource.value)
|
|
824
|
+
WHEN jsonb_typeof(attempt.resource_json) = 'array'
|
|
825
|
+
THEN attempt.resource_json || jsonb_build_array(resource.value)
|
|
826
|
+
ELSE jsonb_build_array(attempt.resource_json, resource.value)
|
|
827
|
+
END,
|
|
828
|
+
updated_at = clock_timestamp()
|
|
829
|
+
FROM resource
|
|
830
|
+
WHERE attempt.run_id = resource.run_id
|
|
831
|
+
AND attempt.attempt = resource.attempt
|
|
832
|
+
RETURNING attempt.run_id
|
|
833
|
+
), bound AS (
|
|
834
|
+
UPDATE ${leases} AS lease
|
|
835
|
+
SET sandbox_id = $2, routing_domain = $3
|
|
836
|
+
FROM promoted
|
|
837
|
+
WHERE lease.lease_id = promoted.operation_key
|
|
838
|
+
AND lease.released_at IS NULL
|
|
839
|
+
RETURNING lease.lease_id
|
|
840
|
+
), queued AS (
|
|
841
|
+
INSERT INTO ${cleanup} (
|
|
842
|
+
provider, sandbox_id, run_id, attempt, environment, routing_domain
|
|
843
|
+
)
|
|
844
|
+
SELECT 'daytona', $2, promoted.run_id, promoted.attempt,
|
|
845
|
+
promoted.environment, $3
|
|
846
|
+
FROM promoted
|
|
847
|
+
ON CONFLICT (provider, sandbox_id, routing_domain_key) DO NOTHING
|
|
848
|
+
)
|
|
849
|
+
SELECT promoted.operation_key FROM promoted
|
|
850
|
+
JOIN recorded_attempt ON recorded_attempt.run_id = promoted.run_id
|
|
851
|
+
JOIN bound ON bound.lease_id = promoted.operation_key`,
|
|
852
|
+
[input.operationKey, input.sandboxId, input.routingDomain],
|
|
853
|
+
);
|
|
854
|
+
return recorded.rows.length === 1;
|
|
855
|
+
}
|
|
856
|
+
|
|
729
857
|
/** Release only after the provider confirms deletion (or already absent). */
|
|
730
858
|
export async function releaseRuntimeSandboxCapacityLeaseForSandbox(
|
|
731
859
|
client: PostgresSchedulerQueryClient,
|
|
@@ -41,11 +41,11 @@ export function releasableRuntimeSheetAttemptFenceSql(
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* Predicate for
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
44
|
+
* Predicate for callers that need to identify a terminal row from the same
|
|
45
|
+
* attempt owner + epoch. Runtime map persistence now enforces first-terminal
|
|
46
|
+
* idempotency inline because its write-version and row-key context are also
|
|
47
|
+
* required; keep this helper exported for compatibility with external
|
|
48
|
+
* conformance checks and integrations.
|
|
49
49
|
*/
|
|
50
50
|
export function sameOwnerTerminalAttemptEpochSql(
|
|
51
51
|
tableAlias: string,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { scopeToolReceiptToInvocation } from '../durable-call-cache';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Freshness chooses which completed results a run may reuse. It never turns
|
|
5
|
+
* off durable progress inside that run. A forced invocation gets an immutable
|
|
6
|
+
* result of its own; a scheduler retry reads it like any other completed key.
|
|
7
|
+
*
|
|
8
|
+
* The canonical key already binds payload, authorization, action and response
|
|
9
|
+
* semantics. Keep it in the derivation so a changed input cannot recover an
|
|
10
|
+
* unrelated result. Provider operation identities and public receipt metadata
|
|
11
|
+
* remain canonical and are deliberately outside this storage policy.
|
|
12
|
+
*/
|
|
13
|
+
export function resolveToolCallResultReceiptPolicy(input: {
|
|
14
|
+
orgId?: string | null;
|
|
15
|
+
toolId: string;
|
|
16
|
+
resultReceiptKey: string;
|
|
17
|
+
runId: string;
|
|
18
|
+
logicalCallId: string;
|
|
19
|
+
force: boolean;
|
|
20
|
+
/** Historical local contexts may have no durable result store. */
|
|
21
|
+
canStoreResult?: boolean;
|
|
22
|
+
}): { resultReceiptKey: string; force: boolean } {
|
|
23
|
+
if (!input.resultReceiptKey.trim()) {
|
|
24
|
+
throw new Error('Tool Call result policy requires a result receipt key.');
|
|
25
|
+
}
|
|
26
|
+
if (!input.force) {
|
|
27
|
+
return { resultReceiptKey: input.resultReceiptKey, force: false };
|
|
28
|
+
}
|
|
29
|
+
if (input.canStoreResult === false) {
|
|
30
|
+
return { resultReceiptKey: input.resultReceiptKey, force: true };
|
|
31
|
+
}
|
|
32
|
+
if (!input.runId.trim() || !input.logicalCallId.trim()) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
'Forced Tool Call requires stable run and call identities.',
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
resultReceiptKey: scopeToolReceiptToInvocation({
|
|
39
|
+
orgId: input.orgId,
|
|
40
|
+
toolId: input.toolId,
|
|
41
|
+
receiptKey: input.resultReceiptKey,
|
|
42
|
+
invocationIdentity: `forced-result:${input.runId}:${input.logicalCallId}`,
|
|
43
|
+
}),
|
|
44
|
+
force: false,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -425,20 +425,29 @@ export function createToolExecuteHttpFailureAttemptTracker(): ToolExecuteHttpFai
|
|
|
425
425
|
};
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
-
|
|
428
|
+
// Keep expired absolute deadlines intact: durable response replay must not
|
|
429
|
+
// turn old provider feedback into a new AIMD throttle episode.
|
|
430
|
+
export function parseToolExecuteRetryAtMs(
|
|
429
431
|
header: string | null | undefined,
|
|
430
432
|
nowMs = Date.now(),
|
|
431
433
|
): number {
|
|
432
|
-
if (!header) return TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
|
|
434
|
+
if (!header) return nowMs + TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
|
|
433
435
|
const seconds = Number(header);
|
|
434
436
|
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
435
|
-
return Math.ceil(seconds * 1000);
|
|
437
|
+
return nowMs + Math.ceil(seconds * 1000);
|
|
436
438
|
}
|
|
437
439
|
const retryAt = Date.parse(header);
|
|
438
440
|
if (Number.isFinite(retryAt)) {
|
|
439
|
-
return
|
|
441
|
+
return retryAt;
|
|
440
442
|
}
|
|
441
|
-
return TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
|
|
443
|
+
return nowMs + TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
export function parseToolExecuteRetryAfterMs(
|
|
447
|
+
header: string | null | undefined,
|
|
448
|
+
nowMs = Date.now(),
|
|
449
|
+
): number {
|
|
450
|
+
return Math.max(0, parseToolExecuteRetryAtMs(header, nowMs) - nowMs);
|
|
442
451
|
}
|
|
443
452
|
|
|
444
453
|
export function classifyToolExecuteHttpFailure(input: {
|
|
@@ -265,7 +265,11 @@ function receiptFailureKindForToolErrorPayload(
|
|
|
265
265
|
// A credential connection can be added or replaced between play runs. Keep
|
|
266
266
|
// the failure terminal within its owning run, but let a later run reclaim
|
|
267
267
|
// the durable receipt instead of replaying stale authorization state.
|
|
268
|
-
|
|
268
|
+
if (code === 'INTEGRATION_CREDENTIALS_MISSING') return 'repairable';
|
|
269
|
+
// Managed AI has billing evidence for completed model steps, but no stored
|
|
270
|
+
// responses from which to resume the later rate-limited step. Its 409 stops
|
|
271
|
+
// automatic replay; an explicit later run may intentionally repeat work.
|
|
272
|
+
return code === 'UPSTREAM_PARTIAL_EXECUTION' ? 'repairable' : 'terminal';
|
|
269
273
|
}
|
|
270
274
|
|
|
271
275
|
function formatHardBillingFailureMessage(input: {
|
|
@@ -246,17 +246,11 @@ export function decideWorkReceiptClaim(input: {
|
|
|
246
246
|
const sameLogicalRun =
|
|
247
247
|
normalize(input.claimantRunId) !== null &&
|
|
248
248
|
normalize(input.claimantRunId) === normalize(input.receipt.runId);
|
|
249
|
-
const sameRunNewerLeaseAttempt =
|
|
250
|
-
state.reusable &&
|
|
251
|
-
state.lease.kind === 'active' &&
|
|
252
|
-
state.lease.ownerRunId === normalize(input.claimantRunId) &&
|
|
253
|
-
state.lease.ownerAttempt < normalizeAttempt(input.claimantRunAttempt);
|
|
254
249
|
// Force refresh means new intent across runs. Within one run it is a replay,
|
|
255
250
|
// so reuse terminal output instead of creating a second terminal payload
|
|
256
|
-
// under the run's existing Runtime Sheet write version. A
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
if (state.reusable && sameLogicalRun && !sameRunNewerLeaseAttempt) {
|
|
251
|
+
// under the run's existing Runtime Sheet write version. A scheduler resume
|
|
252
|
+
// increases the attempt number but does not create another refresh intent.
|
|
253
|
+
if (state.reusable && sameLogicalRun) {
|
|
260
254
|
return { kind: 'reuse_terminal' };
|
|
261
255
|
}
|
|
262
256
|
if (state.reusable && input.forceRefresh !== true) {
|